libcouchbase 0.2.0 → 0.3.1
Sign up to get free protection for your applications and to get access to all the features.
- 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();
|