libcouchbase 0.3.3 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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
- }