libcouchbase 0.2.0 → 0.3.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (129) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +1 -1
  3. data/README.md +1 -1
  4. data/ext/libcouchbase/CMakeLists.txt +8 -6
  5. data/ext/libcouchbase/README.markdown +2 -2
  6. data/ext/libcouchbase/RELEASE_NOTES.markdown +0 -86
  7. data/ext/libcouchbase/cmake/Modules/ConfigureDtrace.cmake +0 -11
  8. data/ext/libcouchbase/cmake/Modules/GenerateConfigDotH.cmake +0 -2
  9. data/ext/libcouchbase/cmake/Modules/GetLibcouchbaseFlags.cmake +1 -2
  10. data/ext/libcouchbase/cmake/Modules/GetVersionInfo.cmake +3 -3
  11. data/ext/libcouchbase/cmake/config-cmake.h.in +0 -2
  12. data/ext/libcouchbase/cmake/defs.mk.in +2 -0
  13. data/ext/libcouchbase/cmake/source_files.cmake +5 -21
  14. data/ext/libcouchbase/include/libcouchbase/auth.h +0 -10
  15. data/ext/libcouchbase/include/libcouchbase/cntl.h +1 -27
  16. data/ext/libcouchbase/include/libcouchbase/error.h +1 -15
  17. data/ext/libcouchbase/include/libcouchbase/n1ql.h +1 -13
  18. data/ext/libcouchbase/include/libcouchbase/plugins/io/bsdio-inl.c +1 -1
  19. data/ext/libcouchbase/include/libcouchbase/subdoc.h +0 -9
  20. data/ext/libcouchbase/include/libcouchbase/views.h +1 -7
  21. data/ext/libcouchbase/include/libcouchbase/visibility.h +0 -1
  22. data/ext/libcouchbase/include/memcached/protocol_binary.h +1131 -29
  23. data/ext/libcouchbase/include/memcached/vbucket.h +42 -0
  24. data/ext/libcouchbase/packaging/parse-git-describe.pl +1 -1
  25. data/ext/libcouchbase/plugins/io/libev/libev_io_opts.h +2 -3
  26. data/ext/libcouchbase/src/README.md +2 -0
  27. data/ext/libcouchbase/src/auth-priv.h +0 -1
  28. data/ext/libcouchbase/src/auth.cc +4 -10
  29. data/ext/libcouchbase/src/bootstrap.c +269 -0
  30. data/ext/libcouchbase/src/bootstrap.h +39 -50
  31. data/ext/libcouchbase/src/bucketconfig/bc_cccp.cc +117 -84
  32. data/ext/libcouchbase/src/bucketconfig/bc_file.c +347 -0
  33. data/ext/libcouchbase/src/bucketconfig/bc_http.c +630 -0
  34. data/ext/libcouchbase/src/bucketconfig/bc_http.h +25 -50
  35. data/ext/libcouchbase/src/bucketconfig/bc_mcraw.c +150 -0
  36. data/ext/libcouchbase/src/bucketconfig/clconfig.h +386 -407
  37. data/ext/libcouchbase/src/bucketconfig/confmon.c +474 -0
  38. data/ext/libcouchbase/src/cbft.cc +27 -22
  39. data/ext/libcouchbase/src/cntl.cc +19 -30
  40. data/ext/libcouchbase/src/connspec.cc +1 -48
  41. data/ext/libcouchbase/src/connspec.h +0 -27
  42. data/ext/libcouchbase/src/dump.cc +2 -2
  43. data/ext/libcouchbase/src/getconfig.cc +33 -7
  44. data/ext/libcouchbase/src/handler.cc +2 -0
  45. data/ext/libcouchbase/src/hostlist.cc +36 -0
  46. data/ext/libcouchbase/src/hostlist.h +62 -41
  47. data/ext/libcouchbase/src/http/http-priv.h +112 -125
  48. data/ext/libcouchbase/src/http/http.cc +30 -15
  49. data/ext/libcouchbase/src/http/http.h +34 -1
  50. data/ext/libcouchbase/src/http/http_io.cc +26 -22
  51. data/ext/libcouchbase/src/instance.cc +23 -94
  52. data/ext/libcouchbase/src/internal.h +26 -52
  53. data/ext/libcouchbase/src/jsparse/parser.cc +202 -146
  54. data/ext/libcouchbase/src/jsparse/parser.h +98 -91
  55. data/ext/libcouchbase/src/lcbht/lcbht.c +282 -0
  56. data/ext/libcouchbase/src/lcbht/lcbht.h +163 -174
  57. data/ext/libcouchbase/src/lcbio/connect.c +557 -0
  58. data/ext/libcouchbase/src/lcbio/connect.h +2 -9
  59. data/ext/libcouchbase/src/lcbio/ctx.c +1 -1
  60. data/ext/libcouchbase/src/lcbio/iotable.h +16 -61
  61. data/ext/libcouchbase/src/lcbio/ioutils.h +1 -1
  62. data/ext/libcouchbase/src/lcbio/manager.c +2 -2
  63. data/ext/libcouchbase/src/mc/mcreq.h +2 -9
  64. data/ext/libcouchbase/src/mcserver/mcserver.cc +34 -143
  65. data/ext/libcouchbase/src/mcserver/mcserver.h +12 -7
  66. data/ext/libcouchbase/src/mcserver/negotiate.cc +38 -132
  67. data/ext/libcouchbase/src/n1ql/ixmgmt.cc +2 -1
  68. data/ext/libcouchbase/src/n1ql/n1ql.cc +32 -56
  69. data/ext/libcouchbase/src/newconfig.cc +6 -6
  70. data/ext/libcouchbase/src/nodeinfo.cc +2 -2
  71. data/ext/libcouchbase/src/operations/{cbflush.cc → cbflush.c} +15 -7
  72. data/ext/libcouchbase/src/operations/{counter.cc → counter.c} +0 -0
  73. data/ext/libcouchbase/src/operations/durability.cc +26 -6
  74. data/ext/libcouchbase/src/operations/durability_internal.h +3 -6
  75. data/ext/libcouchbase/src/operations/{get.cc → get.c} +26 -24
  76. data/ext/libcouchbase/src/operations/{observe.cc → observe.c} +93 -68
  77. data/ext/libcouchbase/src/operations/{pktfwd.cc → pktfwd.c} +0 -0
  78. data/ext/libcouchbase/src/operations/{remove.cc → remove.c} +0 -0
  79. data/ext/libcouchbase/src/operations/stats.cc +8 -3
  80. data/ext/libcouchbase/src/operations/{store.cc → store.c} +32 -27
  81. data/ext/libcouchbase/src/operations/subdoc.cc +18 -38
  82. data/ext/libcouchbase/src/operations/{touch.cc → touch.c} +0 -0
  83. data/ext/libcouchbase/src/packetutils.c +37 -0
  84. data/ext/libcouchbase/src/packetutils.h +2 -2
  85. data/ext/libcouchbase/src/probes.d +1 -1
  86. data/ext/libcouchbase/src/{retrychk.cc → retrychk.c} +3 -2
  87. data/ext/libcouchbase/src/retryq.cc +4 -4
  88. data/ext/libcouchbase/src/settings.c +0 -3
  89. data/ext/libcouchbase/src/settings.h +0 -5
  90. data/ext/libcouchbase/src/simplestring.c +211 -0
  91. data/ext/libcouchbase/src/simplestring.h +228 -0
  92. data/ext/libcouchbase/src/ssl/ssl_c.c +0 -1
  93. data/ext/libcouchbase/src/ssl/ssl_common.c +0 -2
  94. data/ext/libcouchbase/src/ssl/ssl_e.c +1 -0
  95. data/ext/libcouchbase/src/ssobuf.h +82 -0
  96. data/ext/libcouchbase/src/trace.h +4 -4
  97. data/ext/libcouchbase/src/vbucket/vbucket.c +1 -0
  98. data/ext/libcouchbase/src/views/{docreq.cc → docreq.c} +54 -48
  99. data/ext/libcouchbase/src/views/docreq.h +30 -24
  100. data/ext/libcouchbase/src/views/viewreq.c +358 -0
  101. data/ext/libcouchbase/src/views/viewreq.h +13 -43
  102. data/ext/libcouchbase/tests/basic/t_connstr.cc +50 -89
  103. data/ext/libcouchbase/tests/basic/t_host.cc +75 -67
  104. data/ext/libcouchbase/tests/basic/t_jsparse.cc +78 -27
  105. data/ext/libcouchbase/tests/basic/t_string.cc +112 -0
  106. data/ext/libcouchbase/tests/htparse/t_basic.cc +78 -58
  107. data/ext/libcouchbase/tests/iotests/mock-environment.h +1 -2
  108. data/ext/libcouchbase/tests/iotests/t_confmon.cc +114 -96
  109. data/ext/libcouchbase/tests/mc/t_alloc.cc +9 -9
  110. data/ext/libcouchbase/tools/cbc-pillowfight.cc +1 -1
  111. data/lib/libcouchbase/ext/tasks.rb +6 -2
  112. data/lib/libcouchbase/query_view.rb +1 -1
  113. data/lib/libcouchbase/results_fiber.rb +6 -6
  114. data/lib/libcouchbase/version.rb +1 -1
  115. metadata +26 -26
  116. data/ext/libcouchbase/src/bootstrap.cc +0 -216
  117. data/ext/libcouchbase/src/bucketconfig/bc_file.cc +0 -281
  118. data/ext/libcouchbase/src/bucketconfig/bc_http.cc +0 -528
  119. data/ext/libcouchbase/src/bucketconfig/bc_mcraw.cc +0 -115
  120. data/ext/libcouchbase/src/bucketconfig/confmon.cc +0 -378
  121. data/ext/libcouchbase/src/dns-srv.cc +0 -142
  122. data/ext/libcouchbase/src/errmap.cc +0 -107
  123. data/ext/libcouchbase/src/errmap.h +0 -113
  124. data/ext/libcouchbase/src/lcbht/lcbht.cc +0 -177
  125. data/ext/libcouchbase/src/lcbio/connect.cc +0 -562
  126. data/ext/libcouchbase/src/lcbio/timer-cxx.h +0 -87
  127. data/ext/libcouchbase/src/mctx-helper.h +0 -51
  128. data/ext/libcouchbase/src/views/viewreq.cc +0 -318
  129. data/ext/libcouchbase/tests/iotests/t_errmap.cc +0 -97
@@ -1,528 +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->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
- using namespace lcb::clconfig;
28
-
29
- static void io_error_handler(lcbio_CTX *, lcb_error_t);
30
- static void on_connected(lcbio_SOCKET *, void *, lcb_error_t, lcbio_OSERR);
31
- static void read_common(lcbio_CTX *, unsigned);
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
- bool HttpProvider::is_v220_compat() const {
40
- lcb_uint32_t setting = parent->settings->bc_http_stream_time;
41
- return setting == (lcb_uint32_t)-1;
42
- }
43
-
44
- void HttpProvider::close_current()
45
- {
46
- disconn_timer.cancel();
47
- if (ioctx) {
48
- lcbio_ctx_close(ioctx, NULL, NULL);
49
- } else if (creq){
50
- lcbio_connect_cancel(creq);
51
- }
52
- creq = NULL;
53
- ioctx = NULL;
54
- }
55
-
56
- /**
57
- * Call when there is an error in I/O. This includes read, write, connect
58
- * and timeouts.
59
- */
60
- lcb_error_t HttpProvider::on_io_error(lcb_error_t origerr)
61
- {
62
- close_current();
63
-
64
- creq = lcbio_connect_hl(
65
- parent->iot, &settings(), nodes, 0, settings().config_node_timeout,
66
- on_connected, this);
67
- if (creq) {
68
- return LCB_SUCCESS;
69
- }
70
- parent->provider_failed(this, origerr);
71
- io_timer.cancel();
72
- if (is_v220_compat() && parent->config != NULL) {
73
- lcb_log(LOGARGS(this, INFO), "HTTP node list finished. Trying to obtain connection from first node in list");
74
- as_reconnect.arm_if_disarmed(settings().grace_next_cycle);
75
- }
76
- return origerr;
77
- }
78
-
79
- void set_new_config(HttpProvider *http)
80
- {
81
- const lcb_host_t *curhost;
82
- if (http->current_config) {
83
- http->current_config->decref();
84
- }
85
-
86
- curhost = lcbio_get_host(lcbio_ctx_sock(http->ioctx));
87
- http->current_config = http->last_parsed;
88
- http->current_config->incref();
89
- lcbvb_replace_host(http->current_config->vbc, curhost->host);
90
- http->parent->provider_got_config(http, http->current_config);
91
- }
92
-
93
- static lcb_error_t
94
- process_chunk(HttpProvider *http, const void *buf, unsigned nbuf)
95
- {
96
- namespace htp = lcb::htparse;
97
- lcb_error_t err = LCB_SUCCESS;
98
- int rv;
99
- lcbvb_CONFIG *cfgh;
100
- unsigned state, oldstate, diff;
101
- htp::Response& resp = http->htp->get_cur_response();
102
-
103
- oldstate = resp.state;
104
- state = http->htp->parse(buf, nbuf);
105
- diff = state ^ oldstate;
106
-
107
- if (state & htp::Parser::S_ERROR) {
108
- return LCB_PROTOCOL_ERROR;
109
- }
110
-
111
- if (diff & htp::Parser::S_HEADER) {
112
- /* see that we got a success? */
113
- if (resp.status == 200) {
114
- /* nothing */
115
- } else if (resp.status == 404) {
116
- const int urlmode = http->settings().bc_http_urltype;
117
- err = LCB_BUCKET_ENOENT;
118
-
119
- if (++http->uritype > LCB_HTCONFIG_URLTYPE_COMPAT) {
120
- 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));
121
- goto GT_HT_ERROR;
122
-
123
- } else if ((urlmode & LCB_HTCONFIG_URLTYPE_COMPAT) == 0) {
124
- lcb_log(LOGARGS(http, ERR), LOGFMT "Got 404 on config stream for terse URI. Compat URI disabled, so not trying", LOGID(http));
125
-
126
- } else {
127
- /* reissue the request; but wait for it to drain */
128
- lcb_log(LOGARGS(http, WARN), LOGFMT "Got 404 on config stream. Assuming terse URI not supported on cluster", LOGID(http));
129
- http->try_nexturi = 1;
130
- err = LCB_SUCCESS;
131
- goto GT_CHECKDONE;
132
- }
133
- } else if (resp.status == 401) {
134
- err = LCB_AUTH_ERROR;
135
- } else {
136
- err = LCB_ERROR;
137
- }
138
-
139
- GT_HT_ERROR:
140
- if (err != LCB_SUCCESS) {
141
- lcb_log(LOGARGS(http, ERR), LOGFMT "Got non-success HTTP status code %d", LOGID(http), resp.status);
142
- return err;
143
- }
144
- }
145
-
146
- GT_CHECKDONE:
147
- if (http->try_nexturi) {
148
- lcb_host_t *host;
149
- if (!(state & htp::Parser::S_DONE)) {
150
- return LCB_SUCCESS;
151
- }
152
- host = lcbio_get_host(lcbio_ctx_sock(http->ioctx));
153
- http->try_nexturi = 0;
154
- if ((err = http->setup_request_header(*host)) != LCB_SUCCESS) {
155
- return err;
156
- }
157
-
158
- /* reset the state? */
159
- http->htp->reset();
160
- lcbio_ctx_put(http->ioctx, http->request_buf.c_str(), http->request_buf.size());
161
- return LCB_SUCCESS;
162
- }
163
-
164
- if (http->settings().conntype == LCB_TYPE_CLUSTER) {
165
- /* don't bother with parsing the actual config */
166
- resp.body.clear();
167
- return LCB_SUCCESS;
168
- }
169
- if (!(state & htp::Parser::S_BODY)) {
170
- /* nothing to parse yet */
171
- return LCB_SUCCESS;
172
- }
173
-
174
- /* seek ahead for strstr */
175
- size_t termpos = resp.body.find(CONFIG_DELIMITER);
176
- if (termpos == std::string::npos) {
177
- return LCB_SUCCESS;
178
- }
179
- resp.body[termpos] = '\0';
180
- cfgh = lcbvb_create();
181
- if (!cfgh) {
182
- return LCB_CLIENT_ENOMEM;
183
- }
184
- rv = lcbvb_load_json(cfgh, resp.body.c_str());
185
- if (rv != 0) {
186
- lcb_log(LOGARGS(http, ERR), LOGFMT "Failed to parse a valid config from HTTP stream", LOGID(http));
187
- lcb_log_badconfig(LOGARGS(http, ERR), cfgh, resp.body.c_str());
188
- lcbvb_destroy(cfgh);
189
- return LCB_PROTOCOL_ERROR;
190
- }
191
- if (http->last_parsed) {
192
- http->last_parsed->decref();
193
- }
194
- http->last_parsed = ConfigInfo::create(cfgh, CLCONFIG_HTTP);
195
- http->generation++;
196
-
197
- /** Relocate the stream */
198
- resp.body.erase(0, termpos + sizeof(CONFIG_DELIMITER)-1);
199
- return LCB_SUCCESS;
200
- }
201
-
202
- /**
203
- * Common function to handle parsing the HTTP stream for both v0 and v1 io
204
- * implementations.
205
- */
206
- static void
207
- read_common(lcbio_CTX *ctx, unsigned nr)
208
- {
209
- lcbio_CTXRDITER riter;
210
- HttpProvider *http = reinterpret_cast<HttpProvider*>(lcbio_ctx_data(ctx));
211
- int old_generation = http->generation;
212
-
213
- lcb_log(LOGARGS(http, TRACE), LOGFMT "Received %d bytes on HTTP stream", LOGID(http), nr);
214
- http->io_timer.rearm(http->settings().config_node_timeout);
215
-
216
- LCBIO_CTX_ITERFOR(ctx, &riter, nr) {
217
- unsigned nbuf = lcbio_ctx_risize(&riter);
218
- void *buf = lcbio_ctx_ribuf(&riter);
219
- lcb_error_t err = process_chunk(http, buf, nbuf);
220
-
221
- if (err != LCB_SUCCESS) {
222
- http->on_io_error(err);
223
- return;
224
- }
225
- }
226
-
227
- if (http->generation != old_generation) {
228
- lcb_log(LOGARGS(http, DEBUG), LOGFMT "Generation %d -> %d", LOGID(http), old_generation, http->generation);
229
- http->io_timer.cancel();
230
- set_new_config(http);
231
- }
232
-
233
- lcbio_ctx_rwant(ctx, 1);
234
- lcbio_ctx_schedule(ctx);
235
- }
236
-
237
- lcb_error_t HttpProvider::setup_request_header(const lcb_host_t &host) {
238
- request_buf.assign("GET ");
239
- if (settings().conntype == LCB_TYPE_BUCKET) {
240
- if (uritype == LCB_HTCONFIG_URLTYPE_25PLUS) {
241
- request_buf.append(REQBUCKET_TERSE_PREFIX);
242
- } else {
243
- request_buf.append(REQBUCKET_COMPAT_PREFIX);
244
- }
245
- request_buf.append(settings().bucket);
246
- } else if (settings().conntype == LCB_TYPE_CLUSTER) {
247
- request_buf.append(REQPOOLS_URI);
248
- } else {
249
- return LCB_EINVAL;
250
- }
251
-
252
- request_buf.append(" HTTP/1.1\r\n");
253
- const char *username = NULL, *password = NULL;
254
- lcbauth_get_upass(settings().auth, &username, &password);
255
-
256
- if (password) {
257
- char cred[256], b64[256];
258
- snprintf(cred, sizeof(cred), "%s:%s", username, password);
259
-
260
- if (lcb_base64_encode(cred, b64, sizeof(b64)) == -1) {
261
- return LCB_EINTERNAL;
262
- }
263
- request_buf.append("Authorization: Basic ").append(b64).append("\r\n");
264
- }
265
- request_buf.append("Host: ").append(host.host).append(":").append(host.port).append("\r\n");
266
- request_buf.append("User-Agent: libcouchbase/").append(LCB_VERSION_STRING).append("\r\n");
267
- request_buf.append("\r\n");
268
- return LCB_SUCCESS;
269
- }
270
-
271
- void HttpProvider::reset_stream_state() {
272
- const int urlmode = settings().bc_http_urltype;
273
- if (last_parsed) {
274
- last_parsed->decref();
275
- last_parsed = NULL;
276
- }
277
- if (urlmode & LCB_HTCONFIG_URLTYPE_25PLUS) {
278
- uritype = LCB_HTCONFIG_URLTYPE_25PLUS;
279
- } else {
280
- uritype = LCB_HTCONFIG_URLTYPE_COMPAT;
281
- }
282
- try_nexturi = false;
283
- htp->reset();
284
- }
285
-
286
- static void
287
- on_connected(lcbio_SOCKET *sock, void *arg, lcb_error_t err, lcbio_OSERR syserr)
288
- {
289
- HttpProvider *http = reinterpret_cast<HttpProvider*>(arg);
290
- lcb_host_t *host;
291
- lcbio_CTXPROCS procs;
292
- http->creq = NULL;
293
-
294
- if (err != LCB_SUCCESS) {
295
- lcb_log(LOGARGS(http, ERR), "Connection to REST API failed with %s (os errno = %d)", lcb_strerror_short(err), syserr);
296
- http->on_io_error(err);
297
- return;
298
- }
299
- host = lcbio_get_host(sock);
300
- lcb_log(LOGARGS(http, DEBUG), "Successfuly connected to REST API %s:%s", host->host, host->port);
301
-
302
- lcbio_sslify_if_needed(sock, http->parent->settings);
303
- http->reset_stream_state();
304
-
305
- if ((err = http->setup_request_header(*host)) != LCB_SUCCESS) {
306
- lcb_log(LOGARGS(http, ERR), "Couldn't setup request header");
307
- http->on_io_error(err);
308
- return;
309
- }
310
-
311
- memset(&procs, 0, sizeof(procs));
312
- procs.cb_err = io_error_handler;
313
- procs.cb_read = read_common;
314
- http->ioctx = lcbio_ctx_new(sock, http, &procs);
315
- http->ioctx->subsys = "bc_http";
316
-
317
- lcbio_ctx_put(http->ioctx, http->request_buf.c_str(), http->request_buf.size());
318
- lcbio_ctx_rwant(http->ioctx, 1);
319
- lcbio_ctx_schedule(http->ioctx);
320
- http->io_timer.rearm(http->settings().config_node_timeout);
321
- }
322
-
323
- void HttpProvider::on_timeout() {
324
- lcb_log(LOGARGS(this, ERR), LOGFMT "HTTP Provider timed out waiting for I/O", LOGID(this));
325
-
326
- /**
327
- * If we're not the current provider then ignore the timeout until we're
328
- * actively requested to do so
329
- */
330
- if (this != parent->cur_provider || !parent->is_refreshing()) {
331
- lcb_log(LOGARGS(this, DEBUG), LOGFMT "Ignoring timeout because we're either not in a refresh or not the current provider", LOGID(this));
332
- return;
333
- }
334
-
335
- on_io_error(LCB_ETIMEDOUT);
336
- }
337
-
338
-
339
- lcb_error_t HttpProvider::connect_next() {
340
- lcb_log(LOGARGS(this, TRACE), "Starting HTTP Configuration Provider %p", (void*)this);
341
- close_current();
342
- as_reconnect.cancel();
343
-
344
- if (nodes->empty()) {
345
- lcb_log(LOGARGS(this, ERROR), "Not scheduling HTTP provider since no nodes have been configured for HTTP bootstrap");
346
- return LCB_CONNECT_ERROR;
347
- }
348
-
349
- creq = lcbio_connect_hl(parent->iot, &settings(), nodes, 1,
350
- settings().config_node_timeout, on_connected, this);
351
- if (creq) {
352
- return LCB_SUCCESS;
353
- }
354
- lcb_log(LOGARGS(this, ERROR), "%p: Couldn't schedule connection", (void*)this);
355
- return LCB_CONNECT_ERROR;
356
- }
357
-
358
- void HttpProvider::delayed_disconn() {
359
- lcb_log(LOGARGS(this, DEBUG), "Stopping HTTP provider %p", (void*)this);
360
-
361
- /** closes the connection and cleans up the timer */
362
- close_current();
363
- io_timer.cancel();
364
- }
365
-
366
- void HttpProvider::delayed_reconnect() {
367
- if (ioctx) {
368
- /* have a context already */
369
- return;
370
- }
371
- lcb_error_t err = connect_next();
372
- if (err != LCB_SUCCESS) {
373
- on_io_error(err);
374
- }
375
- }
376
-
377
- bool HttpProvider::pause() {
378
- if (is_v220_compat()) {
379
- return LCB_SUCCESS;
380
- }
381
- disconn_timer.arm_if_disarmed(settings().bc_http_stream_time);
382
- return LCB_SUCCESS;
383
- }
384
-
385
- lcb_error_t HttpProvider::refresh() {
386
- /**
387
- * We want a grace interval here because we might already be fetching a
388
- * connection. HOWEVER we don't want to indefinitely wait on a socket
389
- * so we issue a timer indicating how long we expect to wait for a
390
- * streaming update until we get something.
391
- */
392
-
393
- /** If we need a new socket, we do connect_next. */
394
- if (ioctx == NULL && creq == NULL) {
395
- as_reconnect.signal();
396
- }
397
- disconn_timer.cancel();
398
- if (ioctx) {
399
- io_timer.rearm(settings().config_node_timeout);
400
- }
401
- return LCB_SUCCESS;
402
- }
403
-
404
- ConfigInfo* HttpProvider::get_cached() {
405
- return current_config;
406
- }
407
-
408
- void HttpProvider::config_updated(lcbvb_CONFIG *newconfig)
409
- {
410
- unsigned sopts;
411
- lcbvb_SVCMODE mode;
412
- nodes->clear();
413
-
414
- sopts = settings().sslopts;
415
- if (sopts & LCB_SSL_ENABLED) {
416
- mode = LCBVB_SVCMODE_SSL;
417
- } else {
418
- mode = LCBVB_SVCMODE_PLAIN;
419
- }
420
-
421
- for (size_t ii = 0; ii < newconfig->nsrv; ++ii) {
422
- const char *ss;
423
- lcb_error_t status;
424
- ss = lcbvb_get_hostport(newconfig, ii, LCBVB_SVCTYPE_MGMT, mode);
425
- if (!ss) {
426
- /* not supported? */
427
- continue;
428
- }
429
- status = nodes->add(ss, LCB_CONFIG_HTTP_PORT);
430
- lcb_assert(status == LCB_SUCCESS);
431
- }
432
- if (nodes->empty()) {
433
- lcb_log(LOGARGS(this, FATAL), "New nodes do not contain management ports");
434
- }
435
-
436
- if (settings().randomize_bootstrap_nodes) {
437
- nodes->randomize();
438
- }
439
- }
440
-
441
- void HttpProvider::configure_nodes(const lcb::Hostlist& newnodes) {
442
- nodes->assign(newnodes);
443
- if (settings().randomize_bootstrap_nodes) {
444
- nodes->randomize();
445
- }
446
- }
447
-
448
- const lcb::Hostlist* HttpProvider::get_nodes() const {
449
- return nodes;
450
- }
451
-
452
- HttpProvider::~HttpProvider() {
453
- reset_stream_state();
454
- close_current();
455
- delete htp;
456
- disconn_timer.release();
457
- io_timer.release();
458
- as_reconnect.release();
459
-
460
- if (current_config) {
461
- current_config->decref();
462
- }
463
- if (nodes) {
464
- delete nodes;
465
- }
466
- }
467
-
468
- void HttpProvider::dump(FILE *fp) const {
469
- fprintf(fp, "## BEGIN HTTP PROVIDER DUMP\n");
470
- fprintf(fp, "NUMBER OF CONFIGS RECEIVED: %u\n", generation);
471
- fprintf(fp, "DUMPING I/O TIMER\n");
472
- io_timer.dump(fp);
473
- if (ioctx) {
474
- fprintf(fp, "DUMPING CURRENT CONNECTION:\n");
475
- lcbio_ctx_dump(ioctx, fp);
476
- } else if (creq) {
477
- fprintf(fp, "CURRENTLY CONNECTING..\n");
478
- } else {
479
- fprintf(fp, "NO CONNECTION ACTIVE\n");
480
- }
481
- }
482
-
483
-
484
- HttpProvider::HttpProvider(Confmon *parent_)
485
- : Provider(parent_, CLCONFIG_HTTP),
486
- ioctx(NULL),
487
- htp(new lcb::htparse::Parser(parent->settings)),
488
- disconn_timer(parent->iot, this),
489
- io_timer(parent->iot, this),
490
- as_reconnect(parent->iot, this),
491
- nodes(new Hostlist()),
492
- current_config(NULL),
493
- last_parsed(NULL),
494
- generation(0),
495
- try_nexturi(false),
496
- uritype(0) {
497
-
498
- memset(&creq, 0, sizeof creq);
499
- }
500
-
501
- static void
502
- io_error_handler(lcbio_CTX *ctx, lcb_error_t err)
503
- {
504
- reinterpret_cast<HttpProvider *>(lcbio_ctx_data(ctx))->on_io_error(err);
505
- }
506
-
507
-
508
- const lcbio_SOCKET* lcb::clconfig::http_get_conn(const Provider *p) {
509
- const HttpProvider *http = static_cast<const HttpProvider *>(p);
510
- if (!http->ioctx) {
511
- return NULL;
512
- }
513
- return lcbio_ctx_sock(http->ioctx);
514
-
515
- }
516
-
517
- const lcb_host_t* lcb::clconfig::http_get_host(const Provider *p)
518
- {
519
- const lcbio_SOCKET *sock = http_get_conn(p);
520
- if (sock) {
521
- return lcbio_get_host(sock);
522
- }
523
- return NULL;
524
- }
525
-
526
- Provider* lcb::clconfig::new_http_provider(Confmon* mon) {
527
- return new HttpProvider(mon);
528
- }