libcouchbase 0.3.3 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (167) hide show
  1. checksums.yaml +4 -4
  2. data/ext/libcouchbase/CMakeLists.txt +6 -8
  3. data/ext/libcouchbase/README.markdown +2 -2
  4. data/ext/libcouchbase/RELEASE_NOTES.markdown +229 -2
  5. data/ext/libcouchbase/cmake/Modules/ConfigureDtrace.cmake +11 -0
  6. data/ext/libcouchbase/cmake/Modules/GenerateConfigDotH.cmake +18 -0
  7. data/ext/libcouchbase/cmake/Modules/GetLibcouchbaseFlags.cmake +3 -2
  8. data/ext/libcouchbase/cmake/Modules/GetVersionInfo.cmake +3 -3
  9. data/ext/libcouchbase/cmake/config-cmake.h.in +4 -0
  10. data/ext/libcouchbase/cmake/defs.mk.in +0 -2
  11. data/ext/libcouchbase/cmake/source_files.cmake +21 -5
  12. data/ext/libcouchbase/contrib/cJSON/cJSON.c +1 -1
  13. data/ext/libcouchbase/contrib/cbsasl/src/client.c +2 -0
  14. data/ext/libcouchbase/example/users/README +48 -0
  15. data/ext/libcouchbase/example/users/users.c +147 -0
  16. data/ext/libcouchbase/include/libcouchbase/auth.h +175 -31
  17. data/ext/libcouchbase/include/libcouchbase/cntl.h +82 -1
  18. data/ext/libcouchbase/include/libcouchbase/couchbase.h +45 -3
  19. data/ext/libcouchbase/include/libcouchbase/error.h +19 -1
  20. data/ext/libcouchbase/include/libcouchbase/iops.h +3 -0
  21. data/ext/libcouchbase/include/libcouchbase/n1ql.h +31 -1
  22. data/ext/libcouchbase/include/libcouchbase/plugins/io/bsdio-inl.c +4 -1
  23. data/ext/libcouchbase/include/libcouchbase/subdoc.h +36 -2
  24. data/ext/libcouchbase/include/libcouchbase/views.h +7 -1
  25. data/ext/libcouchbase/include/libcouchbase/visibility.h +1 -0
  26. data/ext/libcouchbase/include/memcached/protocol_binary.h +24 -1146
  27. data/ext/libcouchbase/packaging/parse-git-describe.pl +1 -1
  28. data/ext/libcouchbase/plugins/io/libev/libev_io_opts.h +3 -2
  29. data/ext/libcouchbase/src/README.md +0 -2
  30. data/ext/libcouchbase/src/auth-priv.h +23 -4
  31. data/ext/libcouchbase/src/auth.cc +51 -43
  32. data/ext/libcouchbase/src/bootstrap.cc +244 -0
  33. data/ext/libcouchbase/src/bootstrap.h +58 -38
  34. data/ext/libcouchbase/src/bucketconfig/bc_cccp.cc +120 -158
  35. data/ext/libcouchbase/src/bucketconfig/bc_file.cc +281 -0
  36. data/ext/libcouchbase/src/bucketconfig/bc_http.cc +526 -0
  37. data/ext/libcouchbase/src/bucketconfig/bc_http.h +50 -25
  38. data/ext/libcouchbase/src/bucketconfig/bc_static.cc +150 -0
  39. data/ext/libcouchbase/src/bucketconfig/clconfig.h +410 -386
  40. data/ext/libcouchbase/src/bucketconfig/confmon.cc +393 -0
  41. data/ext/libcouchbase/src/cbft.cc +22 -27
  42. data/ext/libcouchbase/src/cntl.cc +56 -22
  43. data/ext/libcouchbase/src/connspec.cc +47 -6
  44. data/ext/libcouchbase/src/connspec.h +27 -0
  45. data/ext/libcouchbase/src/dns-srv.cc +147 -0
  46. data/ext/libcouchbase/src/dump.cc +3 -3
  47. data/ext/libcouchbase/src/errmap.cc +173 -0
  48. data/ext/libcouchbase/src/errmap.h +198 -0
  49. data/ext/libcouchbase/src/getconfig.cc +7 -33
  50. data/ext/libcouchbase/src/handler.cc +118 -7
  51. data/ext/libcouchbase/src/hostlist.cc +0 -36
  52. data/ext/libcouchbase/src/hostlist.h +44 -62
  53. data/ext/libcouchbase/src/http/http-priv.h +125 -112
  54. data/ext/libcouchbase/src/http/http.cc +27 -35
  55. data/ext/libcouchbase/src/http/http.h +1 -34
  56. data/ext/libcouchbase/src/http/http_io.cc +28 -36
  57. data/ext/libcouchbase/src/instance.cc +131 -34
  58. data/ext/libcouchbase/src/internal.h +58 -26
  59. data/ext/libcouchbase/src/jsparse/parser.cc +136 -210
  60. data/ext/libcouchbase/src/jsparse/parser.h +84 -98
  61. data/ext/libcouchbase/src/lcbht/lcbht.cc +177 -0
  62. data/ext/libcouchbase/src/lcbht/lcbht.h +174 -163
  63. data/ext/libcouchbase/src/lcbio/connect.cc +569 -0
  64. data/ext/libcouchbase/src/lcbio/connect.h +16 -7
  65. data/ext/libcouchbase/src/lcbio/ctx.c +1 -1
  66. data/ext/libcouchbase/src/lcbio/iotable.h +101 -16
  67. data/ext/libcouchbase/src/lcbio/{ioutils.c → ioutils.cc} +30 -51
  68. data/ext/libcouchbase/src/lcbio/ioutils.h +29 -90
  69. data/ext/libcouchbase/src/lcbio/manager.cc +543 -0
  70. data/ext/libcouchbase/src/lcbio/manager.h +133 -96
  71. data/ext/libcouchbase/src/lcbio/protoctx.c +2 -2
  72. data/ext/libcouchbase/src/lcbio/timer-cxx.h +87 -0
  73. data/ext/libcouchbase/src/mc/mcreq.c +11 -2
  74. data/ext/libcouchbase/src/mc/mcreq.h +9 -2
  75. data/ext/libcouchbase/src/mcserver/mcserver.cc +175 -43
  76. data/ext/libcouchbase/src/mcserver/mcserver.h +9 -13
  77. data/ext/libcouchbase/src/mcserver/negotiate.cc +181 -62
  78. data/ext/libcouchbase/src/mcserver/negotiate.h +1 -3
  79. data/ext/libcouchbase/src/mctx-helper.h +51 -0
  80. data/ext/libcouchbase/src/n1ql/ixmgmt.cc +1 -2
  81. data/ext/libcouchbase/src/n1ql/n1ql.cc +74 -42
  82. data/ext/libcouchbase/src/netbuf/netbuf.c +4 -4
  83. data/ext/libcouchbase/src/newconfig.cc +6 -6
  84. data/ext/libcouchbase/src/nodeinfo.cc +2 -2
  85. data/ext/libcouchbase/src/operations/{cbflush.c → cbflush.cc} +7 -15
  86. data/ext/libcouchbase/src/operations/{counter.c → counter.cc} +0 -0
  87. data/ext/libcouchbase/src/operations/durability.cc +6 -26
  88. data/ext/libcouchbase/src/operations/durability_internal.h +6 -3
  89. data/ext/libcouchbase/src/operations/{get.c → get.cc} +24 -26
  90. data/ext/libcouchbase/src/operations/{observe.c → observe.cc} +68 -93
  91. data/ext/libcouchbase/src/operations/{pktfwd.c → pktfwd.cc} +0 -0
  92. data/ext/libcouchbase/src/operations/{remove.c → remove.cc} +0 -0
  93. data/ext/libcouchbase/src/operations/stats.cc +3 -8
  94. data/ext/libcouchbase/src/operations/{store.c → store.cc} +27 -32
  95. data/ext/libcouchbase/src/operations/subdoc.cc +129 -42
  96. data/ext/libcouchbase/src/operations/{touch.c → touch.cc} +0 -0
  97. data/ext/libcouchbase/src/packetutils.h +30 -2
  98. data/ext/libcouchbase/src/probes.d +1 -1
  99. data/ext/libcouchbase/src/rdb/rope.c +1 -1
  100. data/ext/libcouchbase/src/{retrychk.c → retrychk.cc} +2 -3
  101. data/ext/libcouchbase/src/retryq.cc +52 -14
  102. data/ext/libcouchbase/src/retryq.h +3 -3
  103. data/ext/libcouchbase/src/settings.c +5 -0
  104. data/ext/libcouchbase/src/settings.h +11 -0
  105. data/ext/libcouchbase/src/ssl/ssl_c.c +1 -0
  106. data/ext/libcouchbase/src/ssl/ssl_common.c +2 -0
  107. data/ext/libcouchbase/src/ssl/ssl_e.c +0 -1
  108. data/ext/libcouchbase/src/strcodecs/strcodecs.h +1 -1
  109. data/ext/libcouchbase/src/trace.h +4 -4
  110. data/ext/libcouchbase/src/vbucket/vbucket.c +6 -10
  111. data/ext/libcouchbase/src/views/{docreq.c → docreq.cc} +48 -54
  112. data/ext/libcouchbase/src/views/docreq.h +24 -30
  113. data/ext/libcouchbase/src/views/viewreq.cc +318 -0
  114. data/ext/libcouchbase/src/views/viewreq.h +43 -13
  115. data/ext/libcouchbase/tests/basic/t_connstr.cc +88 -50
  116. data/ext/libcouchbase/tests/basic/t_creds.cc +47 -5
  117. data/ext/libcouchbase/tests/basic/t_host.cc +67 -75
  118. data/ext/libcouchbase/tests/basic/t_jsparse.cc +27 -82
  119. data/ext/libcouchbase/tests/basic/t_misc.cc +1 -1
  120. data/ext/libcouchbase/tests/basic/t_n1qlstrings.cc +0 -1
  121. data/ext/libcouchbase/tests/htparse/t_basic.cc +58 -78
  122. data/ext/libcouchbase/tests/ioserver/connection.cc +1 -1
  123. data/ext/libcouchbase/tests/ioserver/ioserver.cc +19 -6
  124. data/ext/libcouchbase/tests/iotests/mock-environment.cc +28 -2
  125. data/ext/libcouchbase/tests/iotests/mock-environment.h +51 -1
  126. data/ext/libcouchbase/tests/iotests/t_behavior.cc +1 -7
  127. data/ext/libcouchbase/tests/iotests/t_confmon.cc +97 -115
  128. data/ext/libcouchbase/tests/iotests/t_durability.cc +0 -1
  129. data/ext/libcouchbase/tests/iotests/t_eerrs.cc +119 -0
  130. data/ext/libcouchbase/tests/iotests/t_errmap.cc +178 -0
  131. data/ext/libcouchbase/tests/iotests/t_misc.cc +3 -3
  132. data/ext/libcouchbase/tests/iotests/t_netfail.cc +1 -1
  133. data/ext/libcouchbase/tests/iotests/t_obseqno.cc +0 -1
  134. data/ext/libcouchbase/tests/iotests/t_subdoc.cc +18 -11
  135. data/ext/libcouchbase/tests/mc/t_alloc.cc +9 -9
  136. data/ext/libcouchbase/tests/socktests/socktest.cc +7 -10
  137. data/ext/libcouchbase/tests/socktests/socktest.h +2 -3
  138. data/ext/libcouchbase/tests/socktests/t_basic.cc +6 -6
  139. data/ext/libcouchbase/tests/socktests/t_manager.cc +5 -6
  140. data/ext/libcouchbase/tests/socktests/t_ssl.cc +1 -1
  141. data/ext/libcouchbase/tests/vbucket/confdata/ketama_expected.json +2562 -0
  142. data/ext/libcouchbase/tests/vbucket/confdata/memd_ketama_config.json +31 -0
  143. data/ext/libcouchbase/tests/vbucket/t_config.cc +35 -5
  144. data/ext/libcouchbase/tools/CMakeLists.txt +2 -2
  145. data/ext/libcouchbase/tools/cbc-handlers.h +128 -0
  146. data/ext/libcouchbase/tools/cbc-n1qlback.cc +64 -10
  147. data/ext/libcouchbase/tools/cbc-pillowfight.cc +2 -2
  148. data/ext/libcouchbase/tools/cbc.cc +143 -10
  149. data/ext/libcouchbase/tools/docgen/loc.h +1 -1
  150. data/lib/libcouchbase/connection.rb +4 -3
  151. data/lib/libcouchbase/version.rb +1 -1
  152. metadata +37 -28
  153. data/ext/libcouchbase/include/memcached/vbucket.h +0 -42
  154. data/ext/libcouchbase/src/bootstrap.c +0 -269
  155. data/ext/libcouchbase/src/bucketconfig/bc_file.c +0 -347
  156. data/ext/libcouchbase/src/bucketconfig/bc_http.c +0 -630
  157. data/ext/libcouchbase/src/bucketconfig/bc_mcraw.c +0 -150
  158. data/ext/libcouchbase/src/bucketconfig/confmon.c +0 -474
  159. data/ext/libcouchbase/src/lcbht/lcbht.c +0 -282
  160. data/ext/libcouchbase/src/lcbio/connect.c +0 -557
  161. data/ext/libcouchbase/src/lcbio/manager.c +0 -584
  162. data/ext/libcouchbase/src/packetutils.c +0 -37
  163. data/ext/libcouchbase/src/simplestring.c +0 -211
  164. data/ext/libcouchbase/src/simplestring.h +0 -228
  165. data/ext/libcouchbase/src/ssobuf.h +0 -82
  166. data/ext/libcouchbase/src/views/viewreq.c +0 -358
  167. data/ext/libcouchbase/tests/basic/t_string.cc +0 -112
@@ -1,630 +0,0 @@
1
- /* -*- Mode: C; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2
- /*
3
- * Copyright 2013 Couchbase, Inc.
4
- *
5
- * Licensed under the Apache License, Version 2.0 (the "License");
6
- * you may not use this file except in compliance with the License.
7
- * You may obtain a copy of the License at
8
- *
9
- * http://www.apache.org/licenses/LICENSE-2.0
10
- *
11
- * Unless required by applicable law or agreed to in writing, software
12
- * distributed under the License is distributed on an "AS IS" BASIS,
13
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
- * See the License for the specific language governing permissions and
15
- * limitations under the License.
16
- */
17
-
18
- #include "internal.h"
19
- #include "clconfig.h"
20
- #include "bc_http.h"
21
- #include <lcbio/ssl.h>
22
- #include "ctx-log-inl.h"
23
- #define LOGARGS(ht, lvlbase) ht->base.parent->settings, "htconfig", LCB_LOG_##lvlbase, __FILE__, __LINE__
24
- #define LOGFMT "<%s:%s> "
25
- #define LOGID(h) get_ctx_host(h->ioctx), get_ctx_port(h->ioctx)
26
-
27
- static void io_error_handler(lcbio_CTX *, lcb_error_t);
28
- static void on_connected(lcbio_SOCKET *, void *, lcb_error_t, lcbio_OSERR);
29
- static lcb_error_t connect_next(http_provider *);
30
- static void read_common(lcbio_CTX *, unsigned);
31
- static lcb_error_t setup_request_header(http_provider *, const lcb_host_t *);
32
-
33
- /**
34
- * Determine if we're in compatibility mode with the previous versions of the
35
- * library - where the idle timeout is disabled and a perpetual streaming
36
- * connection will always remain open (regardless of whether it was triggered
37
- * by start_refresh/get_refresh).
38
- */
39
- static int is_v220_compat(http_provider *http)
40
- {
41
- lcb_uint32_t setting = PROVIDER_SETTING(&http->base, bc_http_stream_time);
42
- if (setting == (lcb_uint32_t)-1) {
43
- return 1;
44
- }
45
- return 0;
46
- }
47
-
48
- /**
49
- * Closes the current connection and removes the disconn timer along with it
50
- */
51
- static void close_current(http_provider *http)
52
- {
53
- lcbio_timer_disarm(http->disconn_timer);
54
- if (http->ioctx) {
55
- lcbio_ctx_close(http->ioctx, NULL, NULL);
56
- } else if (http->creq){
57
- lcbio_connect_cancel(http->creq);
58
- }
59
- http->creq = NULL;
60
- http->ioctx = NULL;
61
- }
62
-
63
- /**
64
- * Call when there is an error in I/O. This includes read, write, connect
65
- * and timeouts.
66
- */
67
- static lcb_error_t
68
- io_error(http_provider *http, lcb_error_t origerr)
69
- {
70
- lcb_confmon *mon = http->base.parent;
71
- lcb_settings *settings = mon->settings;
72
-
73
- close_current(http);
74
-
75
- http->creq = lcbio_connect_hl(
76
- mon->iot, settings, http->nodes, 0, settings->config_node_timeout,
77
- on_connected, http);
78
- if (http->creq) {
79
- return LCB_SUCCESS;
80
- }
81
-
82
- lcb_confmon_provider_failed(&http->base, origerr);
83
- lcbio_timer_disarm(http->io_timer);
84
- if (is_v220_compat(http) && http->base.parent->config != NULL) {
85
- lcb_log(LOGARGS(http, INFO), "HTTP node list finished. Trying to obtain connection from first node in list");
86
- if (!lcbio_timer_armed(http->as_reconnect)) {
87
- lcbio_timer_rearm(http->as_reconnect,
88
- PROVIDER_SETTING(&http->base, grace_next_cycle));
89
- }
90
- }
91
- return origerr;
92
- }
93
-
94
- /**
95
- * Call this if the configuration generation has changed.
96
- */
97
- static void set_new_config(http_provider *http)
98
- {
99
- const lcb_host_t *curhost;
100
- if (http->current_config) {
101
- lcb_clconfig_decref(http->current_config);
102
- }
103
-
104
- curhost = lcbio_get_host(lcbio_ctx_sock(http->ioctx));
105
- http->current_config = http->last_parsed;
106
- lcb_clconfig_incref(http->current_config);
107
- lcbvb_replace_host(http->current_config->vbc, curhost->host);
108
- lcb_confmon_provider_success(&http->base, http->current_config);
109
- }
110
-
111
- static lcb_error_t
112
- process_chunk(http_provider *http, const void *buf, unsigned nbuf)
113
- {
114
- lcb_error_t err = LCB_SUCCESS;
115
- char *term;
116
- int rv;
117
- lcbvb_CONFIG *cfgh;
118
- lcbht_RESPSTATE state, oldstate, diff;
119
- lcbht_RESPONSE *resp = lcbht_get_response(http->htp);
120
-
121
- oldstate = resp->state;
122
- state = lcbht_parse(http->htp, buf, nbuf);
123
- diff = state ^ oldstate;
124
-
125
- if (state & LCBHT_S_ERROR) {
126
- return LCB_PROTOCOL_ERROR;
127
- }
128
-
129
- if (diff & LCBHT_S_HEADER) {
130
- /* see that we got a success? */
131
- if (resp->status == 200) {
132
- /* nothing */
133
- } else if (resp->status == 404) {
134
- const int urlmode = PROVIDER_SETTING(&http->base, bc_http_urltype);
135
- err = LCB_BUCKET_ENOENT;
136
-
137
- if (++http->uritype > LCB_HTCONFIG_URLTYPE_COMPAT) {
138
- lcb_log(LOGARGS(http, ERR), LOGFMT "Got 404 on config stream. Assuming bucket does not exist as we've tried both URL types", LOGID(http));
139
- goto GT_HT_ERROR;
140
-
141
- } else if ((urlmode & LCB_HTCONFIG_URLTYPE_COMPAT) == 0) {
142
- lcb_log(LOGARGS(http, ERR), LOGFMT "Got 404 on config stream for terse URI. Compat URI disabled, so not trying", LOGID(http));
143
-
144
- } else {
145
- /* reissue the request; but wait for it to drain */
146
- lcb_log(LOGARGS(http, WARN), LOGFMT "Got 404 on config stream. Assuming terse URI not supported on cluster", LOGID(http));
147
- http->try_nexturi = 1;
148
- err = LCB_SUCCESS;
149
- goto GT_CHECKDONE;
150
- }
151
- } else if (resp->status == 401) {
152
- err = LCB_AUTH_ERROR;
153
- } else {
154
- err = LCB_ERROR;
155
- }
156
-
157
- GT_HT_ERROR:
158
- if (err != LCB_SUCCESS) {
159
- lcb_log(LOGARGS(http, ERR), LOGFMT "Got non-success HTTP status code %d", LOGID(http), resp->status);
160
- return err;
161
- }
162
- }
163
-
164
- GT_CHECKDONE:
165
- if (http->try_nexturi) {
166
- lcb_host_t *host;
167
- if (!(state & LCBHT_S_DONE)) {
168
- return LCB_SUCCESS;
169
- }
170
- host = lcbio_get_host(lcbio_ctx_sock(http->ioctx));
171
- http->try_nexturi = 0;
172
- if ((err = setup_request_header(http, host)) != LCB_SUCCESS) {
173
- return err;
174
- }
175
-
176
- /* reset the state? */
177
- lcbht_reset(http->htp);
178
- lcbio_ctx_put(http->ioctx, http->request_buf, strlen(http->request_buf));
179
- return LCB_SUCCESS;
180
- }
181
-
182
- if (PROVIDER_SETTING(&http->base, conntype) == LCB_TYPE_CLUSTER) {
183
- /* don't bother with parsing the actual config */
184
- resp->body.nused = 0;
185
- return LCB_SUCCESS;
186
- }
187
- if (!(state & LCBHT_S_BODY)) {
188
- /* nothing to parse yet */
189
- return LCB_SUCCESS;
190
- }
191
-
192
- /* seek ahead for strstr */
193
- term = strstr(resp->body.base, CONFIG_DELIMITER);
194
- if (!term) {
195
- return LCB_SUCCESS;
196
- }
197
-
198
- *term = '\0';
199
- cfgh = lcbvb_create();
200
- if (!cfgh) {
201
- return LCB_CLIENT_ENOMEM;
202
- }
203
- rv = lcbvb_load_json(cfgh, resp->body.base);
204
- if (rv != 0) {
205
- lcb_log(LOGARGS(http, ERR), LOGFMT "Failed to parse a valid config from HTTP stream", LOGID(http));
206
- lcb_log_badconfig(LOGARGS(http, ERR), cfgh, resp->body.base);
207
- lcbvb_destroy(cfgh);
208
- return LCB_PROTOCOL_ERROR;
209
- }
210
- if (http->last_parsed) {
211
- lcb_clconfig_decref(http->last_parsed);
212
- }
213
- http->last_parsed = lcb_clconfig_create(cfgh, LCB_CLCONFIG_HTTP);
214
- http->last_parsed->cmpclock = gethrtime();
215
- http->generation++;
216
-
217
- /** Relocate the stream */
218
- lcb_string_erase_beginning(&resp->body,
219
- (term+sizeof(CONFIG_DELIMITER)-1)-resp->body.base);
220
-
221
- return LCB_SUCCESS;
222
- }
223
-
224
- /**
225
- * Common function to handle parsing the HTTP stream for both v0 and v1 io
226
- * implementations.
227
- */
228
- static void
229
- read_common(lcbio_CTX *ctx, unsigned nr)
230
- {
231
- lcbio_CTXRDITER riter;
232
- http_provider *http = lcbio_ctx_data(ctx);
233
- int old_generation = http->generation;
234
-
235
- lcb_log(LOGARGS(http, TRACE), LOGFMT "Received %d bytes on HTTP stream", LOGID(http), nr);
236
-
237
- lcbio_timer_rearm(http->io_timer,
238
- PROVIDER_SETTING(&http->base, config_node_timeout));
239
-
240
- LCBIO_CTX_ITERFOR(ctx, &riter, nr) {
241
- unsigned nbuf = lcbio_ctx_risize(&riter);
242
- void *buf = lcbio_ctx_ribuf(&riter);
243
- lcb_error_t err = process_chunk(http, buf, nbuf);
244
-
245
- if (err != LCB_SUCCESS) {
246
- io_error(http, err);
247
- return;
248
- }
249
- }
250
-
251
- if (http->generation != old_generation) {
252
- lcb_log(LOGARGS(http, DEBUG), LOGFMT "Generation %d -> %d", LOGID(http), old_generation, http->generation);
253
- lcbio_timer_disarm(http->io_timer);
254
- set_new_config(http);
255
- }
256
-
257
- lcbio_ctx_rwant(ctx, 1);
258
- lcbio_ctx_schedule(ctx);
259
- }
260
-
261
- static lcb_error_t
262
- setup_request_header(http_provider *http, const lcb_host_t *host)
263
- {
264
- lcb_settings *settings = http->base.parent->settings;
265
-
266
- char *buf = http->request_buf;
267
- const char *username = NULL, *password = NULL;
268
- lcb_size_t nbuf = sizeof(http->request_buf);
269
-
270
- lcb_size_t offset = 0;
271
- http->request_buf[0] = '\0';
272
-
273
- if (settings->conntype == LCB_TYPE_BUCKET) {
274
- const char *fmt;
275
- if (http->uritype == LCB_HTCONFIG_URLTYPE_25PLUS) {
276
- fmt = REQBUCKET_TERSE_FMT;
277
- } else {
278
- fmt = REQBUCKET_COMPAT_FMT;
279
- }
280
- offset = snprintf(buf, nbuf, fmt, settings->bucket);
281
-
282
- } else if (settings->conntype == LCB_TYPE_CLUSTER) {
283
- offset = snprintf(buf, nbuf, REQPOOLS_FMT);
284
-
285
- } else {
286
- return LCB_EINVAL;
287
- }
288
- lcbauth_get_upass(settings->auth, &username, &password);
289
-
290
- if (password) {
291
- char cred[256], b64[256];
292
- snprintf(cred, sizeof(cred), "%s:%s", username, password);
293
-
294
- if (lcb_base64_encode(cred, b64, sizeof(b64)) == -1) {
295
- return LCB_EINTERNAL;
296
- }
297
-
298
- offset += snprintf(buf + offset, nbuf - offset, AUTHDR_FMT, b64);
299
- }
300
-
301
- offset += snprintf(buf + offset, nbuf - offset, HOSTHDR_FMT,
302
- host->host, host->port);
303
-
304
- offset += snprintf(buf + offset, nbuf - offset, "%s\r\n", LAST_HTTP_HEADER);
305
-
306
- return LCB_SUCCESS;
307
- }
308
-
309
- static void reset_stream_state(http_provider *http)
310
- {
311
- const int urlmode = PROVIDER_SETTING(&http->base, bc_http_urltype);
312
- if (http->last_parsed) {
313
- lcb_clconfig_decref(http->last_parsed);
314
- http->last_parsed = NULL;
315
- }
316
- if (urlmode & LCB_HTCONFIG_URLTYPE_25PLUS) {
317
- http->uritype = LCB_HTCONFIG_URLTYPE_25PLUS;
318
- } else {
319
- http->uritype = LCB_HTCONFIG_URLTYPE_COMPAT;
320
- }
321
- http->try_nexturi = 0;
322
- lcbht_reset(http->htp);
323
- }
324
-
325
- static void
326
- on_connected(lcbio_SOCKET *sock, void *arg, lcb_error_t err, lcbio_OSERR syserr)
327
- {
328
- http_provider *http = arg;
329
- lcb_host_t *host;
330
- lcbio_CTXPROCS procs;
331
- http->creq = NULL;
332
-
333
- if (err != LCB_SUCCESS) {
334
- lcb_log(LOGARGS(http, ERR), "Connection to REST API failed with code=0x%x (%d)", err, syserr);
335
- io_error(http, err);
336
- return;
337
- }
338
- host = lcbio_get_host(sock);
339
- lcb_log(LOGARGS(http, DEBUG), "Successfuly connected to REST API %s:%s", host->host, host->port);
340
-
341
- lcbio_sslify_if_needed(sock, http->base.parent->settings);
342
- reset_stream_state(http);
343
-
344
- if ((err = setup_request_header(http, host)) != LCB_SUCCESS) {
345
- lcb_log(LOGARGS(http, ERR), "Couldn't setup request header");
346
- io_error(http, err);
347
- return;
348
- }
349
-
350
- memset(&procs, 0, sizeof(procs));
351
- procs.cb_err = io_error_handler;
352
- procs.cb_read = read_common;
353
- http->ioctx = lcbio_ctx_new(sock, http, &procs);
354
- http->ioctx->subsys = "bc_http";
355
-
356
- lcbio_ctx_put(http->ioctx, http->request_buf, strlen(http->request_buf));
357
- lcbio_ctx_rwant(http->ioctx, 1);
358
- lcbio_ctx_schedule(http->ioctx);
359
- lcbio_timer_rearm(http->io_timer,
360
- PROVIDER_SETTING(&http->base, config_node_timeout));
361
- }
362
-
363
- static void
364
- timeout_handler(void *arg)
365
- {
366
- http_provider *http = arg;
367
-
368
- lcb_log(LOGARGS(http, ERR), LOGFMT "HTTP Provider timed out waiting for I/O", LOGID(http));
369
-
370
- /**
371
- * If we're not the current provider then ignore the timeout until we're
372
- * actively requested to do so
373
- */
374
- if (&http->base != http->base.parent->cur_provider ||
375
- lcb_confmon_is_refreshing(http->base.parent) == 0) {
376
- lcb_log(LOGARGS(http, DEBUG), LOGFMT "Ignoring timeout because we're either not in a refresh or not the current provider", LOGID(http));
377
- return;
378
- }
379
-
380
- io_error(http, LCB_ETIMEDOUT);
381
- }
382
-
383
-
384
- static lcb_error_t
385
- connect_next(http_provider *http)
386
- {
387
- lcb_settings *settings = http->base.parent->settings;
388
- lcb_log(LOGARGS(http, TRACE), "Starting HTTP Configuration Provider %p", (void*)http);
389
- close_current(http);
390
- lcbio_timer_disarm(http->as_reconnect);
391
-
392
- if (!hostlist_size(http->nodes)) {
393
- lcb_log(LOGARGS(http, ERROR), "Not scheduling HTTP provider since no nodes have been configured for HTTP bootstrap");
394
- return LCB_CONNECT_ERROR;
395
- }
396
-
397
- http->creq = lcbio_connect_hl(http->base.parent->iot, settings, http->nodes, 1,
398
- settings->config_node_timeout, on_connected, http);
399
- if (http->creq) {
400
- return LCB_SUCCESS;
401
- }
402
- lcb_log(LOGARGS(http, ERROR), "%p: Couldn't schedule connection", (void*)http);
403
- return LCB_CONNECT_ERROR;
404
- }
405
-
406
- static void delayed_disconn(void *arg)
407
- {
408
- http_provider *http = arg;
409
- lcb_log(LOGARGS(http, DEBUG), "Stopping HTTP provider %p", (void*)http);
410
-
411
- /** closes the connection and cleans up the timer */
412
- close_current(http);
413
- lcbio_timer_disarm(http->io_timer);
414
- }
415
-
416
- static void delayed_reconnect(void *arg)
417
- {
418
- http_provider *http = arg;
419
- lcb_error_t err;
420
- if (http->ioctx) {
421
- /* have a context already */
422
- return;
423
- }
424
- err = connect_next(http);
425
- if (err != LCB_SUCCESS) {
426
- io_error(http, err);
427
- }
428
- }
429
-
430
- static lcb_error_t pause_http(clconfig_provider *pb)
431
- {
432
- http_provider *http = (http_provider *)pb;
433
- if (is_v220_compat(http)) {
434
- return LCB_SUCCESS;
435
- }
436
-
437
- if (!lcbio_timer_armed(http->disconn_timer)) {
438
- lcbio_timer_rearm(http->disconn_timer,
439
- PROVIDER_SETTING(pb, bc_http_stream_time));
440
- }
441
- return LCB_SUCCESS;
442
- }
443
-
444
- static lcb_error_t get_refresh(clconfig_provider *provider)
445
- {
446
- http_provider *http = (http_provider *)provider;
447
-
448
- /**
449
- * We want a grace interval here because we might already be fetching a
450
- * connection. HOWEVER we don't want to indefinitely wait on a socket
451
- * so we issue a timer indicating how long we expect to wait for a
452
- * streaming update until we get something.
453
- */
454
-
455
- /** If we need a new socket, we do connect_next. */
456
- if (http->ioctx == NULL && http->creq == NULL) {
457
- lcbio_async_signal(http->as_reconnect);
458
- }
459
-
460
- lcbio_timer_disarm(http->disconn_timer);
461
- if (http->ioctx) {
462
- lcbio_timer_rearm(http->io_timer,
463
- PROVIDER_SETTING(provider, config_node_timeout));
464
- }
465
- return LCB_SUCCESS;
466
- }
467
-
468
- static clconfig_info* http_get_cached(clconfig_provider *provider)
469
- {
470
- http_provider *http = (http_provider *)provider;
471
- return http->current_config;
472
- }
473
-
474
- static void
475
- config_updated(clconfig_provider *pb, lcbvb_CONFIG *newconfig)
476
- {
477
- unsigned int ii;
478
- http_provider *http = (http_provider *)pb;
479
- lcb_SSLOPTS sopts;
480
- lcbvb_SVCMODE mode;
481
-
482
- hostlist_clear(http->nodes);
483
-
484
- sopts = PROVIDER_SETTING(pb, sslopts);
485
- if (sopts & LCB_SSL_ENABLED) {
486
- mode = LCBVB_SVCMODE_SSL;
487
- } else {
488
- mode = LCBVB_SVCMODE_PLAIN;
489
- }
490
-
491
- for (ii = 0; ii < newconfig->nsrv; ++ii) {
492
- const char *ss;
493
- lcb_error_t status;
494
- ss = lcbvb_get_hostport(newconfig, ii, LCBVB_SVCTYPE_MGMT, mode);
495
- if (!ss) {
496
- /* not supported? */
497
- continue;
498
- }
499
- status = hostlist_add_stringz(http->nodes, ss, LCB_CONFIG_HTTP_PORT);
500
- lcb_assert(status == LCB_SUCCESS);
501
- }
502
- if (!hostlist_size(http->nodes)) {
503
- lcb_log(LOGARGS(http, FATAL), "New nodes do not contain management ports");
504
- }
505
-
506
- if (PROVIDER_SETTING(pb, randomize_bootstrap_nodes)) {
507
- hostlist_randomize(http->nodes);
508
- }
509
- }
510
-
511
- static void
512
- configure_nodes(clconfig_provider *pb, const hostlist_t newnodes)
513
- {
514
- http_provider *http = (void *)pb;
515
- hostlist_assign(http->nodes, newnodes);
516
- if (PROVIDER_SETTING(pb, randomize_bootstrap_nodes)) {
517
- hostlist_randomize(http->nodes);
518
- }
519
- }
520
-
521
- static hostlist_t
522
- get_nodes(const clconfig_provider *pb)
523
- {
524
- return ((http_provider *)pb)->nodes;
525
- }
526
-
527
- static void shutdown_http(clconfig_provider *provider)
528
- {
529
- http_provider *http = (http_provider *)provider;
530
- reset_stream_state(http);
531
- close_current(http);
532
- lcbht_free(http->htp);
533
-
534
- if (http->current_config) {
535
- lcb_clconfig_decref(http->current_config);
536
- }
537
- if (http->disconn_timer) {
538
- lcbio_timer_destroy(http->disconn_timer);
539
- }
540
- if (http->io_timer) {
541
- lcbio_timer_destroy(http->io_timer);
542
- }
543
- if (http->as_reconnect) {
544
- lcbio_timer_destroy(http->as_reconnect);
545
- }
546
- if (http->nodes) {
547
- hostlist_destroy(http->nodes);
548
- }
549
- free(http);
550
- }
551
-
552
- static void
553
- do_http_dump(clconfig_provider *pb, FILE *fp)
554
- {
555
- http_provider *ht = (http_provider *)pb;
556
- fprintf(fp, "## BEGIN HTTP PROVIDER DUMP\n");
557
- fprintf(fp, "NUMBER OF CONFIGS RECEIVED: %u\n", ht->generation);
558
- fprintf(fp, "DUMPING I/O TIMER\n");
559
- lcbio_timer_dump(ht->io_timer, fp);
560
- if (ht->ioctx) {
561
- fprintf(fp, "DUMPING CURRENT CONNECTION:\n");
562
- lcbio_ctx_dump(ht->ioctx, fp);
563
- } else if (ht->creq) {
564
- fprintf(fp, "CURRENTLY CONNECTING..\n");
565
- } else {
566
- fprintf(fp, "NO CONNECTION ACTIVE\n");
567
- }
568
- }
569
-
570
- clconfig_provider * lcb_clconfig_create_http(lcb_confmon *parent)
571
- {
572
- http_provider *http = calloc(1, sizeof(*http));
573
-
574
- if (!http) {
575
- return NULL;
576
- }
577
-
578
- if (! (http->nodes = hostlist_create())) {
579
- free(http);
580
- return NULL;
581
- }
582
-
583
- http->base.type = LCB_CLCONFIG_HTTP;
584
- http->base.refresh = get_refresh;
585
- http->base.pause = pause_http;
586
- http->base.get_cached = http_get_cached;
587
- http->base.shutdown = shutdown_http;
588
- http->base.config_updated = config_updated;
589
- http->base.configure_nodes = configure_nodes;
590
- http->base.get_nodes = get_nodes;
591
- http->base.dump = do_http_dump;
592
- http->base.enabled = 0;
593
- http->io_timer = lcbio_timer_new(parent->iot, http, timeout_handler);
594
- http->disconn_timer = lcbio_timer_new(parent->iot, http, delayed_disconn);
595
- http->as_reconnect = lcbio_timer_new(parent->iot, http, delayed_reconnect);
596
- http->htp = lcbht_new(parent->settings);
597
- return &http->base;
598
- }
599
-
600
- static void
601
- io_error_handler(lcbio_CTX *ctx, lcb_error_t err)
602
- {
603
- io_error((http_provider *)lcbio_ctx_data(ctx), err);
604
- }
605
-
606
- void lcb_clconfig_http_enable(clconfig_provider *http)
607
- {
608
- http->enabled = 1;
609
- }
610
-
611
- lcbio_SOCKET *
612
- lcb_confmon_get_rest_connection(lcb_confmon *mon)
613
- {
614
- http_provider *http = (http_provider *)mon->all_providers[LCB_CLCONFIG_HTTP];
615
- if (!http->ioctx) {
616
- return NULL;
617
- }
618
- return lcbio_ctx_sock(http->ioctx);
619
-
620
- }
621
-
622
- lcb_host_t *
623
- lcb_confmon_get_rest_host(lcb_confmon *mon)
624
- {
625
- lcbio_SOCKET *sock = lcb_confmon_get_rest_connection(mon);
626
- if (sock) {
627
- return lcbio_get_host(sock);
628
- }
629
- return NULL;
630
- }