libcouchbase 0.2.0 → 0.3.1
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/.travis.yml +1 -1
- data/README.md +1 -1
- data/ext/libcouchbase/CMakeLists.txt +8 -6
- data/ext/libcouchbase/README.markdown +2 -2
- data/ext/libcouchbase/RELEASE_NOTES.markdown +0 -86
- data/ext/libcouchbase/cmake/Modules/ConfigureDtrace.cmake +0 -11
- data/ext/libcouchbase/cmake/Modules/GenerateConfigDotH.cmake +0 -2
- data/ext/libcouchbase/cmake/Modules/GetLibcouchbaseFlags.cmake +1 -2
- data/ext/libcouchbase/cmake/Modules/GetVersionInfo.cmake +3 -3
- data/ext/libcouchbase/cmake/config-cmake.h.in +0 -2
- data/ext/libcouchbase/cmake/defs.mk.in +2 -0
- data/ext/libcouchbase/cmake/source_files.cmake +5 -21
- data/ext/libcouchbase/include/libcouchbase/auth.h +0 -10
- data/ext/libcouchbase/include/libcouchbase/cntl.h +1 -27
- data/ext/libcouchbase/include/libcouchbase/error.h +1 -15
- data/ext/libcouchbase/include/libcouchbase/n1ql.h +1 -13
- data/ext/libcouchbase/include/libcouchbase/plugins/io/bsdio-inl.c +1 -1
- data/ext/libcouchbase/include/libcouchbase/subdoc.h +0 -9
- data/ext/libcouchbase/include/libcouchbase/views.h +1 -7
- data/ext/libcouchbase/include/libcouchbase/visibility.h +0 -1
- data/ext/libcouchbase/include/memcached/protocol_binary.h +1131 -29
- data/ext/libcouchbase/include/memcached/vbucket.h +42 -0
- data/ext/libcouchbase/packaging/parse-git-describe.pl +1 -1
- data/ext/libcouchbase/plugins/io/libev/libev_io_opts.h +2 -3
- data/ext/libcouchbase/src/README.md +2 -0
- data/ext/libcouchbase/src/auth-priv.h +0 -1
- data/ext/libcouchbase/src/auth.cc +4 -10
- data/ext/libcouchbase/src/bootstrap.c +269 -0
- data/ext/libcouchbase/src/bootstrap.h +39 -50
- data/ext/libcouchbase/src/bucketconfig/bc_cccp.cc +117 -84
- data/ext/libcouchbase/src/bucketconfig/bc_file.c +347 -0
- data/ext/libcouchbase/src/bucketconfig/bc_http.c +630 -0
- data/ext/libcouchbase/src/bucketconfig/bc_http.h +25 -50
- data/ext/libcouchbase/src/bucketconfig/bc_mcraw.c +150 -0
- data/ext/libcouchbase/src/bucketconfig/clconfig.h +386 -407
- data/ext/libcouchbase/src/bucketconfig/confmon.c +474 -0
- data/ext/libcouchbase/src/cbft.cc +27 -22
- data/ext/libcouchbase/src/cntl.cc +19 -30
- data/ext/libcouchbase/src/connspec.cc +1 -48
- data/ext/libcouchbase/src/connspec.h +0 -27
- data/ext/libcouchbase/src/dump.cc +2 -2
- data/ext/libcouchbase/src/getconfig.cc +33 -7
- data/ext/libcouchbase/src/handler.cc +2 -0
- data/ext/libcouchbase/src/hostlist.cc +36 -0
- data/ext/libcouchbase/src/hostlist.h +62 -41
- data/ext/libcouchbase/src/http/http-priv.h +112 -125
- data/ext/libcouchbase/src/http/http.cc +30 -15
- data/ext/libcouchbase/src/http/http.h +34 -1
- data/ext/libcouchbase/src/http/http_io.cc +26 -22
- data/ext/libcouchbase/src/instance.cc +23 -94
- data/ext/libcouchbase/src/internal.h +26 -52
- data/ext/libcouchbase/src/jsparse/parser.cc +202 -146
- data/ext/libcouchbase/src/jsparse/parser.h +98 -91
- data/ext/libcouchbase/src/lcbht/lcbht.c +282 -0
- data/ext/libcouchbase/src/lcbht/lcbht.h +163 -174
- data/ext/libcouchbase/src/lcbio/connect.c +557 -0
- data/ext/libcouchbase/src/lcbio/connect.h +2 -9
- data/ext/libcouchbase/src/lcbio/ctx.c +1 -1
- data/ext/libcouchbase/src/lcbio/iotable.h +16 -61
- data/ext/libcouchbase/src/lcbio/ioutils.h +1 -1
- data/ext/libcouchbase/src/lcbio/manager.c +2 -2
- data/ext/libcouchbase/src/mc/mcreq.h +2 -9
- data/ext/libcouchbase/src/mcserver/mcserver.cc +34 -143
- data/ext/libcouchbase/src/mcserver/mcserver.h +12 -7
- data/ext/libcouchbase/src/mcserver/negotiate.cc +38 -132
- data/ext/libcouchbase/src/n1ql/ixmgmt.cc +2 -1
- data/ext/libcouchbase/src/n1ql/n1ql.cc +32 -56
- data/ext/libcouchbase/src/newconfig.cc +6 -6
- data/ext/libcouchbase/src/nodeinfo.cc +2 -2
- data/ext/libcouchbase/src/operations/{cbflush.cc → cbflush.c} +15 -7
- data/ext/libcouchbase/src/operations/{counter.cc → counter.c} +0 -0
- data/ext/libcouchbase/src/operations/durability.cc +26 -6
- data/ext/libcouchbase/src/operations/durability_internal.h +3 -6
- data/ext/libcouchbase/src/operations/{get.cc → get.c} +26 -24
- data/ext/libcouchbase/src/operations/{observe.cc → observe.c} +93 -68
- data/ext/libcouchbase/src/operations/{pktfwd.cc → pktfwd.c} +0 -0
- data/ext/libcouchbase/src/operations/{remove.cc → remove.c} +0 -0
- data/ext/libcouchbase/src/operations/stats.cc +8 -3
- data/ext/libcouchbase/src/operations/{store.cc → store.c} +32 -27
- data/ext/libcouchbase/src/operations/subdoc.cc +18 -38
- data/ext/libcouchbase/src/operations/{touch.cc → touch.c} +0 -0
- data/ext/libcouchbase/src/packetutils.c +37 -0
- data/ext/libcouchbase/src/packetutils.h +2 -2
- data/ext/libcouchbase/src/probes.d +1 -1
- data/ext/libcouchbase/src/{retrychk.cc → retrychk.c} +3 -2
- data/ext/libcouchbase/src/retryq.cc +4 -4
- data/ext/libcouchbase/src/settings.c +0 -3
- data/ext/libcouchbase/src/settings.h +0 -5
- data/ext/libcouchbase/src/simplestring.c +211 -0
- data/ext/libcouchbase/src/simplestring.h +228 -0
- data/ext/libcouchbase/src/ssl/ssl_c.c +0 -1
- data/ext/libcouchbase/src/ssl/ssl_common.c +0 -2
- data/ext/libcouchbase/src/ssl/ssl_e.c +1 -0
- data/ext/libcouchbase/src/ssobuf.h +82 -0
- data/ext/libcouchbase/src/trace.h +4 -4
- data/ext/libcouchbase/src/vbucket/vbucket.c +1 -0
- data/ext/libcouchbase/src/views/{docreq.cc → docreq.c} +54 -48
- data/ext/libcouchbase/src/views/docreq.h +30 -24
- data/ext/libcouchbase/src/views/viewreq.c +358 -0
- data/ext/libcouchbase/src/views/viewreq.h +13 -43
- data/ext/libcouchbase/tests/basic/t_connstr.cc +50 -89
- data/ext/libcouchbase/tests/basic/t_host.cc +75 -67
- data/ext/libcouchbase/tests/basic/t_jsparse.cc +78 -27
- data/ext/libcouchbase/tests/basic/t_string.cc +112 -0
- data/ext/libcouchbase/tests/htparse/t_basic.cc +78 -58
- data/ext/libcouchbase/tests/iotests/mock-environment.h +1 -2
- data/ext/libcouchbase/tests/iotests/t_confmon.cc +114 -96
- data/ext/libcouchbase/tests/mc/t_alloc.cc +9 -9
- data/ext/libcouchbase/tools/cbc-pillowfight.cc +1 -1
- data/lib/libcouchbase/ext/tasks.rb +6 -2
- data/lib/libcouchbase/query_view.rb +1 -1
- data/lib/libcouchbase/results_fiber.rb +6 -6
- data/lib/libcouchbase/version.rb +1 -1
- metadata +26 -26
- data/ext/libcouchbase/src/bootstrap.cc +0 -216
- data/ext/libcouchbase/src/bucketconfig/bc_file.cc +0 -281
- data/ext/libcouchbase/src/bucketconfig/bc_http.cc +0 -528
- data/ext/libcouchbase/src/bucketconfig/bc_mcraw.cc +0 -115
- data/ext/libcouchbase/src/bucketconfig/confmon.cc +0 -378
- data/ext/libcouchbase/src/dns-srv.cc +0 -142
- data/ext/libcouchbase/src/errmap.cc +0 -107
- data/ext/libcouchbase/src/errmap.h +0 -113
- data/ext/libcouchbase/src/lcbht/lcbht.cc +0 -177
- data/ext/libcouchbase/src/lcbio/connect.cc +0 -562
- data/ext/libcouchbase/src/lcbio/timer-cxx.h +0 -87
- data/ext/libcouchbase/src/mctx-helper.h +0 -51
- data/ext/libcouchbase/src/views/viewreq.cc +0 -318
- data/ext/libcouchbase/tests/iotests/t_errmap.cc +0 -97
|
@@ -24,6 +24,9 @@
|
|
|
24
24
|
#include <netbuf/netbuf.h>
|
|
25
25
|
|
|
26
26
|
#ifdef __cplusplus
|
|
27
|
+
struct lcb_settings_st;
|
|
28
|
+
struct lcb_server_st;
|
|
29
|
+
|
|
27
30
|
namespace lcb {
|
|
28
31
|
|
|
29
32
|
class RetryQueue;
|
|
@@ -106,10 +109,6 @@ public:
|
|
|
106
109
|
return mutation_tokens;
|
|
107
110
|
}
|
|
108
111
|
|
|
109
|
-
bool supports_compression() const {
|
|
110
|
-
return compsupport;
|
|
111
|
-
}
|
|
112
|
-
|
|
113
112
|
bool is_connected() const {
|
|
114
113
|
return connctx != NULL;
|
|
115
114
|
}
|
|
@@ -173,12 +172,10 @@ public:
|
|
|
173
172
|
|
|
174
173
|
enum ReadState {
|
|
175
174
|
PKT_READ_COMPLETE,
|
|
176
|
-
PKT_READ_PARTIAL
|
|
177
|
-
PKT_READ_ABORT
|
|
175
|
+
PKT_READ_PARTIAL
|
|
178
176
|
};
|
|
179
177
|
|
|
180
178
|
ReadState try_read(lcbio_CTX *ctx, rdb_IOROPE *ior);
|
|
181
|
-
bool handle_unknown_error(const MemcachedResponse& resinfo, lcb_error_t& newerr);
|
|
182
179
|
bool handle_nmv(MemcachedResponse& resinfo, mc_PACKET *oldpkt);
|
|
183
180
|
bool maybe_retry_packet(mc_PACKET *pkt, lcb_error_t err);
|
|
184
181
|
bool maybe_reconnect_on_fake_timeout(lcb_error_t received_error);
|
|
@@ -209,5 +206,13 @@ public:
|
|
|
209
206
|
lcb_host_t *curhost;
|
|
210
207
|
};
|
|
211
208
|
}
|
|
209
|
+
|
|
210
|
+
typedef lcb::Server mc_SERVER;
|
|
211
|
+
extern "C" {int mcserver_supports_compression(mc_SERVER*);}
|
|
212
|
+
|
|
213
|
+
#else
|
|
214
|
+
/* C only */
|
|
215
|
+
typedef struct mc_SERVER mc_SERVER;
|
|
216
|
+
int mcserver_supports_compression(mc_SERVER *server);
|
|
212
217
|
#endif /* __cplusplus */
|
|
213
218
|
#endif /* LCB_MCSERVER_H */
|
|
@@ -16,10 +16,6 @@
|
|
|
16
16
|
*/
|
|
17
17
|
|
|
18
18
|
#include <algorithm>
|
|
19
|
-
#include <string>
|
|
20
|
-
#include <sstream>
|
|
21
|
-
#include <vector>
|
|
22
|
-
|
|
23
19
|
#include "packetutils.h"
|
|
24
20
|
#include "mcserver.h"
|
|
25
21
|
#include "logging.h"
|
|
@@ -30,7 +26,6 @@
|
|
|
30
26
|
#include <cbsasl/cbsasl.h>
|
|
31
27
|
#include "negotiate.h"
|
|
32
28
|
#include "ctx-log-inl.h"
|
|
33
|
-
#include "auth-priv.h"
|
|
34
29
|
|
|
35
30
|
using namespace lcb;
|
|
36
31
|
|
|
@@ -39,7 +34,6 @@ static void cleanup_negotiated(SessionInfo* info);
|
|
|
39
34
|
static void handle_ioerr(lcbio_CTX *ctx, lcb_error_t err);
|
|
40
35
|
#define SESSREQ_LOGFMT "<%s:%s> (SASLREQ=%p) "
|
|
41
36
|
|
|
42
|
-
|
|
43
37
|
static void timeout_handler(void *arg);
|
|
44
38
|
|
|
45
39
|
#define SESSREQ_LOGID(s) get_ctx_host(s->ctx), get_ctx_port(s->ctx), (void*)s
|
|
@@ -71,12 +65,9 @@ public:
|
|
|
71
65
|
bool read_hello(const lcb::MemcachedResponse& packet);
|
|
72
66
|
void send_auth(const char *sasl_data, unsigned ndata);
|
|
73
67
|
void handle_read(lcbio_CTX *ioctx);
|
|
74
|
-
bool maybe_select_bucket();
|
|
75
68
|
|
|
76
69
|
enum MechStatus { MECH_UNAVAILABLE, MECH_NOT_NEEDED, MECH_OK };
|
|
77
70
|
MechStatus set_chosen_mech(std::string& mechlist, const char **data, unsigned int *ndata);
|
|
78
|
-
bool request_errmap();
|
|
79
|
-
bool update_errmap(const lcb::MemcachedResponse& packet);
|
|
80
71
|
|
|
81
72
|
SessionRequestImpl(lcbio_CONNDONE_cb callback, void *data, uint32_t timeout, lcbio_TABLE *iot, lcb_settings* settings_)
|
|
82
73
|
: ctx(NULL), cb(callback), cbdata(data),
|
|
@@ -332,11 +323,6 @@ SessionRequestImpl::send_hello()
|
|
|
332
323
|
|
|
333
324
|
unsigned nfeatures = 0;
|
|
334
325
|
features[nfeatures++] = PROTOCOL_BINARY_FEATURE_TLS;
|
|
335
|
-
features[nfeatures++] = PROTOCOL_BINARY_FEATURE_XATTR;
|
|
336
|
-
features[nfeatures++] = PROTOCOL_BINARY_FEATURE_SELECT_BUCKET;
|
|
337
|
-
if (settings->use_errmap) {
|
|
338
|
-
features[nfeatures++] = PROTOCOL_BINARY_FEATURE_XERROR;
|
|
339
|
-
}
|
|
340
326
|
if (settings->tcp_nodelay) {
|
|
341
327
|
features[nfeatures++] = PROTOCOL_BINARY_FEATURE_TCPNODELAY;
|
|
342
328
|
}
|
|
@@ -373,7 +359,6 @@ SessionRequestImpl::send_hello()
|
|
|
373
359
|
lcb_U16 tmp = htons(features[ii]);
|
|
374
360
|
lcbio_ctx_put(ctx, &tmp, sizeof tmp);
|
|
375
361
|
}
|
|
376
|
-
|
|
377
362
|
lcbio_ctx_rwant(ctx, 24);
|
|
378
363
|
return true;
|
|
379
364
|
}
|
|
@@ -389,74 +374,18 @@ SessionRequestImpl::read_hello(const lcb::MemcachedResponse& resp)
|
|
|
389
374
|
lcb_U16 tmp;
|
|
390
375
|
memcpy(&tmp, cur, sizeof(tmp));
|
|
391
376
|
tmp = ntohs(tmp);
|
|
392
|
-
lcb_log(LOGARGS(this, DEBUG), SESSREQ_LOGFMT "
|
|
377
|
+
lcb_log(LOGARGS(this, DEBUG), SESSREQ_LOGFMT "Found feature 0x%x (%s)", SESSREQ_LOGID(this), tmp, protocol_feature_2_text(tmp));
|
|
393
378
|
info->server_features.push_back(tmp);
|
|
394
379
|
}
|
|
395
380
|
return true;
|
|
396
381
|
}
|
|
397
382
|
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
lcbio_ctx_put(ctx, hdr.data(), hdr.size());
|
|
406
|
-
lcbio_ctx_put(ctx, p, 2);
|
|
407
|
-
lcbio_ctx_rwant(ctx, 24);
|
|
408
|
-
return true;
|
|
409
|
-
}
|
|
410
|
-
|
|
411
|
-
bool
|
|
412
|
-
SessionRequestImpl::update_errmap(const lcb::MemcachedResponse& resp)
|
|
413
|
-
{
|
|
414
|
-
// Get the error map object
|
|
415
|
-
using lcb::errmap::ErrorMap;
|
|
416
|
-
|
|
417
|
-
std::string errmsg;
|
|
418
|
-
ErrorMap& mm = *settings->errmap;
|
|
419
|
-
ErrorMap::ParseStatus status = mm.parse(
|
|
420
|
-
resp.body<const char*>(), resp.bodylen(), errmsg);
|
|
421
|
-
|
|
422
|
-
if (status != ErrorMap::UPDATED && status != ErrorMap::NOT_UPDATED) {
|
|
423
|
-
errmsg = "Couldn't update error map: " + errmsg;
|
|
424
|
-
set_error(LCB_PROTOCOL_ERROR, errmsg.c_str());
|
|
425
|
-
return false;
|
|
426
|
-
}
|
|
427
|
-
|
|
428
|
-
return true;
|
|
429
|
-
}
|
|
430
|
-
|
|
431
|
-
// Returns true if sending the SELECT_BUCKET command, false otherwise.
|
|
432
|
-
bool
|
|
433
|
-
SessionRequestImpl::maybe_select_bucket() {
|
|
434
|
-
|
|
435
|
-
// Only send a SELECT_BUCKET if we have the SELECT_BUCKET bit enabled.
|
|
436
|
-
if (!info->has_feature(PROTOCOL_BINARY_FEATURE_SELECT_BUCKET)) {
|
|
437
|
-
return false;
|
|
438
|
-
}
|
|
439
|
-
|
|
440
|
-
if (!settings->select_bucket) {
|
|
441
|
-
lcb_log(LOGARGS(this, WARN), SESSREQ_LOGFMT "SELECT_BUCKET Disabled by application", SESSREQ_LOGID(this));
|
|
442
|
-
return false;
|
|
443
|
-
}
|
|
444
|
-
|
|
445
|
-
// send the SELECT_BUCKET command:
|
|
446
|
-
lcb_log(LOGARGS(this, INFO), SESSREQ_LOGFMT "Sending SELECT_BUCKET", SESSREQ_LOGID(this));
|
|
447
|
-
lcb::MemcachedRequest req(PROTOCOL_BINARY_CMD_SELECT_BUCKET);
|
|
448
|
-
req.sizes(0, strlen(settings->bucket), 0);
|
|
449
|
-
lcbio_ctx_put(ctx, req.data(), req.size());
|
|
450
|
-
lcbio_ctx_put(ctx, settings->bucket, strlen(settings->bucket));
|
|
451
|
-
LCBIO_CTX_RSCHEDULE(ctx, 24);
|
|
452
|
-
return true;
|
|
453
|
-
}
|
|
454
|
-
|
|
455
|
-
static bool isUnsupported(uint16_t status) {
|
|
456
|
-
return status == PROTOCOL_BINARY_RESPONSE_NOT_SUPPORTED ||
|
|
457
|
-
status == PROTOCOL_BINARY_RESPONSE_UNKNOWN_COMMAND ||
|
|
458
|
-
status == PROTOCOL_BINARY_RESPONSE_EACCESS;
|
|
459
|
-
}
|
|
383
|
+
typedef enum {
|
|
384
|
+
SREQ_S_WAIT,
|
|
385
|
+
SREQ_S_AUTHDONE,
|
|
386
|
+
SREQ_S_HELLODONE,
|
|
387
|
+
SREQ_S_ERROR
|
|
388
|
+
} sreq_STATE;
|
|
460
389
|
|
|
461
390
|
/**
|
|
462
391
|
* It's assumed the server buffers will be reset upon close(), so we must make
|
|
@@ -467,7 +396,7 @@ SessionRequestImpl::handle_read(lcbio_CTX *ioctx)
|
|
|
467
396
|
{
|
|
468
397
|
lcb::MemcachedResponse resp;
|
|
469
398
|
unsigned required;
|
|
470
|
-
|
|
399
|
+
sreq_STATE state = SREQ_S_WAIT;
|
|
471
400
|
|
|
472
401
|
GT_NEXT_PACKET:
|
|
473
402
|
|
|
@@ -486,92 +415,66 @@ SessionRequestImpl::handle_read(lcbio_CTX *ioctx)
|
|
|
486
415
|
MechStatus mechrc = set_chosen_mech(mechs, &mechlist_data, &nmechlist_data);
|
|
487
416
|
if (mechrc == MECH_OK) {
|
|
488
417
|
send_auth(mechlist_data, nmechlist_data);
|
|
418
|
+
state = SREQ_S_WAIT;
|
|
489
419
|
} else if (mechrc == MECH_UNAVAILABLE) {
|
|
490
|
-
|
|
420
|
+
state = SREQ_S_ERROR;
|
|
491
421
|
} else {
|
|
492
|
-
|
|
422
|
+
state = SREQ_S_HELLODONE;
|
|
493
423
|
}
|
|
494
424
|
break;
|
|
495
425
|
}
|
|
496
426
|
|
|
497
427
|
case PROTOCOL_BINARY_CMD_SASL_AUTH: {
|
|
498
428
|
if (status == PROTOCOL_BINARY_RESPONSE_SUCCESS) {
|
|
499
|
-
|
|
429
|
+
send_hello();
|
|
430
|
+
state = SREQ_S_AUTHDONE;
|
|
500
431
|
break;
|
|
501
|
-
}
|
|
502
|
-
|
|
503
|
-
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
if (status != PROTOCOL_BINARY_RESPONSE_AUTH_CONTINUE) {
|
|
504
435
|
set_error(LCB_AUTH_ERROR, "SASL AUTH failed");
|
|
436
|
+
state = SREQ_S_ERROR;
|
|
505
437
|
break;
|
|
506
438
|
}
|
|
439
|
+
if (send_step(resp) && send_hello()) {
|
|
440
|
+
state = SREQ_S_WAIT;
|
|
441
|
+
} else {
|
|
442
|
+
state = SREQ_S_ERROR;
|
|
443
|
+
}
|
|
507
444
|
break;
|
|
508
445
|
}
|
|
509
446
|
|
|
510
447
|
case PROTOCOL_BINARY_CMD_SASL_STEP: {
|
|
511
|
-
if (status
|
|
512
|
-
completed = !maybe_select_bucket();
|
|
513
|
-
} else {
|
|
448
|
+
if (status != PROTOCOL_BINARY_RESPONSE_SUCCESS) {
|
|
514
449
|
lcb_log(LOGARGS(this, WARN), SESSREQ_LOGFMT "SASL auth failed with STATUS=0x%x", SESSREQ_LOGID(this), status);
|
|
515
450
|
set_error(LCB_AUTH_ERROR, "SASL Step Failed");
|
|
451
|
+
state = SREQ_S_ERROR;
|
|
452
|
+
} else {
|
|
453
|
+
/* Wait for pipelined HELLO response */
|
|
454
|
+
state = SREQ_S_AUTHDONE;
|
|
516
455
|
}
|
|
517
456
|
break;
|
|
518
457
|
}
|
|
519
458
|
|
|
520
459
|
case PROTOCOL_BINARY_CMD_HELLO: {
|
|
460
|
+
state = SREQ_S_HELLODONE;
|
|
521
461
|
if (status == PROTOCOL_BINARY_RESPONSE_SUCCESS) {
|
|
522
462
|
if (!read_hello(resp)) {
|
|
523
463
|
set_error(LCB_PROTOCOL_ERROR, "Couldn't parse HELLO");
|
|
524
|
-
break;
|
|
525
464
|
}
|
|
526
|
-
} else if (
|
|
465
|
+
} else if (status == PROTOCOL_BINARY_RESPONSE_UNKNOWN_COMMAND ||
|
|
466
|
+
status == PROTOCOL_BINARY_RESPONSE_NOT_SUPPORTED) {
|
|
527
467
|
lcb_log(LOGARGS(this, DEBUG), SESSREQ_LOGFMT "Server does not support HELLO", SESSREQ_LOGID(this));
|
|
468
|
+
/* nothing */
|
|
528
469
|
} else {
|
|
529
470
|
set_error(LCB_PROTOCOL_ERROR, "Hello response unexpected");
|
|
530
|
-
|
|
531
|
-
}
|
|
532
|
-
|
|
533
|
-
if (info->has_feature(PROTOCOL_BINARY_FEATURE_XERROR)) {
|
|
534
|
-
request_errmap();
|
|
535
|
-
} else {
|
|
536
|
-
lcb_log(LOGARGS(this, TRACE), SESSREQ_LOGFMT "GET_ERRORMAP unsupported/disabled", SESSREQ_LOGID(this));
|
|
537
|
-
}
|
|
538
|
-
|
|
539
|
-
// In any event, it's also time to send the LIST_MECHS request
|
|
540
|
-
lcb::MemcachedRequest req(PROTOCOL_BINARY_CMD_SASL_LIST_MECHS);
|
|
541
|
-
lcbio_ctx_put(ctx, req.data(), req.size());
|
|
542
|
-
LCBIO_CTX_RSCHEDULE(ctx, 24);
|
|
543
|
-
|
|
544
|
-
break;
|
|
545
|
-
}
|
|
546
|
-
|
|
547
|
-
case PROTOCOL_BINARY_CMD_GET_ERROR_MAP: {
|
|
548
|
-
if (status == PROTOCOL_BINARY_RESPONSE_SUCCESS) {
|
|
549
|
-
if (!update_errmap(resp)) {
|
|
550
|
-
}
|
|
551
|
-
} else if (isUnsupported(status)) {
|
|
552
|
-
lcb_log(LOGARGS(this, DEBUG), SESSREQ_LOGFMT "Server does not support GET_ERRMAP (0x%x)", SESSREQ_LOGID(this), status);
|
|
553
|
-
} else {
|
|
554
|
-
lcb_log(LOGARGS(this, ERROR), SESSREQ_LOGFMT "Unexpected status 0x%x received for GET_ERRMAP", SESSREQ_LOGID(this), status);
|
|
555
|
-
set_error(LCB_PROTOCOL_ERROR, "GET_ERRMAP response unexpected");
|
|
556
|
-
}
|
|
557
|
-
// Note, there is no explicit state transition here. LIST_MECHS is
|
|
558
|
-
// pipelined after this request.
|
|
559
|
-
break;
|
|
560
|
-
}
|
|
561
|
-
|
|
562
|
-
case PROTOCOL_BINARY_CMD_SELECT_BUCKET: {
|
|
563
|
-
if (status == PROTOCOL_BINARY_RESPONSE_SUCCESS) {
|
|
564
|
-
completed = true;
|
|
565
|
-
} else if (status == PROTOCOL_BINARY_RESPONSE_EACCESS) {
|
|
566
|
-
set_error(LCB_AUTH_ERROR, "Provided credentials not allowed for bucket");
|
|
567
|
-
} else {
|
|
568
|
-
lcb_log(LOGARGS(this, ERROR), SESSREQ_LOGFMT "Unexpected status 0x%x received for SELECT_BUCKET", SESSREQ_LOGID(this), status);
|
|
569
|
-
set_error(LCB_PROTOCOL_ERROR, "Other auth error");
|
|
471
|
+
state = SREQ_S_ERROR;
|
|
570
472
|
}
|
|
571
473
|
break;
|
|
572
474
|
}
|
|
573
475
|
|
|
574
476
|
default: {
|
|
477
|
+
state = SREQ_S_ERROR;
|
|
575
478
|
lcb_log(LOGARGS(this, ERROR), SESSREQ_LOGFMT "Received unknown response. OP=0x%x. RC=0x%x", SESSREQ_LOGID(this), resp.opcode(), resp.status());
|
|
576
479
|
set_error(LCB_NOT_SUPPORTED, "Received unknown response");
|
|
577
480
|
break;
|
|
@@ -586,7 +489,9 @@ SessionRequestImpl::handle_read(lcbio_CTX *ioctx)
|
|
|
586
489
|
// or fail the request, potentially destroying the underlying connection
|
|
587
490
|
if (has_error()) {
|
|
588
491
|
fail();
|
|
589
|
-
} else if (
|
|
492
|
+
} else if (state == SREQ_S_ERROR) {
|
|
493
|
+
fail(LCB_ERROR, "FIXME: Error code set without description");
|
|
494
|
+
} else if (state == SREQ_S_HELLODONE) {
|
|
590
495
|
success();
|
|
591
496
|
} else {
|
|
592
497
|
goto GT_NEXT_PACKET;
|
|
@@ -631,7 +536,8 @@ SessionRequestImpl::start(lcbio_SOCKET *sock) {
|
|
|
631
536
|
return;
|
|
632
537
|
}
|
|
633
538
|
|
|
634
|
-
|
|
539
|
+
lcb::MemcachedRequest hdr(PROTOCOL_BINARY_CMD_SASL_LIST_MECHS);
|
|
540
|
+
lcbio_ctx_put(ctx, hdr.data(), hdr.size());
|
|
635
541
|
LCBIO_CTX_RSCHEDULE(ctx, 24);
|
|
636
542
|
}
|
|
637
543
|
|
|
@@ -210,7 +210,8 @@ dispatch_common(lcb_t instance,
|
|
|
210
210
|
// mind-numbing buffer copies. Maybe this can be done via a macro instead?
|
|
211
211
|
class IndexSpec : public lcb_N1XSPEC {
|
|
212
212
|
public:
|
|
213
|
-
IndexSpec(const char *s, size_t n)
|
|
213
|
+
IndexSpec(const char *s, size_t n) {
|
|
214
|
+
memset(static_cast<lcb_N1XSPEC*>(this), 0, sizeof (lcb_N1XSPEC));
|
|
214
215
|
load_json(s, n);
|
|
215
216
|
}
|
|
216
217
|
inline IndexSpec(const lcb_N1XSPEC *spec);
|
|
@@ -142,10 +142,10 @@ struct lcb_N1QLCACHE_st {
|
|
|
142
142
|
}
|
|
143
143
|
};
|
|
144
144
|
|
|
145
|
-
typedef struct lcb_N1QLREQ
|
|
145
|
+
typedef struct lcb_N1QLREQ {
|
|
146
146
|
const lcb_RESPHTTP *cur_htresp;
|
|
147
147
|
struct lcb_http_request_st *htreq;
|
|
148
|
-
|
|
148
|
+
lcbjsp_PARSER *parser;
|
|
149
149
|
const void *cookie;
|
|
150
150
|
lcb_N1QLCALLBACK callback;
|
|
151
151
|
lcb_t instance;
|
|
@@ -155,9 +155,6 @@ typedef struct lcb_N1QLREQ : lcb::jsparse::Parser::Actions {
|
|
|
155
155
|
// How many rows were received. Used to avoid parsing the meta
|
|
156
156
|
size_t nrows;
|
|
157
157
|
|
|
158
|
-
// Host for CBAS/Analytics query
|
|
159
|
-
std::string cbashost;
|
|
160
|
-
|
|
161
158
|
/** The PREPARE query itself */
|
|
162
159
|
struct lcb_N1QLREQ *prepare_req;
|
|
163
160
|
|
|
@@ -230,28 +227,9 @@ typedef struct lcb_N1QLREQ : lcb::jsparse::Parser::Actions {
|
|
|
230
227
|
*/
|
|
231
228
|
inline void fail_prepared(const lcb_RESPN1QL *orig, lcb_error_t err);
|
|
232
229
|
|
|
233
|
-
bool is_cbas() const {
|
|
234
|
-
return !cbashost.empty();
|
|
235
|
-
}
|
|
236
|
-
|
|
237
230
|
inline lcb_N1QLREQ(lcb_t obj, const void *user_cookie, const lcb_CMDN1QL *cmd);
|
|
238
231
|
inline ~lcb_N1QLREQ();
|
|
239
232
|
|
|
240
|
-
// Parser overrides:
|
|
241
|
-
void JSPARSE_on_row(const lcb::jsparse::Row& row) {
|
|
242
|
-
lcb_RESPN1QL resp = { 0 };
|
|
243
|
-
resp.row = static_cast<const char *>(row.row.iov_base);
|
|
244
|
-
resp.nrow = row.row.iov_len;
|
|
245
|
-
nrows++;
|
|
246
|
-
invoke_row(&resp, false);
|
|
247
|
-
}
|
|
248
|
-
void JSPARSE_on_error(const std::string&) {
|
|
249
|
-
lasterr = LCB_PROTOCOL_ERROR;
|
|
250
|
-
}
|
|
251
|
-
void JSPARSE_on_complete(const std::string&) {
|
|
252
|
-
// Nothing
|
|
253
|
-
}
|
|
254
|
-
|
|
255
233
|
} N1QLREQ;
|
|
256
234
|
|
|
257
235
|
static bool
|
|
@@ -352,7 +330,8 @@ N1QLREQ::maybe_retry()
|
|
|
352
330
|
}
|
|
353
331
|
|
|
354
332
|
was_retried = true;
|
|
355
|
-
|
|
333
|
+
|
|
334
|
+
lcbjsp_get_postmortem(parser, &meta);
|
|
356
335
|
if (!parse_json(static_cast<const char*>(meta.iov_base), meta.iov_len, root)) {
|
|
357
336
|
return false; // Not JSON
|
|
358
337
|
}
|
|
@@ -372,7 +351,7 @@ N1QLREQ::maybe_retry()
|
|
|
372
351
|
|
|
373
352
|
} else {
|
|
374
353
|
// We'll be parsing more rows later on..
|
|
375
|
-
parser
|
|
354
|
+
lcbjsp_reset(parser);
|
|
376
355
|
}
|
|
377
356
|
return true;
|
|
378
357
|
}
|
|
@@ -387,7 +366,7 @@ N1QLREQ::invoke_row(lcb_RESPN1QL *resp, bool is_last)
|
|
|
387
366
|
lcb_IOV meta;
|
|
388
367
|
resp->rflags |= LCB_RESP_F_FINAL;
|
|
389
368
|
resp->rc = lasterr;
|
|
390
|
-
parser
|
|
369
|
+
lcbjsp_get_postmortem(parser, &meta);
|
|
391
370
|
resp->row = static_cast<const char*>(meta.iov_base);
|
|
392
371
|
resp->nrow = meta.iov_len;
|
|
393
372
|
}
|
|
@@ -413,13 +392,31 @@ lcb_N1QLREQ::~lcb_N1QLREQ()
|
|
|
413
392
|
}
|
|
414
393
|
|
|
415
394
|
if (parser) {
|
|
416
|
-
|
|
395
|
+
lcbjsp_free(parser);
|
|
417
396
|
}
|
|
418
397
|
if (prepare_req) {
|
|
419
398
|
lcb_n1ql_cancel(instance, prepare_req);
|
|
420
399
|
}
|
|
421
400
|
}
|
|
422
401
|
|
|
402
|
+
static void
|
|
403
|
+
row_callback(lcbjsp_PARSER *parser, const lcbjsp_ROW *datum)
|
|
404
|
+
{
|
|
405
|
+
N1QLREQ *req = static_cast<N1QLREQ*>(parser->data);
|
|
406
|
+
lcb_RESPN1QL resp = { 0 };
|
|
407
|
+
|
|
408
|
+
if (datum->type == LCBJSP_TYPE_ROW) {
|
|
409
|
+
resp.row = static_cast<const char*>(datum->row.iov_base);
|
|
410
|
+
resp.nrow = datum->row.iov_len;
|
|
411
|
+
req->nrows++;
|
|
412
|
+
req->invoke_row(&resp, 0);
|
|
413
|
+
} else if (datum->type == LCBJSP_TYPE_ERROR) {
|
|
414
|
+
req->lasterr = resp.rc = LCB_PROTOCOL_ERROR;
|
|
415
|
+
} else if (datum->type == LCBJSP_TYPE_COMPLETE) {
|
|
416
|
+
/* Nothing */
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
|
|
423
420
|
static void
|
|
424
421
|
chunk_callback(lcb_t instance, int ign, const lcb_RESPBASE *rb)
|
|
425
422
|
{
|
|
@@ -447,7 +444,8 @@ chunk_callback(lcb_t instance, int ign, const lcb_RESPBASE *rb)
|
|
|
447
444
|
delete req;
|
|
448
445
|
return;
|
|
449
446
|
}
|
|
450
|
-
|
|
447
|
+
|
|
448
|
+
lcbjsp_feed(req->parser, static_cast<const char*>(rh->body), rh->nbody);
|
|
451
449
|
}
|
|
452
450
|
|
|
453
451
|
#define QUERY_PATH "/query/service"
|
|
@@ -514,14 +512,7 @@ N1QLREQ::issue_htreq(const std::string& body)
|
|
|
514
512
|
|
|
515
513
|
htcmd.content_type = "application/json";
|
|
516
514
|
htcmd.method = LCB_HTTP_METHOD_POST;
|
|
517
|
-
|
|
518
|
-
if (is_cbas()) {
|
|
519
|
-
htcmd.type = LCB_HTTP_TYPE_RAW;
|
|
520
|
-
htcmd.host = cbashost.c_str();
|
|
521
|
-
} else {
|
|
522
|
-
htcmd.type = LCB_HTTP_TYPE_N1QL;
|
|
523
|
-
}
|
|
524
|
-
|
|
515
|
+
htcmd.type = LCB_HTTP_TYPE_N1QL;
|
|
525
516
|
htcmd.cmdflags = LCB_CMDHTTP_F_STREAM|LCB_CMDHTTP_F_CASTMO;
|
|
526
517
|
if (flags & F_CMDN1QL_CREDSAUTH) {
|
|
527
518
|
htcmd.cmdflags |= LCB_CMDHTTP_F_NOUPASS;
|
|
@@ -531,7 +522,7 @@ N1QLREQ::issue_htreq(const std::string& body)
|
|
|
531
522
|
|
|
532
523
|
lcb_error_t rc = lcb_http3(instance, this, &htcmd);
|
|
533
524
|
if (rc == LCB_SUCCESS) {
|
|
534
|
-
htreq
|
|
525
|
+
lcb_htreq_setcb(htreq, chunk_callback);
|
|
535
526
|
}
|
|
536
527
|
return rc;
|
|
537
528
|
}
|
|
@@ -595,12 +586,13 @@ lcb_n1qlreq_parsetmo(const std::string& s)
|
|
|
595
586
|
|
|
596
587
|
lcb_N1QLREQ::lcb_N1QLREQ(lcb_t obj,
|
|
597
588
|
const void *user_cookie, const lcb_CMDN1QL *cmd)
|
|
598
|
-
: cur_htresp(NULL), htreq(NULL),
|
|
599
|
-
parser(new lcb::jsparse::Parser(lcb::jsparse::Parser::MODE_N1QL, this)),
|
|
589
|
+
: cur_htresp(NULL), htreq(NULL), parser(lcbjsp_create(LCBJSP_MODE_N1QL)),
|
|
600
590
|
cookie(user_cookie), callback(cmd->callback), instance(obj),
|
|
601
591
|
lasterr(LCB_SUCCESS), flags(cmd->cmdflags), timeout(0),
|
|
602
592
|
nrows(0), prepare_req(NULL), was_retried(false)
|
|
603
593
|
{
|
|
594
|
+
parser->data = this;
|
|
595
|
+
parser->callback = row_callback;
|
|
604
596
|
if (cmd->handle) {
|
|
605
597
|
*cmd->handle = this;
|
|
606
598
|
}
|
|
@@ -612,22 +604,6 @@ lcb_N1QLREQ::lcb_N1QLREQ(lcb_t obj,
|
|
|
612
604
|
return;
|
|
613
605
|
}
|
|
614
606
|
|
|
615
|
-
if (flags & LCB_CMDN1QL_F_CBASQUERY) {
|
|
616
|
-
if (!cmd->host) {
|
|
617
|
-
lasterr = LCB_EINVAL;
|
|
618
|
-
return;
|
|
619
|
-
}
|
|
620
|
-
cbashost.assign(cmd->host);
|
|
621
|
-
if (cbashost.empty()) {
|
|
622
|
-
lasterr = LCB_EINVAL;
|
|
623
|
-
return;
|
|
624
|
-
}
|
|
625
|
-
if (flags & LCB_CMDN1QL_F_PREPCACHE) {
|
|
626
|
-
lasterr = LCB_OPTIONS_CONFLICT;
|
|
627
|
-
return;
|
|
628
|
-
}
|
|
629
|
-
}
|
|
630
|
-
|
|
631
607
|
const Json::Value& j_statement = json_const()["statement"];
|
|
632
608
|
if (j_statement.isString()) {
|
|
633
609
|
statement = j_statement.asString();
|