couchbase 3.2.0 → 3.2.4
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.
- package/README.md +24 -18
- package/binding.gyp +88 -85
- package/deps/lcb/CMakeLists.txt +1 -1
- package/deps/lcb/CONTRIBUTING.md +1 -1
- package/deps/lcb/README.markdown +2 -2
- package/deps/lcb/RELEASE_NOTES.markdown +99 -14
- package/deps/lcb/cmake/Modules/GetVersionInfo.cmake +1 -1
- package/deps/lcb/contrib/cbsasl/src/scram-sha/scram_utils.cc +22 -26
- package/deps/lcb/contrib/lcb-jsoncpp/lcb-jsoncpp.cpp +20 -7
- package/deps/lcb/doc/Doxyfile +1 -1
- package/deps/lcb/example/CMakeLists.txt +4 -4
- package/deps/lcb/example/libuvdirect/main.c +39 -12
- package/deps/lcb/example/minimal/durability.cc +149 -0
- package/deps/lcb/example/minimal/query.c +11 -9
- package/deps/lcb/gyp_config/common/libcouchbase/configuration.h +3 -3
- package/deps/lcb/gyp_config/linux/arm64/config.h +243 -0
- package/deps/lcb/include/libcouchbase/couchbase.h +80 -5
- package/deps/lcb/include/libcouchbase/error.h +2 -0
- package/deps/lcb/include/libcouchbase/ixmgmt.h +15 -10
- package/deps/lcb/include/libcouchbase/tracing.h +2 -2
- package/deps/lcb/include/memcached/protocol_binary.h +21 -0
- package/deps/lcb/libcouchbase.gyp +347 -349
- package/deps/lcb/packaging/deb/control +1 -1
- package/deps/lcb/src/analytics/analytics_handle.cc +13 -5
- package/deps/lcb/src/analytics/analytics_handle.hh +29 -0
- package/deps/lcb/src/bootstrap.cc +6 -3
- package/deps/lcb/src/capi/cmd_analytics.cc +12 -1
- package/deps/lcb/src/capi/cmd_analytics.hh +30 -0
- package/deps/lcb/src/capi/cmd_counter.hh +23 -0
- package/deps/lcb/src/capi/cmd_exists.hh +24 -1
- package/deps/lcb/src/capi/cmd_get.hh +22 -0
- package/deps/lcb/src/capi/cmd_get_replica.hh +23 -0
- package/deps/lcb/src/capi/cmd_http.hh +7 -0
- package/deps/lcb/src/capi/cmd_query.cc +11 -1
- package/deps/lcb/src/capi/cmd_query.hh +31 -0
- package/deps/lcb/src/capi/cmd_remove.hh +23 -0
- package/deps/lcb/src/capi/cmd_search.cc +6 -0
- package/deps/lcb/src/capi/cmd_search.hh +23 -0
- package/deps/lcb/src/capi/cmd_store.hh +33 -21
- package/deps/lcb/src/capi/cmd_subdoc.hh +35 -0
- package/deps/lcb/src/capi/cmd_touch.hh +23 -0
- package/deps/lcb/src/capi/cmd_unlock.hh +23 -0
- package/deps/lcb/src/capi/cmd_view.hh +6 -0
- package/deps/lcb/src/capi/collection_qualifier.hh +2 -2
- package/deps/lcb/src/cntl.cc +45 -11
- package/deps/lcb/src/crypto.cc +2 -2
- package/deps/lcb/src/dns-srv.cc +5 -3
- package/deps/lcb/src/errmap.cc +5 -9
- package/deps/lcb/src/errmap.h +7 -3
- package/deps/lcb/src/handler.cc +24 -18
- package/deps/lcb/src/hostlist.h +2 -2
- package/deps/lcb/src/http/http-priv.h +2 -2
- package/deps/lcb/src/http/http.cc +5 -2
- package/deps/lcb/src/instance.cc +20 -11
- package/deps/lcb/src/internal.h +9 -0
- package/deps/lcb/src/lcbio/connect.cc +14 -2
- package/deps/lcb/src/lcbio/connect.h +2 -2
- package/deps/lcb/src/lcbio/ctx.cc +4 -2
- package/deps/lcb/src/lcbio/ioutils.cc +9 -10
- package/deps/lcb/src/lcbio/manager.cc +1 -1
- package/deps/lcb/src/mcserver/mcserver.cc +9 -6
- package/deps/lcb/src/mcserver/negotiate.cc +39 -17
- package/deps/lcb/src/n1ql/ixmgmt.cc +1 -2
- package/deps/lcb/src/n1ql/query_handle.cc +41 -19
- package/deps/lcb/src/n1ql/query_handle.hh +28 -1
- package/deps/lcb/src/operations/counter.cc +18 -5
- package/deps/lcb/src/operations/exists.cc +25 -4
- package/deps/lcb/src/operations/get.cc +39 -19
- package/deps/lcb/src/operations/get_replica.cc +28 -8
- package/deps/lcb/src/operations/observe.cc +1 -1
- package/deps/lcb/src/operations/ping.cc +8 -8
- package/deps/lcb/src/operations/pktfwd.cc +2 -1
- package/deps/lcb/src/operations/remove.cc +39 -22
- package/deps/lcb/src/operations/store.cc +18 -5
- package/deps/lcb/src/operations/subdoc.cc +18 -6
- package/deps/lcb/src/operations/touch.cc +34 -16
- package/deps/lcb/src/operations/unlock.cc +24 -5
- package/deps/lcb/src/packetutils.h +3 -2
- package/deps/lcb/src/retryq.cc +24 -5
- package/deps/lcb/src/search/search.cc +1 -0
- package/deps/lcb/src/search/search_handle.cc +30 -8
- package/deps/lcb/src/search/search_handle.hh +29 -0
- package/deps/lcb/src/settings.cc +1 -1
- package/deps/lcb/src/ssl/ssl_common.c +6 -7
- package/deps/lcb/src/tracing/span.cc +47 -14
- package/deps/lcb/src/tracing/tracer.cc +11 -2
- package/deps/lcb/src/tracing/tracing-internal.h +105 -93
- package/deps/lcb/src/utilities.cc +43 -0
- package/deps/lcb/src/utilities.h +53 -0
- package/deps/lcb/src/vbucket/vbucket.c +34 -33
- package/deps/lcb/src/views/view_handle.cc +13 -5
- package/deps/lcb/src/views/view_handle.hh +29 -0
- package/deps/lcb/tests/CMakeLists.txt +21 -0
- package/deps/lcb/tests/basic/t_ctlcodes.cc +24 -3
- package/deps/lcb/tests/basic/t_jsparse.cc +8 -0
- package/deps/lcb/tests/basic/t_n1qlstrings.cc +73 -0
- package/deps/lcb/tests/iotests/mock-environment.cc +30 -1
- package/deps/lcb/tests/iotests/mock-environment.h +49 -0
- package/deps/lcb/tests/iotests/mock-unit-test.cc +104 -6
- package/deps/lcb/tests/iotests/mock-unit-test.h +34 -0
- package/deps/lcb/tests/iotests/t_collections.cc +1 -1
- package/deps/lcb/tests/iotests/t_confmon.cc +4 -2
- package/deps/lcb/tests/iotests/t_get.cc +109 -7
- package/deps/lcb/tests/iotests/t_http.cc +9 -4
- package/deps/lcb/tests/iotests/t_lock.cc +18 -0
- package/deps/lcb/tests/iotests/t_mutate.cc +157 -63
- package/deps/lcb/tests/iotests/t_n1ql.cc +330 -33
- package/deps/lcb/tests/iotests/t_views.cc +1 -0
- package/deps/lcb/tests/iotests/testutil.cc +168 -0
- package/deps/lcb/tests/iotests/testutil.h +116 -0
- package/deps/lcb/tests/mocksupport/procutil.c +32 -28
- package/deps/lcb/tests/mocksupport/server.c +0 -1
- package/deps/lcb/tests/mocksupport/timeout.c +2 -2
- package/deps/lcb/tools/cbc.cc +7 -0
- package/dist/analyticsindexmanager.js +512 -524
- package/dist/binding.d.ts +3 -0
- package/dist/bindingutilities.js +4 -0
- package/dist/bucket.js +1 -1
- package/dist/bucketmanager.d.ts +31 -1
- package/dist/bucketmanager.js +194 -186
- package/dist/cluster.d.ts +7 -0
- package/dist/cluster.js +48 -38
- package/dist/collection.js +11 -17
- package/dist/collectionmanager.js +181 -197
- package/dist/connection.d.ts +3 -1
- package/dist/connection.js +27 -16
- package/dist/couchbase.d.ts +1 -0
- package/dist/couchbase.js +3 -13
- package/dist/datastructures.js +239 -310
- package/dist/diagnosticsexecutor.js +70 -85
- package/dist/errors.d.ts +70 -0
- package/dist/errors.js +96 -2
- package/dist/eventingfunctionmanager.d.ts +804 -0
- package/dist/eventingfunctionmanager.js +993 -0
- package/dist/httpexecutor.d.ts +2 -1
- package/dist/httpexecutor.js +30 -37
- package/dist/queryindexmanager.js +240 -266
- package/dist/scope.js +10 -4
- package/dist/sdspecs.d.ts +1 -1
- package/dist/searchexecutor.js +3 -0
- package/dist/searchindexmanager.js +240 -271
- package/dist/searchquery.d.ts +17 -0
- package/dist/searchquery.js +22 -1
- package/dist/searchtypes.d.ts +7 -2
- package/dist/searchtypes.js +2 -2
- package/dist/usermanager.js +251 -264
- package/dist/utilities.d.ts +2 -0
- package/dist/utilities.js +7 -2
- package/dist/viewexecutor.js +1 -1
- package/dist/viewindexmanager.js +131 -150
- package/package.json +1 -1
- package/src/addondata.cpp +58 -0
- package/src/addondata.h +40 -0
- package/src/binding.cpp +3 -1
- package/src/cas.h +2 -2
- package/src/connection.cpp +25 -178
- package/src/connection.h +8 -65
- package/src/connection_ops.cpp +57 -34
- package/src/constants.cpp +3 -0
- package/src/instance.cpp +235 -0
- package/src/instance.h +102 -0
- package/src/{connection_callbacks.cpp → instance_callbacks.cpp} +34 -34
- package/src/logger.cpp +11 -1
- package/src/logger.h +3 -0
- package/src/metrics.cpp +10 -0
- package/src/metrics.h +3 -0
- package/src/mutationtoken.h +2 -2
- package/src/opbuilder.h +13 -15
- package/src/respreader.cpp +1 -0
- package/src/respreader.h +6 -4
- package/src/tracespan.h +11 -11
- package/src/tracing.cpp +11 -0
- package/src/tracing.h +3 -0
- package/src/valueparser.h +5 -0
- package/deps/lcb/example/observe/durability.c +0 -110
|
@@ -65,7 +65,7 @@ struct Connstart : ConnectionRequest {
|
|
|
65
65
|
void cancel() override;
|
|
66
66
|
void C_connect();
|
|
67
67
|
|
|
68
|
-
enum State { CS_PENDING, CS_CANCELLED, CS_CONNECTED, CS_ERROR };
|
|
68
|
+
enum State { CS_PENDING, CS_CANCELLED, CS_CONNECTED, CS_ERROR, CS_ERROR_CANCELLED };
|
|
69
69
|
|
|
70
70
|
void state_signal(State next_state, lcb_STATUS err);
|
|
71
71
|
void notify_success();
|
|
@@ -145,6 +145,12 @@ void Connstart::handler()
|
|
|
145
145
|
sock->refcount--; /* dereference because of unsuccessful attempt */
|
|
146
146
|
}
|
|
147
147
|
goto GT_DTOR;
|
|
148
|
+
} else if (state == CS_ERROR_CANCELLED) {
|
|
149
|
+
/* same as above, except the refcount has already been decremented */
|
|
150
|
+
if (sock != nullptr && sock->io->is_C() && sock->u.sd) {
|
|
151
|
+
sock->u.sd->lcbconn = nullptr;
|
|
152
|
+
}
|
|
153
|
+
goto GT_DTOR;
|
|
148
154
|
}
|
|
149
155
|
|
|
150
156
|
if (sock) {
|
|
@@ -225,7 +231,13 @@ void Connstart::cancel()
|
|
|
225
231
|
/* already inside user-defined handler */
|
|
226
232
|
return;
|
|
227
233
|
}
|
|
228
|
-
|
|
234
|
+
|
|
235
|
+
if (state == CS_ERROR) {
|
|
236
|
+
state = CS_ERROR_CANCELLED;
|
|
237
|
+
} else {
|
|
238
|
+
state = CS_CANCELLED;
|
|
239
|
+
}
|
|
240
|
+
|
|
229
241
|
handler();
|
|
230
242
|
}
|
|
231
243
|
|
|
@@ -75,8 +75,8 @@ typedef struct {
|
|
|
75
75
|
struct sockaddr_storage sa_remote;
|
|
76
76
|
struct sockaddr_storage sa_local;
|
|
77
77
|
lcb_host_t ep_remote;
|
|
78
|
-
lcb_host_t
|
|
79
|
-
char
|
|
78
|
+
lcb_host_t ep_local;
|
|
79
|
+
char ep_local_host_and_port[NI_MAXHOST + 1 + NI_MAXSERV + 1];
|
|
80
80
|
} lcbio_CONNINFO;
|
|
81
81
|
|
|
82
82
|
struct lcb_IOMETRICS_st;
|
|
@@ -136,8 +136,10 @@ void lcbio_ctx_close_ex(lcbio_CTX *ctx, lcbio_CTXCLOSE_cb cb, void *arg, lcbio_C
|
|
|
136
136
|
}
|
|
137
137
|
|
|
138
138
|
oldrc = ctx->sock->refcount;
|
|
139
|
-
|
|
140
|
-
|
|
139
|
+
|
|
140
|
+
lcb_log(LOGARGS(ctx, DEBUG),
|
|
141
|
+
CTX_LOGFMT "Destroying context for SOCK=%016" PRIx64 ". Pending Writes=%d, Entered=%s, Socket Refcount=%d",
|
|
142
|
+
CTX_LOGID(ctx), ctx->sock->id, (int)ctx->npending, (int)ctx->entered ? "true" : "false", oldrc);
|
|
141
143
|
|
|
142
144
|
if (cb) {
|
|
143
145
|
int reusable = ctx->npending == 0 && /* no pending events */
|
|
@@ -169,25 +169,24 @@ static int saddr_to_string(struct sockaddr *saddr, int len, char *buf, lcb_size_
|
|
|
169
169
|
|
|
170
170
|
static void lcbio_cache_local_name(lcbio_CONNINFO *sock)
|
|
171
171
|
{
|
|
172
|
+
char addr_str[NI_MAXHOST + 1];
|
|
172
173
|
switch (sock->sa_local.ss_family) {
|
|
173
174
|
case AF_INET: {
|
|
174
175
|
auto *addr = (struct sockaddr_in *)&sock->sa_local;
|
|
175
|
-
inet_ntop(AF_INET, &(addr->sin_addr),
|
|
176
|
-
strncpy(sock->
|
|
177
|
-
snprintf(sock->
|
|
178
|
-
size_t len = strlen(sock->ep_local);
|
|
179
|
-
snprintf(sock->ep_local + len, sizeof(sock->ep_local) - len, ":%d", (int)ntohs(addr->sin_port));
|
|
176
|
+
inet_ntop(AF_INET, &(addr->sin_addr), addr_str, sizeof(addr_str));
|
|
177
|
+
strncpy(sock->ep_local.host, addr_str, sizeof(sock->ep_local.host));
|
|
178
|
+
snprintf(sock->ep_local.port, sizeof(sock->ep_local.port), "%d", (int)ntohs(addr->sin_port));
|
|
180
179
|
} break;
|
|
181
180
|
|
|
182
181
|
case AF_INET6: {
|
|
183
182
|
auto *addr = (struct sockaddr_in6 *)&sock->sa_local;
|
|
184
|
-
inet_ntop(AF_INET6, &(addr->sin6_addr),
|
|
185
|
-
strncpy(sock->
|
|
186
|
-
snprintf(sock->
|
|
187
|
-
size_t len = strlen(sock->ep_local);
|
|
188
|
-
snprintf(sock->ep_local + len, sizeof(sock->ep_local) - len, ":%d", (int)ntohs(addr->sin6_port));
|
|
183
|
+
inet_ntop(AF_INET6, &(addr->sin6_addr), addr_str, sizeof(addr_str));
|
|
184
|
+
strncpy(sock->ep_local.host, addr_str, sizeof(sock->ep_local.host));
|
|
185
|
+
snprintf(sock->ep_local.port, sizeof(sock->ep_local.port), "%d", (int)ntohs(addr->sin6_port));
|
|
189
186
|
} break;
|
|
190
187
|
}
|
|
188
|
+
snprintf(sock->ep_local_host_and_port, sizeof(sock->ep_local_host_and_port), "%s:%s", sock->ep_local.host,
|
|
189
|
+
sock->ep_local.port);
|
|
191
190
|
}
|
|
192
191
|
|
|
193
192
|
void lcbio__load_socknames(lcbio_SOCKET *sock)
|
|
@@ -282,7 +282,7 @@ static void endpointToJSON(hrtime_t now, Json::Value &node, const PoolHost *host
|
|
|
282
282
|
endpoint["id"] = id;
|
|
283
283
|
endpoint["remote"] = get_hehost(host);
|
|
284
284
|
if (info->sock->info) {
|
|
285
|
-
endpoint["local"] = info->sock->info->
|
|
285
|
+
endpoint["local"] = info->sock->info->ep_local_host_and_port;
|
|
286
286
|
endpoint["last_activity_us"] = (Json::Value::UInt64)(now - info->sock->atime);
|
|
287
287
|
}
|
|
288
288
|
auto *session = lcb::SessionInfo::get(info->sock);
|
|
@@ -341,6 +341,11 @@ static bool is_fastpath_error(uint16_t rc)
|
|
|
341
341
|
case PROTOCOL_BINARY_RESPONSE_SYNC_WRITE_IN_PROGRESS:
|
|
342
342
|
case PROTOCOL_BINARY_RESPONSE_SYNC_WRITE_AMBIGUOUS:
|
|
343
343
|
case PROTOCOL_BINARY_RESPONSE_LOCKED:
|
|
344
|
+
case PROTOCOL_BINARY_RATE_LIMITED_NETWORK_INGRESS:
|
|
345
|
+
case PROTOCOL_BINARY_RATE_LIMITED_NETWORK_EGRESS:
|
|
346
|
+
case PROTOCOL_BINARY_RATE_LIMITED_MAX_CONNECTIONS:
|
|
347
|
+
case PROTOCOL_BINARY_RATE_LIMITED_MAX_COMMANDS:
|
|
348
|
+
case PROTOCOL_BINARY_SCOPE_SIZE_LIMIT_EXCEEDED:
|
|
344
349
|
return true;
|
|
345
350
|
default:
|
|
346
351
|
if (rc >= 0xc0 && rc <= 0xcc) {
|
|
@@ -395,10 +400,6 @@ int Server::handle_unknown_error(const mc_PACKET *request, const MemcachedRespon
|
|
|
395
400
|
newerr = LCB_ERR_TEMPORARY_FAILURE;
|
|
396
401
|
}
|
|
397
402
|
|
|
398
|
-
if (err.hasAttribute(errmap::CONSTRAINT_FAILURE)) {
|
|
399
|
-
newerr = LCB_ERR_CAS_MISMATCH;
|
|
400
|
-
}
|
|
401
|
-
|
|
402
403
|
if (err.hasAttribute(errmap::AUTH)) {
|
|
403
404
|
newerr = LCB_ERR_AUTHENTICATION_FAILURE;
|
|
404
405
|
}
|
|
@@ -754,6 +755,8 @@ static const char *opcode_name(uint8_t code)
|
|
|
754
755
|
return "subdoc_get_count";
|
|
755
756
|
case PROTOCOL_BINARY_CMD_GET_ERROR_MAP:
|
|
756
757
|
return "get_error_map";
|
|
758
|
+
case PROTOCOL_BINARY_CMD_GET_META:
|
|
759
|
+
return "exists";
|
|
757
760
|
default:
|
|
758
761
|
return "unknown";
|
|
759
762
|
}
|
|
@@ -811,12 +814,12 @@ void Server::purge_single(mc_PACKET *pkt, lcb_STATUS err)
|
|
|
811
814
|
snprintf(local_id, sizeof(local_id), "%016" PRIx64 "/%016" PRIx64 "/%x", settings->iid, connctx->sock->id,
|
|
812
815
|
(int)pkt->opaque);
|
|
813
816
|
info["i"] = local_id;
|
|
814
|
-
info["l"] = connctx->sock->info->
|
|
817
|
+
info["l"] = connctx->sock->info->ep_local_host_and_port;
|
|
815
818
|
}
|
|
816
819
|
std::string msg(Json::FastWriter().write(info));
|
|
817
820
|
if (msg.size() > 1) {
|
|
818
821
|
lcb_log(LOGARGS(instance, WARN), "Failing command with error %s: %.*s", lcb_strerror_short(err),
|
|
819
|
-
(int)
|
|
822
|
+
(int)msg.size(), msg.c_str());
|
|
820
823
|
}
|
|
821
824
|
} else {
|
|
822
825
|
lcb_log(LOGARGS_T(WARN), LOGFMT "Failing command (pkt=%p, opaque=%lu, opcode=0x%x) with error %s", LOGID_T(),
|
|
@@ -185,6 +185,7 @@ class lcb::SessionRequestImpl : public SessionRequest
|
|
|
185
185
|
SessionInfo *info;
|
|
186
186
|
lcb_settings *settings;
|
|
187
187
|
lcb_host_t host_{};
|
|
188
|
+
bool expecting_error_map{false};
|
|
188
189
|
};
|
|
189
190
|
|
|
190
191
|
static void handle_read(lcbio_CTX *ioctx, unsigned)
|
|
@@ -316,8 +317,9 @@ SessionRequestImpl::MechStatus SessionRequestImpl::set_chosen_mech(std::string &
|
|
|
316
317
|
"PLAIN, but using SCRAM methods is strongly recommended over non-encrypted transports.",
|
|
317
318
|
LOGID(this));
|
|
318
319
|
#else
|
|
319
|
-
lcb_log(LOGARGS(this, WARN),
|
|
320
|
-
|
|
320
|
+
lcb_log(LOGARGS(this, WARN),
|
|
321
|
+
LOGFMT "SASL PLAIN authentication is not allowed on non-TLS connections (server supports: %s)",
|
|
322
|
+
LOGID(this), mechlist.c_str());
|
|
321
323
|
return MECH_UNAVAILABLE;
|
|
322
324
|
#endif
|
|
323
325
|
}
|
|
@@ -642,15 +644,15 @@ GT_NEXT_PACKET:
|
|
|
642
644
|
}
|
|
643
645
|
|
|
644
646
|
if (settings->keypath) {
|
|
645
|
-
completed = !maybe_select_bucket();
|
|
647
|
+
completed = !expecting_error_map && !maybe_select_bucket();
|
|
646
648
|
}
|
|
647
649
|
break;
|
|
648
650
|
}
|
|
649
651
|
|
|
650
652
|
case PROTOCOL_BINARY_CMD_GET_ERROR_MAP: {
|
|
653
|
+
expecting_error_map = false;
|
|
651
654
|
if (status == PROTOCOL_BINARY_RESPONSE_SUCCESS) {
|
|
652
|
-
|
|
653
|
-
}
|
|
655
|
+
update_errmap(resp);
|
|
654
656
|
} else if (isUnsupported(status)) {
|
|
655
657
|
lcb_log(LOGARGS(this, DEBUG), LOGFMT "Server does not support GET_ERRMAP (0x%x)", LOGID(this), status);
|
|
656
658
|
} else {
|
|
@@ -664,18 +666,37 @@ GT_NEXT_PACKET:
|
|
|
664
666
|
}
|
|
665
667
|
|
|
666
668
|
case PROTOCOL_BINARY_CMD_SELECT_BUCKET: {
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
669
|
+
switch (status) {
|
|
670
|
+
case PROTOCOL_BINARY_RESPONSE_SUCCESS:
|
|
671
|
+
completed = true;
|
|
672
|
+
info->selected = true;
|
|
673
|
+
break;
|
|
674
|
+
|
|
675
|
+
case PROTOCOL_BINARY_RESPONSE_EACCESS:
|
|
676
|
+
set_error(LCB_ERR_BUCKET_NOT_FOUND,
|
|
677
|
+
"Provided credentials not allowed for bucket or bucket does not exist", &resp);
|
|
678
|
+
break;
|
|
679
|
+
|
|
680
|
+
case PROTOCOL_BINARY_RESPONSE_KEY_ENOENT:
|
|
681
|
+
set_error(LCB_ERR_BUCKET_NOT_FOUND, "Key/Value service is not configured for given node", &resp);
|
|
682
|
+
break;
|
|
683
|
+
|
|
684
|
+
case PROTOCOL_BINARY_RATE_LIMITED_MAX_COMMANDS:
|
|
685
|
+
case PROTOCOL_BINARY_RATE_LIMITED_MAX_CONNECTIONS:
|
|
686
|
+
case PROTOCOL_BINARY_RATE_LIMITED_NETWORK_EGRESS:
|
|
687
|
+
case PROTOCOL_BINARY_RATE_LIMITED_NETWORK_INGRESS:
|
|
688
|
+
set_error(LCB_ERR_RATE_LIMITED, "The tenant has reached rate limit", &resp);
|
|
689
|
+
break;
|
|
690
|
+
|
|
691
|
+
case PROTOCOL_BINARY_SCOPE_SIZE_LIMIT_EXCEEDED:
|
|
692
|
+
set_error(LCB_ERR_QUOTA_LIMITED, "The tenant has reached quota limit", &resp);
|
|
693
|
+
break;
|
|
694
|
+
|
|
695
|
+
default:
|
|
696
|
+
lcb_log(LOGARGS(this, ERROR), LOGFMT "Unexpected status 0x%x received for SELECT_BUCKET",
|
|
697
|
+
LOGID(this), status);
|
|
698
|
+
set_error(LCB_ERR_PROTOCOL_ERROR, "Other auth error", &resp);
|
|
699
|
+
break;
|
|
679
700
|
}
|
|
680
701
|
break;
|
|
681
702
|
}
|
|
@@ -744,6 +765,7 @@ void SessionRequestImpl::start(lcbio_SOCKET *sock)
|
|
|
744
765
|
send_hello();
|
|
745
766
|
if (settings->use_errmap) {
|
|
746
767
|
request_errmap();
|
|
768
|
+
expecting_error_map = true;
|
|
747
769
|
} else {
|
|
748
770
|
lcb_log(LOGARGS(this, TRACE), LOGFMT "GET_ERRORMAP disabled", LOGID(this));
|
|
749
771
|
}
|
|
@@ -201,8 +201,7 @@ lcb_STATUS dispatch_common(lcb_INSTANCE *instance, const void *cookie, lcb_N1XMG
|
|
|
201
201
|
Json::Value root;
|
|
202
202
|
root["statement"] = ss;
|
|
203
203
|
string reqbuf = Json::FastWriter().write(root);
|
|
204
|
-
return dispatch_common<T>(instance, cookie, u_callback, i_callback, reqbuf.c_str(), reqbuf.size()
|
|
205
|
-
obj);
|
|
204
|
+
return dispatch_common<T>(instance, cookie, u_callback, i_callback, reqbuf.c_str(), reqbuf.size(), obj);
|
|
206
205
|
}
|
|
207
206
|
|
|
208
207
|
// Class to back the storage for the actual lcb_IXSPEC without doing too much
|
|
@@ -99,7 +99,7 @@ bool lcb_QUERY_HANDLE_::parse_meta(const char *row, size_t row_len, lcb_STATUS &
|
|
|
99
99
|
first_error_code = 0;
|
|
100
100
|
|
|
101
101
|
Json::Value meta;
|
|
102
|
-
if (!Json::Reader().parse(row, row + row_len, meta)) {
|
|
102
|
+
if (!Json::Reader(Json::Features::strictMode()).parse(row, row + row_len, meta)) {
|
|
103
103
|
return false;
|
|
104
104
|
}
|
|
105
105
|
const Json::Value &errors = meta["errors"];
|
|
@@ -143,13 +143,15 @@ bool lcb_QUERY_HANDLE_::parse_meta(const char *row, size_t row_len, lcb_STATUS &
|
|
|
143
143
|
rc = LCB_ERR_INTERNAL_SERVER_FAILURE;
|
|
144
144
|
if (!first_error_message.empty()) {
|
|
145
145
|
std::regex already_exists("Index.+already exists"); /* NOTE: case sensitive */
|
|
146
|
+
std::regex not_found("index.+not found");
|
|
146
147
|
if (std::regex_search(first_error_message, already_exists)) {
|
|
147
148
|
rc = LCB_ERR_INDEX_EXISTS;
|
|
148
|
-
} else {
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
149
|
+
} else if (std::regex_search(first_error_message, not_found)) {
|
|
150
|
+
rc = LCB_ERR_INDEX_NOT_FOUND;
|
|
151
|
+
} else if (first_error_message.find(
|
|
152
|
+
"Limit for number of indexes that can be created per scope has been reached") !=
|
|
153
|
+
std::string::npos) {
|
|
154
|
+
rc = LCB_ERR_QUOTA_LIMITED;
|
|
153
155
|
}
|
|
154
156
|
}
|
|
155
157
|
break;
|
|
@@ -166,6 +168,14 @@ bool lcb_QUERY_HANDLE_::parse_meta(const char *row, size_t row_len, lcb_STATUS &
|
|
|
166
168
|
case 13014:
|
|
167
169
|
rc = LCB_ERR_AUTHENTICATION_FAILURE;
|
|
168
170
|
break;
|
|
171
|
+
|
|
172
|
+
case 1191:
|
|
173
|
+
case 1192:
|
|
174
|
+
case 1193:
|
|
175
|
+
case 1194:
|
|
176
|
+
rc = LCB_ERR_RATE_LIMITED;
|
|
177
|
+
break;
|
|
178
|
+
|
|
169
179
|
default:
|
|
170
180
|
if (first_error_code >= 4000 && first_error_code < 5000) {
|
|
171
181
|
rc = LCB_ERR_PLANNING_FAILURE;
|
|
@@ -195,8 +205,8 @@ void lcb_QUERY_HANDLE_::invoke_row(lcb_RESPQUERY *resp, bool is_last)
|
|
|
195
205
|
resp->ctx.endpoint = resp->htresp->ctx.endpoint;
|
|
196
206
|
resp->ctx.endpoint_len = resp->htresp->ctx.endpoint_len;
|
|
197
207
|
}
|
|
198
|
-
resp->ctx.client_context_id =
|
|
199
|
-
resp->ctx.client_context_id_len =
|
|
208
|
+
resp->ctx.client_context_id = client_context_id_.c_str();
|
|
209
|
+
resp->ctx.client_context_id_len = client_context_id_.size();
|
|
200
210
|
resp->ctx.statement = statement_.c_str();
|
|
201
211
|
resp->ctx.statement_len = statement_.size();
|
|
202
212
|
|
|
@@ -213,9 +223,11 @@ void lcb_QUERY_HANDLE_::invoke_row(lcb_RESPQUERY *resp, bool is_last)
|
|
|
213
223
|
resp->ctx.first_error_message_len = first_error_message.size();
|
|
214
224
|
}
|
|
215
225
|
resp->ctx.first_error_code = first_error_code;
|
|
216
|
-
|
|
226
|
+
if (span_ != nullptr) {
|
|
227
|
+
lcb::trace::finish_http_span(span_, this);
|
|
228
|
+
span_ = nullptr;
|
|
229
|
+
}
|
|
217
230
|
|
|
218
|
-
LCBTRACE_HTTP_FINISH(span_);
|
|
219
231
|
if (http_request_ != nullptr) {
|
|
220
232
|
http_request_->span = nullptr;
|
|
221
233
|
}
|
|
@@ -372,6 +384,10 @@ lcb_RETRY_ACTION lcb_QUERY_HANDLE_::has_retriable_error(lcb_STATUS &rc)
|
|
|
372
384
|
}
|
|
373
385
|
}
|
|
374
386
|
}
|
|
387
|
+
|
|
388
|
+
if (rc == LCB_SUCCESS) {
|
|
389
|
+
return {0, 0};
|
|
390
|
+
}
|
|
375
391
|
return lcb_query_should_retry(instance_->settings, this, rc);
|
|
376
392
|
}
|
|
377
393
|
|
|
@@ -390,9 +406,12 @@ lcb_STATUS lcb_QUERY_HANDLE_::issue_htreq(const std::string &body)
|
|
|
390
406
|
lcb_cmdhttp_content_type(htcmd, content_type.c_str(), content_type.size());
|
|
391
407
|
lcb_cmdhttp_method(htcmd, LCB_HTTP_METHOD_POST);
|
|
392
408
|
lcb_cmdhttp_streaming(htcmd, true);
|
|
393
|
-
lcb_cmdhttp_timeout(htcmd, timeout);
|
|
409
|
+
lcb_cmdhttp_timeout(htcmd, timeout + LCBT_SETTING(instance_, n1ql_grace_period));
|
|
394
410
|
lcb_cmdhttp_handle(htcmd, &http_request_);
|
|
395
411
|
lcb_cmdhttp_host(htcmd, endpoint.data(), endpoint.size());
|
|
412
|
+
if (!impostor_.empty()) {
|
|
413
|
+
htcmd->set_header("cb-on-behalf-of", impostor_);
|
|
414
|
+
}
|
|
396
415
|
if (use_multi_bucket_authentication_) {
|
|
397
416
|
lcb_cmdhttp_skip_auth_header(htcmd, true);
|
|
398
417
|
} else {
|
|
@@ -416,6 +435,10 @@ lcb_STATUS lcb_QUERY_HANDLE_::issue_htreq(const std::string &body)
|
|
|
416
435
|
if (rc == LCB_SUCCESS) {
|
|
417
436
|
http_request_->set_callback(reinterpret_cast<lcb_RESPCALLBACK>(chunk_callback));
|
|
418
437
|
}
|
|
438
|
+
lcb_log(LOGARGS(this, TRACE),
|
|
439
|
+
LOGFMT "execute query: %.*s, idempotent=%s, timeout=%uus, grace_period=%uus, client_context_id=\"%s\"",
|
|
440
|
+
LOGID(this), (int)body.size(), body.c_str(), idempotent_ ? "true" : "false", timeout,
|
|
441
|
+
LCBT_SETTING(instance_, n1ql_grace_period), client_context_id_.c_str());
|
|
419
442
|
return rc;
|
|
420
443
|
}
|
|
421
444
|
|
|
@@ -506,17 +529,14 @@ lcb_QUERY_HANDLE_::lcb_QUERY_HANDLE_(lcb_INSTANCE *obj, void *user_cookie, const
|
|
|
506
529
|
if (ccid.isNull()) {
|
|
507
530
|
char buf[32];
|
|
508
531
|
size_t nbuf = snprintf(buf, sizeof(buf), "%016" PRIx64, lcb_next_rand64());
|
|
509
|
-
|
|
510
|
-
json["client_context_id"] =
|
|
532
|
+
client_context_id_.assign(buf, nbuf);
|
|
533
|
+
json["client_context_id"] = client_context_id_;
|
|
511
534
|
} else {
|
|
512
|
-
|
|
535
|
+
client_context_id_ = ccid.asString();
|
|
513
536
|
}
|
|
514
537
|
if (json.isMember("readonly") && json["readonly"].asBool()) {
|
|
515
538
|
idempotent_ = true;
|
|
516
539
|
}
|
|
517
|
-
lcb_log(LOGARGS(this, TRACE), LOGFMT "%.*s, idempotent=%s, timeout=%uus, grace_period=%uus", LOGID(this),
|
|
518
|
-
(int)statement_.size(), statement_.c_str(), idempotent_ ? "true" : "false", timeout,
|
|
519
|
-
LCBT_SETTING(obj, n1ql_grace_period));
|
|
520
540
|
timeout_timer_.rearm(timeout + LCBT_SETTING(obj, n1ql_grace_period));
|
|
521
541
|
|
|
522
542
|
// Determine if we need to add more credentials.
|
|
@@ -541,10 +561,12 @@ lcb_QUERY_HANDLE_::lcb_QUERY_HANDLE_(lcb_INSTANCE *obj, void *user_cookie, const
|
|
|
541
561
|
curCreds["pass"] = ii->second;
|
|
542
562
|
}
|
|
543
563
|
}
|
|
564
|
+
if (cmd->want_impersonation()) {
|
|
565
|
+
impostor_ = cmd->impostor();
|
|
566
|
+
}
|
|
544
567
|
if (instance_->settings->tracer) {
|
|
545
568
|
parent_span_ = cmd->parent_span();
|
|
546
|
-
|
|
547
|
-
LCBTRACE_THRESHOLD_QUERY, span_);
|
|
569
|
+
span_ = lcb::trace::start_http_span_with_statement(instance_->settings, this, statement_);
|
|
548
570
|
}
|
|
549
571
|
}
|
|
550
572
|
|
|
@@ -246,6 +246,32 @@ struct lcb_QUERY_HANDLE_ : lcb::jsparse::Parser::Actions {
|
|
|
246
246
|
return LCB_SUCCESS;
|
|
247
247
|
}
|
|
248
248
|
|
|
249
|
+
static lcbtrace_THRESHOLDOPTS service()
|
|
250
|
+
{
|
|
251
|
+
return LCBTRACE_THRESHOLD_QUERY;
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
static const std::string &operation_name()
|
|
255
|
+
{
|
|
256
|
+
static std::string name = LCBTRACE_OP_QUERY;
|
|
257
|
+
return name;
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
lcbtrace_SPAN *parent_span() const
|
|
261
|
+
{
|
|
262
|
+
return parent_span_;
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
const std::string &client_context_id() const
|
|
266
|
+
{
|
|
267
|
+
return client_context_id_;
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
int retries() const
|
|
271
|
+
{
|
|
272
|
+
return retries_;
|
|
273
|
+
}
|
|
274
|
+
|
|
249
275
|
private:
|
|
250
276
|
void on_backoff();
|
|
251
277
|
|
|
@@ -269,7 +295,7 @@ struct lcb_QUERY_HANDLE_ : lcb::jsparse::Parser::Actions {
|
|
|
269
295
|
Json::Value json;
|
|
270
296
|
/** String of the original statement. Cached here to avoid jsoncpp lookups */
|
|
271
297
|
std::string statement_;
|
|
272
|
-
std::string
|
|
298
|
+
std::string client_context_id_;
|
|
273
299
|
std::string first_error_message{};
|
|
274
300
|
uint32_t first_error_code{};
|
|
275
301
|
|
|
@@ -290,6 +316,7 @@ struct lcb_QUERY_HANDLE_ : lcb::jsparse::Parser::Actions {
|
|
|
290
316
|
|
|
291
317
|
lcb::io::Timer<lcb_QUERY_HANDLE_, &lcb_QUERY_HANDLE_::on_timeout> timeout_timer_;
|
|
292
318
|
lcb::io::Timer<lcb_QUERY_HANDLE_, &lcb_QUERY_HANDLE_::on_backoff> backoff_timer_;
|
|
319
|
+
std::string impostor_{};
|
|
293
320
|
};
|
|
294
321
|
|
|
295
322
|
#endif // LIBCOUCHBASE_N1QL_QUERY_HANDLE_HH
|
|
@@ -136,6 +136,11 @@ LIBCOUCHBASE_API lcb_STATUS lcb_cmdcounter_durability(lcb_CMDCOUNTER *cmd, lcb_D
|
|
|
136
136
|
return cmd->durability_level(level);
|
|
137
137
|
}
|
|
138
138
|
|
|
139
|
+
LIBCOUCHBASE_API lcb_STATUS lcb_cmdcounter_on_behalf_of(lcb_CMDCOUNTER *cmd, const char *data, size_t data_len)
|
|
140
|
+
{
|
|
141
|
+
return cmd->on_behalf_of(std::string(data, data_len));
|
|
142
|
+
}
|
|
143
|
+
|
|
139
144
|
static lcb_STATUS counter_validate(lcb_INSTANCE *instance, const lcb_CMDCOUNTER *cmd)
|
|
140
145
|
{
|
|
141
146
|
if (cmd->key().empty()) {
|
|
@@ -164,13 +169,21 @@ static lcb_STATUS counter_schedule(lcb_INSTANCE *instance, std::shared_ptr<lcb_C
|
|
|
164
169
|
|
|
165
170
|
std::vector<std::uint8_t> framing_extras;
|
|
166
171
|
if (new_durability_supported && cmd->has_durability_requirements()) {
|
|
172
|
+
auto durability_timeout = htons(lcb_durability_timeout(instance, cmd->timeout_in_microseconds()));
|
|
167
173
|
std::uint8_t frame_id = 0x01;
|
|
168
|
-
std::uint8_t frame_size =
|
|
174
|
+
std::uint8_t frame_size = durability_timeout > 0 ? 3 : 1;
|
|
169
175
|
framing_extras.emplace_back(frame_id << 4U | frame_size);
|
|
170
176
|
framing_extras.emplace_back(cmd->durability_level());
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
177
|
+
if (durability_timeout > 0) {
|
|
178
|
+
framing_extras.emplace_back(durability_timeout >> 8U);
|
|
179
|
+
framing_extras.emplace_back(durability_timeout & 0xff);
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
if (cmd->want_impersonation()) {
|
|
183
|
+
err = lcb::flexible_framing_extras::encode_impersonate_user(cmd->impostor(), framing_extras);
|
|
184
|
+
if (err != LCB_SUCCESS) {
|
|
185
|
+
return err;
|
|
186
|
+
}
|
|
174
187
|
}
|
|
175
188
|
|
|
176
189
|
hdr.request.magic = framing_extras.empty() ? PROTOCOL_BINARY_REQ : PROTOCOL_BINARY_AREQ;
|
|
@@ -224,7 +237,7 @@ static lcb_STATUS counter_schedule(lcb_INSTANCE *instance, std::shared_ptr<lcb_C
|
|
|
224
237
|
}
|
|
225
238
|
memcpy(SPAN_BUFFER(&packet->kh_span) + offset, &expiry, sizeof(expiry));
|
|
226
239
|
|
|
227
|
-
|
|
240
|
+
rdata->span = lcb::trace::start_kv_span(instance->settings, packet, cmd);
|
|
228
241
|
TRACE_ARITHMETIC_BEGIN(instance, &hdr, cmd);
|
|
229
242
|
LCB_SCHED_ADD(instance, pipeline, packet);
|
|
230
243
|
return LCB_SUCCESS;
|
|
@@ -107,6 +107,11 @@ LIBCOUCHBASE_API lcb_STATUS lcb_cmdexists_key(lcb_CMDEXISTS *cmd, const char *ke
|
|
|
107
107
|
return cmd->key(std::string(key, key_len));
|
|
108
108
|
}
|
|
109
109
|
|
|
110
|
+
LIBCOUCHBASE_API lcb_STATUS lcb_cmdexists_on_behalf_of(lcb_CMDEXISTS *cmd, const char *data, size_t data_len)
|
|
111
|
+
{
|
|
112
|
+
return cmd->on_behalf_of(std::string(data, data_len));
|
|
113
|
+
}
|
|
114
|
+
|
|
110
115
|
static lcb_STATUS exists_validate(lcb_INSTANCE *instance, const lcb_CMDEXISTS *cmd)
|
|
111
116
|
{
|
|
112
117
|
if (cmd->key().empty()) {
|
|
@@ -123,12 +128,24 @@ static lcb_STATUS exists_schedule(lcb_INSTANCE *instance, std::shared_ptr<lcb_CM
|
|
|
123
128
|
{
|
|
124
129
|
mc_CMDQUEUE *cq = &instance->cmdq;
|
|
125
130
|
|
|
126
|
-
protocol_binary_request_header hdr;
|
|
131
|
+
protocol_binary_request_header hdr{};
|
|
127
132
|
mc_PIPELINE *pipeline;
|
|
128
133
|
mc_PACKET *pkt;
|
|
129
134
|
lcb_STATUS err;
|
|
135
|
+
|
|
136
|
+
std::vector<std::uint8_t> framing_extras;
|
|
137
|
+
if (cmd->want_impersonation()) {
|
|
138
|
+
err = lcb::flexible_framing_extras::encode_impersonate_user(cmd->impostor(), framing_extras);
|
|
139
|
+
if (err != LCB_SUCCESS) {
|
|
140
|
+
return err;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
hdr.request.magic = framing_extras.empty() ? PROTOCOL_BINARY_REQ : PROTOCOL_BINARY_AREQ;
|
|
145
|
+
auto ffextlen = static_cast<std::uint8_t>(framing_extras.size());
|
|
146
|
+
|
|
130
147
|
lcb_KEYBUF keybuf{LCB_KV_COPY, {cmd->key().c_str(), cmd->key().size()}};
|
|
131
|
-
err = mcreq_basic_packet(cq, &keybuf, cmd->collection().collection_id(), &hdr, 0,
|
|
148
|
+
err = mcreq_basic_packet(cq, &keybuf, cmd->collection().collection_id(), &hdr, 0, ffextlen, &pkt, &pipeline,
|
|
132
149
|
MCREQ_BASICPACKET_F_FALLBACKOK);
|
|
133
150
|
if (err != LCB_SUCCESS) {
|
|
134
151
|
return err;
|
|
@@ -136,7 +153,7 @@ static lcb_STATUS exists_schedule(lcb_INSTANCE *instance, std::shared_ptr<lcb_CM
|
|
|
136
153
|
|
|
137
154
|
hdr.request.opcode = PROTOCOL_BINARY_CMD_GET_META;
|
|
138
155
|
hdr.request.datatype = PROTOCOL_BINARY_RAW_BYTES;
|
|
139
|
-
hdr.request.bodylen =
|
|
156
|
+
hdr.request.bodylen = ntohl(mcreq_get_key_size(&hdr));
|
|
140
157
|
hdr.request.opaque = pkt->opaque;
|
|
141
158
|
hdr.request.cas = 0;
|
|
142
159
|
|
|
@@ -146,8 +163,12 @@ static lcb_STATUS exists_schedule(lcb_INSTANCE *instance, std::shared_ptr<lcb_CM
|
|
|
146
163
|
pkt->u_rdata.reqdata.start +
|
|
147
164
|
cmd->timeout_or_default_in_nanoseconds(LCB_US2NS(LCBT_SETTING(instance, operation_timeout)));
|
|
148
165
|
memcpy(SPAN_BUFFER(&pkt->kh_span), hdr.bytes, MCREQ_PKT_BASESIZE);
|
|
166
|
+
std::size_t offset = sizeof(hdr);
|
|
167
|
+
if (!framing_extras.empty()) {
|
|
168
|
+
memcpy(SPAN_BUFFER(&pkt->kh_span) + offset, framing_extras.data(), framing_extras.size());
|
|
169
|
+
}
|
|
149
170
|
|
|
150
|
-
|
|
171
|
+
pkt->u_rdata.reqdata.span = lcb::trace::start_kv_span(instance->settings, pkt, cmd);
|
|
151
172
|
LCB_SCHED_ADD(instance, pipeline, pkt)
|
|
152
173
|
TRACE_EXISTS_BEGIN(instance, &hdr, cmd);
|
|
153
174
|
return LCB_SUCCESS;
|
|
@@ -124,6 +124,11 @@ LIBCOUCHBASE_API lcb_STATUS lcb_cmdget_locktime(lcb_CMDGET *cmd, uint32_t durati
|
|
|
124
124
|
return cmd->with_lock(duration);
|
|
125
125
|
}
|
|
126
126
|
|
|
127
|
+
LIBCOUCHBASE_API lcb_STATUS lcb_cmdget_on_behalf_of(lcb_CMDGET *cmd, const char *data, size_t data_len)
|
|
128
|
+
{
|
|
129
|
+
return cmd->on_behalf_of(std::string(data, data_len));
|
|
130
|
+
}
|
|
131
|
+
|
|
127
132
|
static lcb_STATUS get_validate(lcb_INSTANCE *instance, const lcb_CMDGET *cmd)
|
|
128
133
|
{
|
|
129
134
|
if (cmd->key().empty()) {
|
|
@@ -145,11 +150,20 @@ static lcb_STATUS get_schedule(lcb_INSTANCE *instance, std::shared_ptr<lcb_CMDGE
|
|
|
145
150
|
mc_CMDQUEUE *q = &instance->cmdq;
|
|
146
151
|
lcb_uint8_t extlen = 0;
|
|
147
152
|
lcb_uint8_t opcode = PROTOCOL_BINARY_CMD_GET;
|
|
148
|
-
|
|
149
|
-
protocol_binary_request_header *hdr = &gcmd.message.header;
|
|
153
|
+
protocol_binary_request_header hdr{};
|
|
150
154
|
lcb_STATUS err;
|
|
151
155
|
|
|
152
|
-
|
|
156
|
+
std::vector<std::uint8_t> framing_extras;
|
|
157
|
+
if (cmd->want_impersonation()) {
|
|
158
|
+
err = lcb::flexible_framing_extras::encode_impersonate_user(cmd->impostor(), framing_extras);
|
|
159
|
+
if (err != LCB_SUCCESS) {
|
|
160
|
+
return err;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
hdr.request.magic = framing_extras.empty() ? PROTOCOL_BINARY_REQ : PROTOCOL_BINARY_AREQ;
|
|
165
|
+
auto ffextlen = static_cast<std::uint8_t>(framing_extras.size());
|
|
166
|
+
|
|
153
167
|
if (cmd->with_lock()) {
|
|
154
168
|
extlen = 4;
|
|
155
169
|
opcode = PROTOCOL_BINARY_CMD_GET_LOCKED;
|
|
@@ -159,7 +173,7 @@ static lcb_STATUS get_schedule(lcb_INSTANCE *instance, std::shared_ptr<lcb_CMDGE
|
|
|
159
173
|
}
|
|
160
174
|
|
|
161
175
|
lcb_KEYBUF keybuf{LCB_KV_COPY, {cmd->key().c_str(), cmd->key().size()}};
|
|
162
|
-
err = mcreq_basic_packet(q, &keybuf, cmd->collection().collection_id(), hdr, extlen,
|
|
176
|
+
err = mcreq_basic_packet(q, &keybuf, cmd->collection().collection_id(), &hdr, extlen, ffextlen, &pkt, &pl,
|
|
163
177
|
MCREQ_BASICPACKET_F_FALLBACKOK);
|
|
164
178
|
if (err != LCB_SUCCESS) {
|
|
165
179
|
return err;
|
|
@@ -171,27 +185,33 @@ static lcb_STATUS get_schedule(lcb_INSTANCE *instance, std::shared_ptr<lcb_CMDGE
|
|
|
171
185
|
rdata->deadline =
|
|
172
186
|
rdata->start + cmd->timeout_or_default_in_nanoseconds(LCB_US2NS(LCBT_SETTING(instance, operation_timeout)));
|
|
173
187
|
|
|
174
|
-
hdr
|
|
175
|
-
hdr
|
|
176
|
-
hdr
|
|
177
|
-
hdr
|
|
178
|
-
hdr
|
|
179
|
-
|
|
180
|
-
if (cmd->with_lock()) {
|
|
181
|
-
gcmd.message.body.norm.expiration = htonl(cmd->lock_time());
|
|
182
|
-
}
|
|
183
|
-
if (extlen) {
|
|
184
|
-
gcmd.message.body.norm.expiration = htonl(cmd->expiry());
|
|
185
|
-
}
|
|
188
|
+
hdr.request.opcode = opcode;
|
|
189
|
+
hdr.request.datatype = PROTOCOL_BINARY_RAW_BYTES;
|
|
190
|
+
hdr.request.bodylen = htonl(extlen + ffextlen + mcreq_get_key_size(&hdr));
|
|
191
|
+
hdr.request.opaque = pkt->opaque;
|
|
192
|
+
hdr.request.cas = 0;
|
|
186
193
|
|
|
187
194
|
if (cmd->is_cookie_callback()) {
|
|
188
195
|
pkt->flags |= MCREQ_F_PRIVCALLBACK;
|
|
189
196
|
}
|
|
190
197
|
|
|
191
|
-
memcpy(SPAN_BUFFER(&pkt->kh_span),
|
|
192
|
-
|
|
198
|
+
memcpy(SPAN_BUFFER(&pkt->kh_span), &hdr, sizeof(hdr));
|
|
199
|
+
std::size_t offset = sizeof(hdr);
|
|
200
|
+
if (!framing_extras.empty()) {
|
|
201
|
+
memcpy(SPAN_BUFFER(&pkt->kh_span) + offset, framing_extras.data(), framing_extras.size());
|
|
202
|
+
offset += framing_extras.size();
|
|
203
|
+
}
|
|
204
|
+
if (cmd->with_lock()) {
|
|
205
|
+
std::uint32_t lock_expiry = htonl(cmd->lock_time());
|
|
206
|
+
memcpy(SPAN_BUFFER(&pkt->kh_span) + offset, &lock_expiry, sizeof(lock_expiry));
|
|
207
|
+
} else if (cmd->with_touch()) {
|
|
208
|
+
std::uint32_t expiry = htonl(cmd->expiry());
|
|
209
|
+
memcpy(SPAN_BUFFER(&pkt->kh_span) + offset, &expiry, sizeof(expiry));
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
rdata->span = lcb::trace::start_kv_span(instance->settings, pkt, cmd);
|
|
193
213
|
LCB_SCHED_ADD(instance, pl, pkt)
|
|
194
|
-
TRACE_GET_BEGIN(instance, hdr, cmd);
|
|
214
|
+
TRACE_GET_BEGIN(instance, &hdr, cmd);
|
|
195
215
|
return LCB_SUCCESS;
|
|
196
216
|
}
|
|
197
217
|
|