couchbase 3.2.0 → 3.2.4
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
|