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.
- checksums.yaml +4 -4
- data/ext/libcouchbase/CMakeLists.txt +6 -8
- data/ext/libcouchbase/README.markdown +2 -2
- data/ext/libcouchbase/RELEASE_NOTES.markdown +229 -2
- data/ext/libcouchbase/cmake/Modules/ConfigureDtrace.cmake +11 -0
- data/ext/libcouchbase/cmake/Modules/GenerateConfigDotH.cmake +18 -0
- data/ext/libcouchbase/cmake/Modules/GetLibcouchbaseFlags.cmake +3 -2
- data/ext/libcouchbase/cmake/Modules/GetVersionInfo.cmake +3 -3
- data/ext/libcouchbase/cmake/config-cmake.h.in +4 -0
- data/ext/libcouchbase/cmake/defs.mk.in +0 -2
- data/ext/libcouchbase/cmake/source_files.cmake +21 -5
- data/ext/libcouchbase/contrib/cJSON/cJSON.c +1 -1
- data/ext/libcouchbase/contrib/cbsasl/src/client.c +2 -0
- data/ext/libcouchbase/example/users/README +48 -0
- data/ext/libcouchbase/example/users/users.c +147 -0
- data/ext/libcouchbase/include/libcouchbase/auth.h +175 -31
- data/ext/libcouchbase/include/libcouchbase/cntl.h +82 -1
- data/ext/libcouchbase/include/libcouchbase/couchbase.h +45 -3
- data/ext/libcouchbase/include/libcouchbase/error.h +19 -1
- data/ext/libcouchbase/include/libcouchbase/iops.h +3 -0
- data/ext/libcouchbase/include/libcouchbase/n1ql.h +31 -1
- data/ext/libcouchbase/include/libcouchbase/plugins/io/bsdio-inl.c +4 -1
- data/ext/libcouchbase/include/libcouchbase/subdoc.h +36 -2
- data/ext/libcouchbase/include/libcouchbase/views.h +7 -1
- data/ext/libcouchbase/include/libcouchbase/visibility.h +1 -0
- data/ext/libcouchbase/include/memcached/protocol_binary.h +24 -1146
- data/ext/libcouchbase/packaging/parse-git-describe.pl +1 -1
- data/ext/libcouchbase/plugins/io/libev/libev_io_opts.h +3 -2
- data/ext/libcouchbase/src/README.md +0 -2
- data/ext/libcouchbase/src/auth-priv.h +23 -4
- data/ext/libcouchbase/src/auth.cc +51 -43
- data/ext/libcouchbase/src/bootstrap.cc +244 -0
- data/ext/libcouchbase/src/bootstrap.h +58 -38
- data/ext/libcouchbase/src/bucketconfig/bc_cccp.cc +120 -158
- data/ext/libcouchbase/src/bucketconfig/bc_file.cc +281 -0
- data/ext/libcouchbase/src/bucketconfig/bc_http.cc +526 -0
- data/ext/libcouchbase/src/bucketconfig/bc_http.h +50 -25
- data/ext/libcouchbase/src/bucketconfig/bc_static.cc +150 -0
- data/ext/libcouchbase/src/bucketconfig/clconfig.h +410 -386
- data/ext/libcouchbase/src/bucketconfig/confmon.cc +393 -0
- data/ext/libcouchbase/src/cbft.cc +22 -27
- data/ext/libcouchbase/src/cntl.cc +56 -22
- data/ext/libcouchbase/src/connspec.cc +47 -6
- data/ext/libcouchbase/src/connspec.h +27 -0
- data/ext/libcouchbase/src/dns-srv.cc +147 -0
- data/ext/libcouchbase/src/dump.cc +3 -3
- data/ext/libcouchbase/src/errmap.cc +173 -0
- data/ext/libcouchbase/src/errmap.h +198 -0
- data/ext/libcouchbase/src/getconfig.cc +7 -33
- data/ext/libcouchbase/src/handler.cc +118 -7
- data/ext/libcouchbase/src/hostlist.cc +0 -36
- data/ext/libcouchbase/src/hostlist.h +44 -62
- data/ext/libcouchbase/src/http/http-priv.h +125 -112
- data/ext/libcouchbase/src/http/http.cc +27 -35
- data/ext/libcouchbase/src/http/http.h +1 -34
- data/ext/libcouchbase/src/http/http_io.cc +28 -36
- data/ext/libcouchbase/src/instance.cc +131 -34
- data/ext/libcouchbase/src/internal.h +58 -26
- data/ext/libcouchbase/src/jsparse/parser.cc +136 -210
- data/ext/libcouchbase/src/jsparse/parser.h +84 -98
- data/ext/libcouchbase/src/lcbht/lcbht.cc +177 -0
- data/ext/libcouchbase/src/lcbht/lcbht.h +174 -163
- data/ext/libcouchbase/src/lcbio/connect.cc +569 -0
- data/ext/libcouchbase/src/lcbio/connect.h +16 -7
- data/ext/libcouchbase/src/lcbio/ctx.c +1 -1
- data/ext/libcouchbase/src/lcbio/iotable.h +101 -16
- data/ext/libcouchbase/src/lcbio/{ioutils.c → ioutils.cc} +30 -51
- data/ext/libcouchbase/src/lcbio/ioutils.h +29 -90
- data/ext/libcouchbase/src/lcbio/manager.cc +543 -0
- data/ext/libcouchbase/src/lcbio/manager.h +133 -96
- data/ext/libcouchbase/src/lcbio/protoctx.c +2 -2
- data/ext/libcouchbase/src/lcbio/timer-cxx.h +87 -0
- data/ext/libcouchbase/src/mc/mcreq.c +11 -2
- data/ext/libcouchbase/src/mc/mcreq.h +9 -2
- data/ext/libcouchbase/src/mcserver/mcserver.cc +175 -43
- data/ext/libcouchbase/src/mcserver/mcserver.h +9 -13
- data/ext/libcouchbase/src/mcserver/negotiate.cc +181 -62
- data/ext/libcouchbase/src/mcserver/negotiate.h +1 -3
- data/ext/libcouchbase/src/mctx-helper.h +51 -0
- data/ext/libcouchbase/src/n1ql/ixmgmt.cc +1 -2
- data/ext/libcouchbase/src/n1ql/n1ql.cc +74 -42
- data/ext/libcouchbase/src/netbuf/netbuf.c +4 -4
- data/ext/libcouchbase/src/newconfig.cc +6 -6
- data/ext/libcouchbase/src/nodeinfo.cc +2 -2
- data/ext/libcouchbase/src/operations/{cbflush.c → cbflush.cc} +7 -15
- data/ext/libcouchbase/src/operations/{counter.c → counter.cc} +0 -0
- data/ext/libcouchbase/src/operations/durability.cc +6 -26
- data/ext/libcouchbase/src/operations/durability_internal.h +6 -3
- data/ext/libcouchbase/src/operations/{get.c → get.cc} +24 -26
- data/ext/libcouchbase/src/operations/{observe.c → observe.cc} +68 -93
- data/ext/libcouchbase/src/operations/{pktfwd.c → pktfwd.cc} +0 -0
- data/ext/libcouchbase/src/operations/{remove.c → remove.cc} +0 -0
- data/ext/libcouchbase/src/operations/stats.cc +3 -8
- data/ext/libcouchbase/src/operations/{store.c → store.cc} +27 -32
- data/ext/libcouchbase/src/operations/subdoc.cc +129 -42
- data/ext/libcouchbase/src/operations/{touch.c → touch.cc} +0 -0
- data/ext/libcouchbase/src/packetutils.h +30 -2
- data/ext/libcouchbase/src/probes.d +1 -1
- data/ext/libcouchbase/src/rdb/rope.c +1 -1
- data/ext/libcouchbase/src/{retrychk.c → retrychk.cc} +2 -3
- data/ext/libcouchbase/src/retryq.cc +52 -14
- data/ext/libcouchbase/src/retryq.h +3 -3
- data/ext/libcouchbase/src/settings.c +5 -0
- data/ext/libcouchbase/src/settings.h +11 -0
- data/ext/libcouchbase/src/ssl/ssl_c.c +1 -0
- data/ext/libcouchbase/src/ssl/ssl_common.c +2 -0
- data/ext/libcouchbase/src/ssl/ssl_e.c +0 -1
- data/ext/libcouchbase/src/strcodecs/strcodecs.h +1 -1
- data/ext/libcouchbase/src/trace.h +4 -4
- data/ext/libcouchbase/src/vbucket/vbucket.c +6 -10
- data/ext/libcouchbase/src/views/{docreq.c → docreq.cc} +48 -54
- data/ext/libcouchbase/src/views/docreq.h +24 -30
- data/ext/libcouchbase/src/views/viewreq.cc +318 -0
- data/ext/libcouchbase/src/views/viewreq.h +43 -13
- data/ext/libcouchbase/tests/basic/t_connstr.cc +88 -50
- data/ext/libcouchbase/tests/basic/t_creds.cc +47 -5
- data/ext/libcouchbase/tests/basic/t_host.cc +67 -75
- data/ext/libcouchbase/tests/basic/t_jsparse.cc +27 -82
- data/ext/libcouchbase/tests/basic/t_misc.cc +1 -1
- data/ext/libcouchbase/tests/basic/t_n1qlstrings.cc +0 -1
- data/ext/libcouchbase/tests/htparse/t_basic.cc +58 -78
- data/ext/libcouchbase/tests/ioserver/connection.cc +1 -1
- data/ext/libcouchbase/tests/ioserver/ioserver.cc +19 -6
- data/ext/libcouchbase/tests/iotests/mock-environment.cc +28 -2
- data/ext/libcouchbase/tests/iotests/mock-environment.h +51 -1
- data/ext/libcouchbase/tests/iotests/t_behavior.cc +1 -7
- data/ext/libcouchbase/tests/iotests/t_confmon.cc +97 -115
- data/ext/libcouchbase/tests/iotests/t_durability.cc +0 -1
- data/ext/libcouchbase/tests/iotests/t_eerrs.cc +119 -0
- data/ext/libcouchbase/tests/iotests/t_errmap.cc +178 -0
- data/ext/libcouchbase/tests/iotests/t_misc.cc +3 -3
- data/ext/libcouchbase/tests/iotests/t_netfail.cc +1 -1
- data/ext/libcouchbase/tests/iotests/t_obseqno.cc +0 -1
- data/ext/libcouchbase/tests/iotests/t_subdoc.cc +18 -11
- data/ext/libcouchbase/tests/mc/t_alloc.cc +9 -9
- data/ext/libcouchbase/tests/socktests/socktest.cc +7 -10
- data/ext/libcouchbase/tests/socktests/socktest.h +2 -3
- data/ext/libcouchbase/tests/socktests/t_basic.cc +6 -6
- data/ext/libcouchbase/tests/socktests/t_manager.cc +5 -6
- data/ext/libcouchbase/tests/socktests/t_ssl.cc +1 -1
- data/ext/libcouchbase/tests/vbucket/confdata/ketama_expected.json +2562 -0
- data/ext/libcouchbase/tests/vbucket/confdata/memd_ketama_config.json +31 -0
- data/ext/libcouchbase/tests/vbucket/t_config.cc +35 -5
- data/ext/libcouchbase/tools/CMakeLists.txt +2 -2
- data/ext/libcouchbase/tools/cbc-handlers.h +128 -0
- data/ext/libcouchbase/tools/cbc-n1qlback.cc +64 -10
- data/ext/libcouchbase/tools/cbc-pillowfight.cc +2 -2
- data/ext/libcouchbase/tools/cbc.cc +143 -10
- data/ext/libcouchbase/tools/docgen/loc.h +1 -1
- data/lib/libcouchbase/connection.rb +4 -3
- data/lib/libcouchbase/version.rb +1 -1
- metadata +37 -28
- data/ext/libcouchbase/include/memcached/vbucket.h +0 -42
- data/ext/libcouchbase/src/bootstrap.c +0 -269
- data/ext/libcouchbase/src/bucketconfig/bc_file.c +0 -347
- data/ext/libcouchbase/src/bucketconfig/bc_http.c +0 -630
- data/ext/libcouchbase/src/bucketconfig/bc_mcraw.c +0 -150
- data/ext/libcouchbase/src/bucketconfig/confmon.c +0 -474
- data/ext/libcouchbase/src/lcbht/lcbht.c +0 -282
- data/ext/libcouchbase/src/lcbio/connect.c +0 -557
- data/ext/libcouchbase/src/lcbio/manager.c +0 -584
- data/ext/libcouchbase/src/packetutils.c +0 -37
- data/ext/libcouchbase/src/simplestring.c +0 -211
- data/ext/libcouchbase/src/simplestring.h +0 -228
- data/ext/libcouchbase/src/ssobuf.h +0 -82
- data/ext/libcouchbase/src/views/viewreq.c +0 -358
- data/ext/libcouchbase/tests/basic/t_string.cc +0 -112
|
@@ -19,6 +19,7 @@
|
|
|
19
19
|
#include "bucketconfig/clconfig.h"
|
|
20
20
|
#include "http/http.h"
|
|
21
21
|
#include "http/http-priv.h"
|
|
22
|
+
#include "auth-priv.h"
|
|
22
23
|
using namespace lcb::http;
|
|
23
24
|
|
|
24
25
|
#define LOGFMT "<%s:%s> "
|
|
@@ -43,7 +44,7 @@ Request::decref()
|
|
|
43
44
|
close_io();
|
|
44
45
|
|
|
45
46
|
if (parser) {
|
|
46
|
-
|
|
47
|
+
delete parser;
|
|
47
48
|
}
|
|
48
49
|
|
|
49
50
|
if (timer) {
|
|
@@ -103,7 +104,6 @@ void
|
|
|
103
104
|
Request::maybe_refresh_config(lcb_error_t err)
|
|
104
105
|
{
|
|
105
106
|
int htstatus_ok;
|
|
106
|
-
lcbht_RESPONSE *resp;
|
|
107
107
|
if (!parser) {
|
|
108
108
|
return;
|
|
109
109
|
}
|
|
@@ -112,25 +112,25 @@ Request::maybe_refresh_config(lcb_error_t err)
|
|
|
112
112
|
return;
|
|
113
113
|
}
|
|
114
114
|
|
|
115
|
-
resp =
|
|
116
|
-
htstatus_ok = resp
|
|
115
|
+
const lcb::htparse::Response& resp = parser->get_cur_response();
|
|
116
|
+
htstatus_ok = resp.status >= 200 && resp.status < 299;
|
|
117
117
|
|
|
118
118
|
if (err != LCB_SUCCESS && (err == LCB_ESOCKSHUTDOWN && htstatus_ok) == 0) {
|
|
119
119
|
/* ignore graceful close */
|
|
120
|
-
|
|
120
|
+
instance->bootstrap(BS_REFRESH_ALWAYS);
|
|
121
121
|
return;
|
|
122
122
|
}
|
|
123
123
|
|
|
124
124
|
if (htstatus_ok) {
|
|
125
125
|
return;
|
|
126
126
|
}
|
|
127
|
-
|
|
127
|
+
instance->bootstrap(BS_REFRESH_ALWAYS);
|
|
128
128
|
}
|
|
129
129
|
|
|
130
130
|
void
|
|
131
131
|
Request::init_resp(lcb_RESPHTTP *res)
|
|
132
132
|
{
|
|
133
|
-
const
|
|
133
|
+
const lcb::htparse::Response& htres = parser->get_cur_response();
|
|
134
134
|
|
|
135
135
|
res->cookie = const_cast<void*>(command_cookie);
|
|
136
136
|
res->key = url.c_str() + url_info.field_data[UF_PATH].off;
|
|
@@ -139,9 +139,7 @@ Request::init_resp(lcb_RESPHTTP *res)
|
|
|
139
139
|
if (!response_headers.empty()) {
|
|
140
140
|
res->headers = &response_headers_clist[0];
|
|
141
141
|
}
|
|
142
|
-
|
|
143
|
-
res->htstatus = htres->status;
|
|
144
|
-
}
|
|
142
|
+
res->htstatus = htres.status;
|
|
145
143
|
}
|
|
146
144
|
|
|
147
145
|
void
|
|
@@ -254,9 +252,9 @@ Request::submit()
|
|
|
254
252
|
// Only wipe old parser/response information if current I/O request
|
|
255
253
|
// was a success
|
|
256
254
|
if (parser) {
|
|
257
|
-
|
|
255
|
+
parser->reset();
|
|
258
256
|
} else {
|
|
259
|
-
parser =
|
|
257
|
+
parser = new lcb::htparse::Parser(instance->settings);
|
|
260
258
|
}
|
|
261
259
|
response_headers.clear();
|
|
262
260
|
response_headers_clist.clear();
|
|
@@ -408,6 +406,10 @@ Request::get_api_node(lcb_error_t &rc)
|
|
|
408
406
|
return lcbvb_get_resturl(vbc, ix, svc, mode);
|
|
409
407
|
}
|
|
410
408
|
|
|
409
|
+
static bool is_nonempty(const char *s) {
|
|
410
|
+
return s != NULL && *s != '\0';
|
|
411
|
+
}
|
|
412
|
+
|
|
411
413
|
lcb_error_t
|
|
412
414
|
Request::setup_inputs(const lcb_CMDHTTP *cmd)
|
|
413
415
|
{
|
|
@@ -433,11 +435,13 @@ Request::setup_inputs(const lcb_CMDHTTP *cmd)
|
|
|
433
435
|
if (cmd->cmdflags & LCB_CMDHTTP_F_NOUPASS) {
|
|
434
436
|
username = password = NULL;
|
|
435
437
|
} else if (username == NULL && password == NULL) {
|
|
438
|
+
const Authenticator& auth = *LCBT_SETTING(instance, auth);
|
|
436
439
|
if (reqtype == LCB_HTTP_TYPE_MANAGEMENT) {
|
|
437
|
-
|
|
440
|
+
username = auth.username().c_str();
|
|
441
|
+
password = auth.password().c_str();
|
|
438
442
|
} else {
|
|
439
|
-
username = LCBT_SETTING(instance, bucket);
|
|
440
|
-
password =
|
|
443
|
+
username = auth.username_for(LCBT_SETTING(instance, bucket)).c_str();
|
|
444
|
+
password = auth.password_for(LCBT_SETTING(instance, bucket)).c_str();
|
|
441
445
|
}
|
|
442
446
|
}
|
|
443
447
|
|
|
@@ -462,13 +466,18 @@ Request::setup_inputs(const lcb_CMDHTTP *cmd)
|
|
|
462
466
|
return rc;
|
|
463
467
|
}
|
|
464
468
|
|
|
465
|
-
|
|
466
|
-
if (instance->
|
|
469
|
+
std::string ua("libcouchbase/" LCB_VERSION_STRING);
|
|
470
|
+
if (instance->settings->client_string) {
|
|
471
|
+
ua.append(" ").append(instance->settings->client_string);
|
|
472
|
+
}
|
|
473
|
+
add_header("User-Agent", ua);
|
|
474
|
+
|
|
475
|
+
if (instance->http_sockpool->get_options().maxidle == 0 || !is_data_request()) {
|
|
467
476
|
add_header("Connection", "close");
|
|
468
477
|
}
|
|
469
478
|
|
|
470
479
|
add_header("Accept", "application/json");
|
|
471
|
-
if (password && username) {
|
|
480
|
+
if (is_nonempty(password) && is_nonempty(username)) {
|
|
472
481
|
char auth[256];
|
|
473
482
|
std::string upassbuf;
|
|
474
483
|
upassbuf.append(username).append(":").append(password);
|
|
@@ -613,23 +622,6 @@ Request::cancel()
|
|
|
613
622
|
finish(LCB_SUCCESS);
|
|
614
623
|
}
|
|
615
624
|
|
|
616
|
-
// Wrappers
|
|
617
|
-
void lcb_htreq_setcb(lcb_http_request_t req, lcb_RESPCALLBACK callback) {
|
|
618
|
-
req->callback = callback;
|
|
619
|
-
}
|
|
620
|
-
void lcb_htreq_block_callback(lcb_http_request_t req) {
|
|
621
|
-
req->block_callback();
|
|
622
|
-
}
|
|
623
|
-
void lcb_htreq_pause(lcb_http_request_t req) {
|
|
624
|
-
req->pause();
|
|
625
|
-
}
|
|
626
|
-
void lcb_htreq_resume(lcb_http_request_t req) {
|
|
627
|
-
req->resume();
|
|
628
|
-
}
|
|
629
|
-
void lcb_htreq_finish(lcb_t, lcb_http_request_t req, lcb_error_t rc) {
|
|
630
|
-
req->finish(rc);
|
|
631
|
-
}
|
|
632
|
-
|
|
633
625
|
LIBCOUCHBASE_API
|
|
634
626
|
void
|
|
635
627
|
lcb_cancel_http_request(lcb_t, lcb_http_request_t req)
|
|
@@ -1,34 +1 @@
|
|
|
1
|
-
#
|
|
2
|
-
#define LCB_HTTPAPI_H
|
|
3
|
-
|
|
4
|
-
/* This file contains the internal API for HTTP requests. This allows us to
|
|
5
|
-
* change the internals without exposing the object structure to the rest
|
|
6
|
-
* of the library
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
|
-
#ifdef __cplusplus
|
|
10
|
-
extern "C" {
|
|
11
|
-
#endif
|
|
12
|
-
|
|
13
|
-
void
|
|
14
|
-
lcb_htreq_setcb(lcb_http_request_t, lcb_RESPCALLBACK);
|
|
15
|
-
|
|
16
|
-
void
|
|
17
|
-
lcb_htreq_pause(lcb_http_request_t);
|
|
18
|
-
|
|
19
|
-
void
|
|
20
|
-
lcb_htreq_resume(lcb_http_request_t);
|
|
21
|
-
|
|
22
|
-
void
|
|
23
|
-
lcb_htreq_finish(lcb_t, lcb_http_request_t, lcb_error_t);
|
|
24
|
-
|
|
25
|
-
/* Prevents the callback from being invoked. This is different than a full
|
|
26
|
-
* destruction of the object. This is only called in lcb_destroy() to
|
|
27
|
-
* prevent dereferencing the instance itself.
|
|
28
|
-
*/
|
|
29
|
-
void
|
|
30
|
-
lcb_htreq_block_callback(lcb_http_request_t);
|
|
31
|
-
#ifdef __cplusplus
|
|
32
|
-
}
|
|
33
|
-
#endif
|
|
34
|
-
#endif
|
|
1
|
+
#include "http-priv.h"
|
|
@@ -30,19 +30,13 @@ using namespace lcb::http;
|
|
|
30
30
|
#define LOGARGS(req, lvl) req->instance->settings, "http-io", LCB_LOG_##lvl, __FILE__, __LINE__
|
|
31
31
|
|
|
32
32
|
void
|
|
33
|
-
Request::assign_response_headers(const
|
|
33
|
+
Request::assign_response_headers(const lcb::htparse::Response& resp)
|
|
34
34
|
{
|
|
35
|
-
response_headers.
|
|
35
|
+
response_headers.assign(resp.headers.begin(), resp.headers.end());
|
|
36
36
|
response_headers_clist.clear();
|
|
37
37
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
lcbht_MIMEHDR *hdr = SLLIST_ITEM(curnode, lcbht_MIMEHDR, slnode);
|
|
41
|
-
response_headers.push_back(Header(hdr->key, hdr->value));
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
std::vector<Header>::const_iterator ii = response_headers.begin();
|
|
45
|
-
for (; ii != response_headers.end(); ++ii) {
|
|
38
|
+
std::vector<lcb::htparse::MimeHeader>::const_iterator ii;
|
|
39
|
+
for (ii = response_headers.begin(); ii != response_headers.end(); ++ii) {
|
|
46
40
|
response_headers_clist.push_back(ii->key.c_str());
|
|
47
41
|
response_headers_clist.push_back(ii->value.c_str());
|
|
48
42
|
}
|
|
@@ -53,29 +47,30 @@ int
|
|
|
53
47
|
Request::handle_parse_chunked(const char *buf, unsigned nbuf)
|
|
54
48
|
{
|
|
55
49
|
int parse_state, oldstate, diff;
|
|
56
|
-
|
|
50
|
+
using lcb::htparse::Parser;
|
|
51
|
+
lcb::htparse::Response& res = parser->get_cur_response();
|
|
57
52
|
|
|
58
53
|
do {
|
|
59
54
|
const char *rbody;
|
|
60
55
|
unsigned nused = -1, nbody = -1;
|
|
61
|
-
oldstate = res
|
|
56
|
+
oldstate = res.state;
|
|
62
57
|
|
|
63
|
-
parse_state =
|
|
58
|
+
parse_state = parser->parse_ex(buf, nbuf, &nused, &nbody, &rbody);
|
|
64
59
|
diff = oldstate ^ parse_state;
|
|
65
60
|
|
|
66
61
|
/* Got headers now for the first time */
|
|
67
|
-
if (diff &
|
|
62
|
+
if (diff & Parser::S_HEADER) {
|
|
68
63
|
assign_response_headers(res);
|
|
69
|
-
if (res
|
|
70
|
-
const char *redir =
|
|
64
|
+
if (res.status >= 300 && res.status <= 400) {
|
|
65
|
+
const char *redir = res.get_header_value("Location");
|
|
71
66
|
if (redir != NULL) {
|
|
72
67
|
pending_redirect.assign(redir);
|
|
73
|
-
return
|
|
68
|
+
return Parser::S_DONE;
|
|
74
69
|
}
|
|
75
70
|
}
|
|
76
71
|
}
|
|
77
72
|
|
|
78
|
-
if (parse_state &
|
|
73
|
+
if (parse_state & Parser::S_ERROR) {
|
|
79
74
|
/* nothing to do here */
|
|
80
75
|
return parse_state;
|
|
81
76
|
}
|
|
@@ -91,22 +86,22 @@ Request::handle_parse_chunked(const char *buf, unsigned nbuf)
|
|
|
91
86
|
callback(instance, LCB_CALLBACK_HTTP, (const lcb_RESPBASE *)&htresp);
|
|
92
87
|
|
|
93
88
|
} else {
|
|
94
|
-
|
|
89
|
+
res.body.append(rbody, nbody);
|
|
95
90
|
}
|
|
96
91
|
}
|
|
97
92
|
|
|
98
93
|
buf += nused;
|
|
99
94
|
nbuf -= nused;
|
|
100
|
-
} while ((parse_state &
|
|
95
|
+
} while ((parse_state & Parser::S_DONE) == 0 && is_ongoing() && nbuf);
|
|
101
96
|
|
|
102
|
-
if ( (parse_state &
|
|
97
|
+
if ( (parse_state & Parser::S_DONE) && is_ongoing()) {
|
|
103
98
|
lcb_RESPHTTP resp = { 0 };
|
|
104
99
|
if (chunked) {
|
|
105
100
|
buf = NULL;
|
|
106
101
|
nbuf = 0;
|
|
107
102
|
} else {
|
|
108
|
-
buf = res
|
|
109
|
-
nbuf = res
|
|
103
|
+
buf = res.body.c_str();
|
|
104
|
+
nbuf = res.body.size();
|
|
110
105
|
}
|
|
111
106
|
|
|
112
107
|
init_resp(&resp);
|
|
@@ -143,7 +138,8 @@ io_read(lcbio_CTX *ctx, unsigned nr)
|
|
|
143
138
|
nbuf = lcbio_ctx_risize(&iter);
|
|
144
139
|
parse_state = req->handle_parse_chunked(buf, nbuf);
|
|
145
140
|
|
|
146
|
-
if ((parse_state &
|
|
141
|
+
if ((parse_state & lcb::htparse::Parser::S_ERROR) ||
|
|
142
|
+
req->has_pending_redirect()) {
|
|
147
143
|
rv = -1;
|
|
148
144
|
break;
|
|
149
145
|
} else if (!req->is_ongoing()) {
|
|
@@ -156,7 +152,7 @@ io_read(lcbio_CTX *ctx, unsigned nr)
|
|
|
156
152
|
// parse error or redirect
|
|
157
153
|
lcb_error_t err;
|
|
158
154
|
if (req->has_pending_redirect()) {
|
|
159
|
-
|
|
155
|
+
instance->bootstrap(lcb::BS_REFRESH_THROTTLE);
|
|
160
156
|
// Transfer control to redirect function()
|
|
161
157
|
lcb_log(LOGARGS(req, DEBUG), LOGFMT "Attempting redirect to %s", LOGID(req), req->pending_redirect.c_str());
|
|
162
158
|
req->redirect();
|
|
@@ -224,8 +220,7 @@ on_connected(lcbio_SOCKET *sock, void *arg, lcb_error_t err, lcbio_OSERR syserr)
|
|
|
224
220
|
Request *req = reinterpret_cast<Request*>(arg);
|
|
225
221
|
lcbio_CTXPROCS procs;
|
|
226
222
|
lcb_settings *settings = req->instance->settings;
|
|
227
|
-
|
|
228
|
-
LCBIO_CONNREQ_CLEAR(&req->creq);
|
|
223
|
+
req->creq = NULL;
|
|
229
224
|
|
|
230
225
|
if (err != LCB_SUCCESS) {
|
|
231
226
|
lcb_log(LOGARGS(req, ERR), "Connection to failed with Err=0x%x", err);
|
|
@@ -252,15 +247,12 @@ lcb_error_t
|
|
|
252
247
|
Request::start_io(lcb_host_t& dest)
|
|
253
248
|
{
|
|
254
249
|
lcbio_MGR *pool = instance->http_sockpool;
|
|
255
|
-
lcbio_pMGRREQ poolreq;
|
|
256
250
|
|
|
257
|
-
|
|
258
|
-
if (!
|
|
251
|
+
creq = pool->get(dest, timeout(), on_connected, this);
|
|
252
|
+
if (!creq) {
|
|
259
253
|
return LCB_CONNECT_ERROR;
|
|
260
254
|
}
|
|
261
255
|
|
|
262
|
-
LCBIO_CONNREQ_MKPOOLED(&creq, poolreq);
|
|
263
|
-
|
|
264
256
|
if (!timer) {
|
|
265
257
|
timer = lcbio_timer_new(io, this, request_timed_out);
|
|
266
258
|
}
|
|
@@ -279,16 +271,16 @@ pool_close_cb(lcbio_SOCKET *sock, int reusable, void *arg)
|
|
|
279
271
|
|
|
280
272
|
lcbio_ref(sock);
|
|
281
273
|
if (reusable && close_ok) {
|
|
282
|
-
|
|
274
|
+
lcb::io::Pool::put(sock);
|
|
283
275
|
} else {
|
|
284
|
-
|
|
276
|
+
lcb::io::Pool::discard(sock);
|
|
285
277
|
}
|
|
286
278
|
}
|
|
287
279
|
|
|
288
280
|
void
|
|
289
281
|
Request::close_io()
|
|
290
282
|
{
|
|
291
|
-
|
|
283
|
+
lcb::io::ConnectionRequest::cancel(&creq);
|
|
292
284
|
|
|
293
285
|
if (!ioctx) {
|
|
294
286
|
return;
|
|
@@ -297,7 +289,7 @@ Request::close_io()
|
|
|
297
289
|
int can_ka;
|
|
298
290
|
|
|
299
291
|
if (parser && is_data_request()) {
|
|
300
|
-
can_ka =
|
|
292
|
+
can_ka = parser->can_keepalive();
|
|
301
293
|
} else {
|
|
302
294
|
can_ka = 0;
|
|
303
295
|
}
|
|
@@ -116,17 +116,57 @@ lcb_st::populate_nodes(const Connspec& spec)
|
|
|
116
116
|
}
|
|
117
117
|
}
|
|
118
118
|
|
|
119
|
+
lcb_error_t
|
|
120
|
+
lcb_st::process_dns_srv(Connspec& spec)
|
|
121
|
+
{
|
|
122
|
+
if (!spec.can_dnssrv()) {
|
|
123
|
+
return LCB_SUCCESS;
|
|
124
|
+
}
|
|
125
|
+
if (spec.hosts().empty()) {
|
|
126
|
+
lcb_log(LOGARGS(this, ERR), "Cannot use DNS SRV without a hostname");
|
|
127
|
+
return spec.is_explicit_dnssrv() ? LCB_EINVAL : LCB_SUCCESS;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
const Spechost& host = spec.hosts().front();
|
|
131
|
+
lcb_error_t rc = LCB_ERROR;
|
|
132
|
+
Hostlist* hl = dnssrv_getbslist(host.hostname.c_str(), host.isSSL(), rc);
|
|
133
|
+
|
|
134
|
+
if (hl == NULL) {
|
|
135
|
+
lcb_log(LOGARGS(this, INFO), "DNS SRV lookup failed: %s. Ignore this if not relying on DNS SRV records", lcb_strerror(this, rc));
|
|
136
|
+
if (spec.is_explicit_dnssrv()) {
|
|
137
|
+
return rc;
|
|
138
|
+
} else {
|
|
139
|
+
return LCB_SUCCESS;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
spec.clear_hosts();
|
|
144
|
+
for (size_t ii = 0; ii < hl->size(); ++ii) {
|
|
145
|
+
const lcb_host_t& src = (*hl)[ii];
|
|
146
|
+
Spechost sh;
|
|
147
|
+
sh.hostname = src.host;
|
|
148
|
+
sh.port = std::atoi(src.port);
|
|
149
|
+
sh.type = spec.default_port();
|
|
150
|
+
spec.add_host(sh);
|
|
151
|
+
lcb_log(LOGARGS(this, INFO), "Found host %s:%d via DNS SRV", sh.hostname.c_str(), sh.port);
|
|
152
|
+
}
|
|
153
|
+
delete hl;
|
|
154
|
+
|
|
155
|
+
return LCB_SUCCESS;
|
|
156
|
+
}
|
|
157
|
+
|
|
119
158
|
static lcb_error_t
|
|
120
159
|
init_providers(lcb_t obj, const Connspec &spec)
|
|
121
160
|
{
|
|
122
|
-
|
|
123
|
-
http
|
|
124
|
-
|
|
125
|
-
|
|
161
|
+
using namespace lcb::clconfig;
|
|
162
|
+
Provider *http, *cccp, *mcraw;
|
|
163
|
+
http = obj->confmon->get_provider(CLCONFIG_HTTP);
|
|
164
|
+
cccp = obj->confmon->get_provider(CLCONFIG_CCCP);
|
|
165
|
+
mcraw = obj->confmon->get_provider(CLCONFIG_MCRAW);
|
|
126
166
|
|
|
127
167
|
if (spec.default_port() == LCB_CONFIG_MCCOMPAT_PORT) {
|
|
128
|
-
|
|
129
|
-
mcraw->configure_nodes(
|
|
168
|
+
obj->confmon->set_active(CLCONFIG_MCRAW, true);
|
|
169
|
+
mcraw->configure_nodes(*obj->mc_nodes);
|
|
130
170
|
return LCB_SUCCESS;
|
|
131
171
|
}
|
|
132
172
|
|
|
@@ -155,26 +195,34 @@ init_providers(lcb_t obj, const Connspec &spec)
|
|
|
155
195
|
if (spec.is_bs_file()) {
|
|
156
196
|
/* If the 'file_only' provider is set, just assume something else
|
|
157
197
|
* will provide us with the config, and forget about it. */
|
|
158
|
-
|
|
198
|
+
Provider *prov = obj->confmon->get_provider(CLCONFIG_FILE);
|
|
159
199
|
if (prov && prov->enabled) {
|
|
160
200
|
return LCB_SUCCESS;
|
|
161
201
|
}
|
|
162
202
|
}
|
|
163
|
-
|
|
203
|
+
if (obj->type == LCB_TYPE_CLUSTER) {
|
|
204
|
+
/* Cluster-level connection always falls back to static config */
|
|
205
|
+
Provider *cladmin;
|
|
206
|
+
cladmin = obj->confmon->get_provider(CLCONFIG_CLADMIN);
|
|
207
|
+
cladmin->enable();
|
|
208
|
+
cladmin->configure_nodes(*obj->ht_nodes);
|
|
209
|
+
} else {
|
|
210
|
+
return LCB_BAD_ENVIRONMENT;
|
|
211
|
+
}
|
|
164
212
|
}
|
|
165
213
|
|
|
166
214
|
if (http_enabled) {
|
|
167
|
-
|
|
168
|
-
|
|
215
|
+
http->enable();
|
|
216
|
+
http->configure_nodes(*obj->ht_nodes);
|
|
169
217
|
} else {
|
|
170
|
-
|
|
218
|
+
obj->confmon->set_active(CLCONFIG_HTTP, false);
|
|
171
219
|
}
|
|
172
220
|
|
|
173
221
|
if (cccp_enabled && obj->type != LCB_TYPE_CLUSTER) {
|
|
174
|
-
|
|
175
|
-
|
|
222
|
+
cccp->enable(obj);
|
|
223
|
+
cccp->configure_nodes(*obj->mc_nodes);
|
|
176
224
|
} else {
|
|
177
|
-
|
|
225
|
+
obj->confmon->set_active(CLCONFIG_CCCP, false);
|
|
178
226
|
}
|
|
179
227
|
return LCB_SUCCESS;
|
|
180
228
|
}
|
|
@@ -345,10 +393,20 @@ lcb_error_t lcb_create(lcb_t *instance,
|
|
|
345
393
|
/* initialize the settings */
|
|
346
394
|
obj->type = type;
|
|
347
395
|
obj->settings = settings;
|
|
396
|
+
obj->settings->conntype = type;
|
|
348
397
|
|
|
349
398
|
settings->bucket = strdup(spec.bucket().c_str());
|
|
350
|
-
|
|
351
|
-
|
|
399
|
+
|
|
400
|
+
if (!spec.username().empty()) {
|
|
401
|
+
settings->auth->set_mode(LCBAUTH_MODE_RBAC);
|
|
402
|
+
err = settings->auth->add(spec.username(), spec.password(),
|
|
403
|
+
LCBAUTH_F_CLUSTER);
|
|
404
|
+
} else {
|
|
405
|
+
settings->auth->set_mode(LCBAUTH_MODE_CLASSIC);
|
|
406
|
+
err = settings->auth->add(spec.bucket(), spec.password(),
|
|
407
|
+
LCBAUTH_F_BUCKET);
|
|
408
|
+
}
|
|
409
|
+
if (err != LCB_SUCCESS) {
|
|
352
410
|
goto GT_DONE;
|
|
353
411
|
}
|
|
354
412
|
|
|
@@ -373,13 +431,19 @@ lcb_error_t lcb_create(lcb_t *instance,
|
|
|
373
431
|
|
|
374
432
|
obj->cmdq.cqdata = obj;
|
|
375
433
|
obj->iotable = lcbio_table_new(io_priv);
|
|
376
|
-
obj->memd_sockpool =
|
|
377
|
-
obj->http_sockpool =
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
434
|
+
obj->memd_sockpool = new io::Pool(settings, obj->iotable);
|
|
435
|
+
obj->http_sockpool = new io::Pool(settings, obj->iotable);
|
|
436
|
+
|
|
437
|
+
{
|
|
438
|
+
// Needs its own scope because there are prior GOTOs
|
|
439
|
+
io::Pool::Options pool_opts;
|
|
440
|
+
pool_opts.maxidle = 1;
|
|
441
|
+
pool_opts.tmoidle = LCB_MS2US(10000); // 10 seconds
|
|
442
|
+
obj->memd_sockpool->set_options(pool_opts);
|
|
443
|
+
obj->http_sockpool->set_options(pool_opts);
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
obj->confmon = new clconfig::Confmon(settings, obj->iotable);
|
|
383
447
|
obj->ht_nodes = new Hostlist();
|
|
384
448
|
obj->mc_nodes = new Hostlist();
|
|
385
449
|
obj->retryq = new RetryQueue(&obj->cmdq, obj->iotable, obj->settings);
|
|
@@ -398,8 +462,15 @@ lcb_error_t lcb_create(lcb_t *instance,
|
|
|
398
462
|
goto GT_DONE;
|
|
399
463
|
}
|
|
400
464
|
|
|
465
|
+
if ((err = obj->process_dns_srv(spec)) != LCB_SUCCESS) {
|
|
466
|
+
goto GT_DONE;
|
|
467
|
+
}
|
|
468
|
+
|
|
401
469
|
obj->populate_nodes(spec);
|
|
402
|
-
err = init_providers(obj, spec)
|
|
470
|
+
if ((err = init_providers(obj, spec)) != LCB_SUCCESS) {
|
|
471
|
+
goto GT_DONE;
|
|
472
|
+
}
|
|
473
|
+
|
|
403
474
|
if (err != LCB_SUCCESS) {
|
|
404
475
|
lcb_destroy(obj);
|
|
405
476
|
return err;
|
|
@@ -437,6 +508,8 @@ extern "C" {
|
|
|
437
508
|
void lcbdur_destroy(void*);
|
|
438
509
|
}
|
|
439
510
|
|
|
511
|
+
static void do_pool_shutdown(io::Pool *pool) { pool->shutdown(); }
|
|
512
|
+
|
|
440
513
|
LIBCOUCHBASE_API
|
|
441
514
|
void lcb_destroy(lcb_t instance)
|
|
442
515
|
{
|
|
@@ -446,10 +519,12 @@ void lcb_destroy(lcb_t instance)
|
|
|
446
519
|
lcb_ASPEND_SETTYPE::iterator it;
|
|
447
520
|
lcb_ASPEND_SETTYPE *pendq;
|
|
448
521
|
|
|
449
|
-
|
|
522
|
+
if (instance->cur_configinfo) {
|
|
523
|
+
instance->cur_configinfo->decref();
|
|
524
|
+
instance->cur_configinfo = NULL;
|
|
525
|
+
}
|
|
450
526
|
instance->cmdq.config = NULL;
|
|
451
|
-
|
|
452
|
-
lcb_bootstrap_destroy(instance);
|
|
527
|
+
DESTROY(delete, bs_state);
|
|
453
528
|
DESTROY(delete, ht_nodes);
|
|
454
529
|
DESTROY(delete, mc_nodes);
|
|
455
530
|
|
|
@@ -473,16 +548,16 @@ void lcb_destroy(lcb_t instance)
|
|
|
473
548
|
|
|
474
549
|
if ((pendq = po->items[LCB_PENDTYPE_HTTP])) {
|
|
475
550
|
for (it = pendq->begin(); it != pendq->end(); ++it) {
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
551
|
+
http::Request *htreq = reinterpret_cast<http::Request*>(*it);
|
|
552
|
+
htreq->block_callback();
|
|
553
|
+
htreq->finish(LCB_ERROR);
|
|
479
554
|
}
|
|
480
555
|
}
|
|
481
556
|
|
|
482
557
|
DESTROY(delete, retryq);
|
|
483
|
-
DESTROY(
|
|
484
|
-
DESTROY(
|
|
485
|
-
DESTROY(
|
|
558
|
+
DESTROY(delete, confmon);
|
|
559
|
+
DESTROY(do_pool_shutdown, memd_sockpool);
|
|
560
|
+
DESTROY(do_pool_shutdown, http_sockpool);
|
|
486
561
|
DESTROY(lcb_vbguess_destroy, vbguess);
|
|
487
562
|
DESTROY(lcb_n1qlcache_destroy, n1ql_cache);
|
|
488
563
|
|
|
@@ -534,10 +609,23 @@ lcb_destroy_async(lcb_t instance, const void *arg)
|
|
|
534
609
|
lcbio_async_signal(instance->dtor_timer);
|
|
535
610
|
}
|
|
536
611
|
|
|
612
|
+
lcb::Server *
|
|
613
|
+
lcb_st::find_server(const lcb_host_t& host) const
|
|
614
|
+
{
|
|
615
|
+
unsigned ii;
|
|
616
|
+
for (ii = 0; ii < cmdq.npipelines; ii++) {
|
|
617
|
+
lcb::Server *server = static_cast<lcb::Server*>(cmdq.pipelines[ii]);
|
|
618
|
+
if (lcb_host_equals(&server->get_host(), &host)) {
|
|
619
|
+
return server;
|
|
620
|
+
}
|
|
621
|
+
}
|
|
622
|
+
return NULL;
|
|
623
|
+
}
|
|
624
|
+
|
|
537
625
|
LIBCOUCHBASE_API
|
|
538
626
|
lcb_error_t lcb_connect(lcb_t instance)
|
|
539
627
|
{
|
|
540
|
-
lcb_error_t err =
|
|
628
|
+
lcb_error_t err = instance->bootstrap(BS_REFRESH_INITIAL);
|
|
541
629
|
if (err == LCB_SUCCESS) {
|
|
542
630
|
SYNCMODE_INTERCEPT(instance);
|
|
543
631
|
} else {
|
|
@@ -718,6 +806,15 @@ const char *lcb_strerror(lcb_t instance, lcb_error_t error)
|
|
|
718
806
|
return "Unknown error";
|
|
719
807
|
}
|
|
720
808
|
|
|
809
|
+
LCB_INTERNAL_API
|
|
810
|
+
const char *lcb_strerror_short(lcb_error_t error)
|
|
811
|
+
{
|
|
812
|
+
#define X(c, v, t, s) if (error == c) { return #c " (" #v ")"; }
|
|
813
|
+
LCB_XERR(X)
|
|
814
|
+
#undef X
|
|
815
|
+
return "<FIXME: Not an LCB error>";
|
|
816
|
+
}
|
|
817
|
+
|
|
721
818
|
LIBCOUCHBASE_API
|
|
722
819
|
int lcb_get_errtype(lcb_error_t err)
|
|
723
820
|
{
|