couchbase 3.2.4 → 3.2.5
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/binding.gyp +5 -0
- package/deps/lcb/CMakeLists.txt +1 -1
- package/deps/lcb/RELEASE_NOTES.markdown +12 -0
- package/deps/lcb/cmake/Modules/GetVersionInfo.cmake +1 -1
- package/deps/lcb/doc/Doxyfile +1 -1
- package/deps/lcb/gyp_config/common/libcouchbase/configuration.h +3 -3
- package/deps/lcb/include/libcouchbase/couchbase.h +52 -0
- package/deps/lcb/include/libcouchbase/error.h +4 -1
- package/deps/lcb/libcouchbase.gyp +7 -1
- package/deps/lcb/src/capi/cmd_counter.hh +12 -0
- package/deps/lcb/src/capi/cmd_exists.hh +12 -0
- package/deps/lcb/src/capi/cmd_get.hh +12 -0
- package/deps/lcb/src/capi/cmd_get_replica.hh +14 -1
- package/deps/lcb/src/capi/cmd_query.cc +13 -0
- package/deps/lcb/src/capi/cmd_query.hh +22 -14
- package/deps/lcb/src/capi/cmd_remove.hh +12 -0
- package/deps/lcb/src/capi/cmd_store.hh +12 -0
- package/deps/lcb/src/capi/cmd_subdoc.hh +12 -0
- package/deps/lcb/src/capi/cmd_touch.hh +12 -0
- package/deps/lcb/src/capi/cmd_unlock.hh +12 -0
- package/deps/lcb/src/capi/collection_qualifier.hh +4 -6
- package/deps/lcb/src/internal.h +2 -1
- package/deps/lcb/src/mcserver/negotiate.cc +3 -0
- package/deps/lcb/src/n1ql/n1ql.cc +5 -1
- package/deps/lcb/src/n1ql/query_handle.cc +55 -30
- package/deps/lcb/src/n1ql/query_handle.hh +14 -2
- package/deps/lcb/src/operations/counter.cc +12 -0
- package/deps/lcb/src/operations/exists.cc +12 -0
- package/deps/lcb/src/operations/get.cc +12 -0
- package/deps/lcb/src/operations/get_replica.cc +18 -6
- package/deps/lcb/src/operations/remove.cc +12 -0
- package/deps/lcb/src/operations/store.cc +12 -0
- package/deps/lcb/src/operations/subdoc.cc +12 -0
- package/deps/lcb/src/operations/touch.cc +12 -0
- package/deps/lcb/src/operations/unlock.cc +12 -0
- package/deps/lcb/src/search/search_handle.cc +1 -2
- package/deps/lcb/src/ssl/ssl_common.c +1 -1
- package/deps/lcb/src/utilities.cc +21 -0
- package/deps/lcb/src/utilities.h +3 -0
- package/deps/lcb/tests/iotests/mock-environment.cc +10 -1
- package/deps/lcb/tests/iotests/mock-environment.h +2 -1
- package/deps/lcb/tests/iotests/serverparams.h +7 -2
- package/deps/lcb/tests/iotests/t_ratelimit.cc +729 -0
- package/deps/lcb/tests/iotests/testutil.cc +174 -0
- package/deps/lcb/tests/iotests/testutil.h +53 -0
- package/dist/analyticsexecutor.js +2 -2
- package/dist/analyticsindexmanager.js +3 -3
- package/dist/binarycollection.d.ts +17 -0
- package/dist/binding.js +1 -1
- package/dist/bindingutilities.js +5 -1
- package/dist/bucketmanager.d.ts +1 -22
- package/dist/bucketmanager.js +5 -5
- package/dist/cluster.js +1 -1
- package/dist/collection.js +6 -6
- package/dist/collectionmanager.js +2 -2
- package/dist/connection.js +3 -3
- package/dist/connspec.js +5 -1
- package/dist/couchbase.js +5 -1
- package/dist/httpexecutor.js +5 -1
- package/dist/logging.js +1 -1
- package/dist/queryexecutor.js +3 -3
- package/dist/searchindexmanager.js +1 -1
- package/dist/usermanager.js +2 -2
- package/dist/utilities.d.ts +1 -2
- package/dist/utilities.js +9 -2
- package/dist/viewexecutor.js +1 -1
- package/package.json +1 -1
- package/src/uv-plugin-all.cpp +1 -0
- package/dist/cas.d.ts +0 -0
- package/dist/cas.js +0 -1
@@ -95,8 +95,8 @@ static void prepare_rowcb(lcb_INSTANCE *instance, int, const lcb_RESPQUERY *row)
|
|
95
95
|
|
96
96
|
bool lcb_QUERY_HANDLE_::parse_meta(const char *row, size_t row_len, lcb_STATUS &rc)
|
97
97
|
{
|
98
|
-
|
99
|
-
|
98
|
+
first_error.message.clear();
|
99
|
+
first_error.code = 0;
|
100
100
|
|
101
101
|
Json::Value meta;
|
102
102
|
if (!Json::Reader(Json::Features::strictMode()).parse(row, row + row_len, meta)) {
|
@@ -105,22 +105,42 @@ bool lcb_QUERY_HANDLE_::parse_meta(const char *row, size_t row_len, lcb_STATUS &
|
|
105
105
|
const Json::Value &errors = meta["errors"];
|
106
106
|
if (errors.isArray() && !errors.empty()) {
|
107
107
|
const Json::Value &err = errors[0];
|
108
|
+
if (err.isMember("retry") && err["retry"].isBool()) {
|
109
|
+
first_error.retry = err["retry"].asBool();
|
110
|
+
}
|
111
|
+
if (err.isMember("reason") && err["reason"].isObject()) {
|
112
|
+
const Json::Value &reason = err["reason"];
|
113
|
+
if (reason.isMember("code") && reason["code"].isNumeric()) {
|
114
|
+
first_error.reason_code = reason["code"].asInt();
|
115
|
+
}
|
116
|
+
}
|
108
117
|
const Json::Value &msg = err["msg"];
|
109
118
|
if (msg.isString()) {
|
110
|
-
|
119
|
+
first_error.message = msg.asString();
|
111
120
|
}
|
112
121
|
const Json::Value &code = err["code"];
|
113
122
|
if (code.isNumeric()) {
|
114
|
-
|
115
|
-
switch (
|
123
|
+
first_error.code = code.asUInt();
|
124
|
+
switch (first_error.code) {
|
116
125
|
case 3000:
|
117
126
|
rc = LCB_ERR_PARSING_FAILURE;
|
118
127
|
break;
|
119
128
|
case 12009:
|
120
129
|
rc = LCB_ERR_DML_FAILURE;
|
121
|
-
if (
|
130
|
+
if (first_error.message.find("CAS mismatch") != std::string::npos) {
|
122
131
|
rc = LCB_ERR_CAS_MISMATCH;
|
123
132
|
}
|
133
|
+
switch (first_error.reason_code) {
|
134
|
+
case 12033:
|
135
|
+
rc = LCB_ERR_CAS_MISMATCH;
|
136
|
+
break;
|
137
|
+
case 17014:
|
138
|
+
rc = LCB_ERR_DOCUMENT_NOT_FOUND;
|
139
|
+
break;
|
140
|
+
case 17012:
|
141
|
+
rc = LCB_ERR_DOCUMENT_EXISTS;
|
142
|
+
break;
|
143
|
+
}
|
124
144
|
break;
|
125
145
|
case 4040:
|
126
146
|
case 4050:
|
@@ -132,31 +152,34 @@ bool lcb_QUERY_HANDLE_::parse_meta(const char *row, size_t row_len, lcb_STATUS &
|
|
132
152
|
break;
|
133
153
|
case 4300:
|
134
154
|
rc = LCB_ERR_PLANNING_FAILURE;
|
135
|
-
if (!
|
155
|
+
if (!first_error.message.empty()) {
|
136
156
|
std::regex already_exists("index.+already exists");
|
137
|
-
if (std::regex_search(
|
157
|
+
if (std::regex_search(first_error.message, already_exists)) {
|
138
158
|
rc = LCB_ERR_INDEX_EXISTS;
|
139
159
|
}
|
140
160
|
}
|
141
161
|
break;
|
142
162
|
case 5000:
|
143
163
|
rc = LCB_ERR_INTERNAL_SERVER_FAILURE;
|
144
|
-
if (!
|
164
|
+
if (!first_error.message.empty()) {
|
145
165
|
std::regex already_exists("Index.+already exists"); /* NOTE: case sensitive */
|
146
166
|
std::regex not_found("index.+not found");
|
147
|
-
if (std::regex_search(
|
167
|
+
if (std::regex_search(first_error.message, already_exists)) {
|
148
168
|
rc = LCB_ERR_INDEX_EXISTS;
|
149
|
-
} else if (std::regex_search(
|
169
|
+
} else if (std::regex_search(first_error.message, not_found)) {
|
150
170
|
rc = LCB_ERR_INDEX_NOT_FOUND;
|
151
|
-
} else if (
|
171
|
+
} else if (first_error.message.find(
|
152
172
|
"Limit for number of indexes that can be created per scope has been reached") !=
|
153
173
|
std::string::npos) {
|
154
174
|
rc = LCB_ERR_QUOTA_LIMITED;
|
155
175
|
}
|
156
176
|
}
|
157
177
|
break;
|
158
|
-
case 12004:
|
159
178
|
case 12016:
|
179
|
+
/* see MB-50643 */
|
180
|
+
first_error.retry = false;
|
181
|
+
/* fallthrough */
|
182
|
+
case 12004:
|
160
183
|
rc = LCB_ERR_INDEX_NOT_FOUND;
|
161
184
|
break;
|
162
185
|
case 12003:
|
@@ -177,14 +200,14 @@ bool lcb_QUERY_HANDLE_::parse_meta(const char *row, size_t row_len, lcb_STATUS &
|
|
177
200
|
break;
|
178
201
|
|
179
202
|
default:
|
180
|
-
if (
|
203
|
+
if (first_error.code >= 4000 && first_error.code < 5000) {
|
181
204
|
rc = LCB_ERR_PLANNING_FAILURE;
|
182
|
-
} else if (
|
205
|
+
} else if (first_error.code >= 5000 && first_error.code < 6000) {
|
183
206
|
rc = LCB_ERR_INTERNAL_SERVER_FAILURE;
|
184
|
-
} else if (
|
207
|
+
} else if (first_error.code >= 10000 && first_error.code < 11000) {
|
185
208
|
rc = LCB_ERR_AUTHENTICATION_FAILURE;
|
186
|
-
} else if ((
|
187
|
-
(
|
209
|
+
} else if ((first_error.code >= 12000 && first_error.code < 13000) ||
|
210
|
+
(first_error.code >= 14000 && first_error.code < 15000)) {
|
188
211
|
rc = LCB_ERR_INDEX_FAILURE;
|
189
212
|
}
|
190
213
|
break;
|
@@ -218,11 +241,13 @@ void lcb_QUERY_HANDLE_::invoke_row(lcb_RESPQUERY *resp, bool is_last)
|
|
218
241
|
resp->row = static_cast<const char *>(meta_buf.iov_base);
|
219
242
|
resp->nrow = meta_buf.iov_len;
|
220
243
|
parse_meta(resp->row, resp->nrow, resp->ctx.rc);
|
221
|
-
|
222
|
-
|
223
|
-
|
244
|
+
resp->ctx.error_response_body = resp->row;
|
245
|
+
resp->ctx.error_response_body_len = resp->nrow;
|
246
|
+
if (!first_error.message.empty()) {
|
247
|
+
resp->ctx.first_error_message = first_error.message.c_str();
|
248
|
+
resp->ctx.first_error_message_len = first_error.message.size();
|
224
249
|
}
|
225
|
-
resp->ctx.first_error_code =
|
250
|
+
resp->ctx.first_error_code = first_error.code;
|
226
251
|
if (span_ != nullptr) {
|
227
252
|
lcb::trace::finish_http_span(span_, this);
|
228
253
|
span_ = nullptr;
|
@@ -358,27 +383,27 @@ lcb_RETRY_ACTION lcb_QUERY_HANDLE_::has_retriable_error(lcb_STATUS &rc)
|
|
358
383
|
const uint32_t default_backoff = 100 /* ms */;
|
359
384
|
if (rc == LCB_ERR_PREPARED_STATEMENT_FAILURE) {
|
360
385
|
lcb_log(LOGARGS(this, TRACE), LOGFMT "Will retry request. rc: %s, code: %d, msg: %s", LOGID(this),
|
361
|
-
lcb_strerror_short(rc),
|
386
|
+
lcb_strerror_short(rc), first_error.code, first_error.message.c_str());
|
362
387
|
return {1, default_backoff};
|
363
388
|
}
|
364
|
-
if (
|
389
|
+
if (first_error.code == 13014 &&
|
365
390
|
LCBT_SETTING(instance_, auth)->mode() == LCBAUTH_MODE_DYNAMIC) { // datastore.couchbase.insufficient_credentials
|
366
391
|
auto result = request_credentials(LCBAUTH_REASON_AUTHENTICATION_FAILURE);
|
367
392
|
bool credentials_found = result == LCBAUTH_RESULT_OK;
|
368
393
|
lcb_log(LOGARGS(this, TRACE),
|
369
394
|
LOGFMT "Invalidate credentials and retry request. creds: %s, rc: %s, code: %d, msg: %s", LOGID(this),
|
370
|
-
credentials_found ? "ok" : "not_found", lcb_strerror_short(rc),
|
371
|
-
|
395
|
+
credentials_found ? "ok" : "not_found", lcb_strerror_short(rc), first_error.code,
|
396
|
+
first_error.message.c_str());
|
372
397
|
return {credentials_found, default_backoff};
|
373
398
|
}
|
374
|
-
if (!
|
399
|
+
if (!first_error.message.empty()) {
|
375
400
|
for (const auto &magic_string : wtf_magic_strings) {
|
376
|
-
if (
|
401
|
+
if (first_error.message.find(magic_string) != std::string::npos) {
|
377
402
|
lcb_log(LOGARGS(this, TRACE),
|
378
403
|
LOGFMT
|
379
404
|
"Special error message detected. Will retry request. rc: %s (update to %s), code: %d, msg: %s",
|
380
405
|
LOGID(this), lcb_strerror_short(rc), lcb_strerror_short(LCB_ERR_PREPARED_STATEMENT_FAILURE),
|
381
|
-
|
406
|
+
first_error.code, first_error.message.c_str());
|
382
407
|
rc = LCB_ERR_PREPARED_STATEMENT_FAILURE;
|
383
408
|
return {1, default_backoff};
|
384
409
|
}
|
@@ -388,7 +413,7 @@ lcb_RETRY_ACTION lcb_QUERY_HANDLE_::has_retriable_error(lcb_STATUS &rc)
|
|
388
413
|
if (rc == LCB_SUCCESS) {
|
389
414
|
return {0, 0};
|
390
415
|
}
|
391
|
-
return lcb_query_should_retry(instance_->settings, this, rc);
|
416
|
+
return lcb_query_should_retry(instance_->settings, this, rc, first_error.retry);
|
392
417
|
}
|
393
418
|
|
394
419
|
lcb_STATUS lcb_QUERY_HANDLE_::issue_htreq(const std::string &body)
|
@@ -27,6 +27,19 @@
|
|
27
27
|
#include "capi/cmd_query.hh"
|
28
28
|
#include "query_cache.hh"
|
29
29
|
|
30
|
+
/**
|
31
|
+
* @private
|
32
|
+
*/
|
33
|
+
namespace lcb
|
34
|
+
{
|
35
|
+
struct query_error {
|
36
|
+
std::string message{};
|
37
|
+
uint32_t code{};
|
38
|
+
bool retry{false};
|
39
|
+
uint32_t reason_code{0};
|
40
|
+
};
|
41
|
+
} // namespace lcb
|
42
|
+
|
30
43
|
/**
|
31
44
|
* @private
|
32
45
|
*/
|
@@ -296,8 +309,7 @@ struct lcb_QUERY_HANDLE_ : lcb::jsparse::Parser::Actions {
|
|
296
309
|
/** String of the original statement. Cached here to avoid jsoncpp lookups */
|
297
310
|
std::string statement_;
|
298
311
|
std::string client_context_id_;
|
299
|
-
|
300
|
-
uint32_t first_error_code{};
|
312
|
+
lcb::query_error first_error{};
|
301
313
|
|
302
314
|
/** Whether we're retrying this */
|
303
315
|
int retries_{0};
|
@@ -141,6 +141,12 @@ LIBCOUCHBASE_API lcb_STATUS lcb_cmdcounter_on_behalf_of(lcb_CMDCOUNTER *cmd, con
|
|
141
141
|
return cmd->on_behalf_of(std::string(data, data_len));
|
142
142
|
}
|
143
143
|
|
144
|
+
LIBCOUCHBASE_API lcb_STATUS lcb_cmdcounter_on_behalf_of_extra_privilege(lcb_CMDCOUNTER *cmd, const char *privilege,
|
145
|
+
size_t privilege_len)
|
146
|
+
{
|
147
|
+
return cmd->on_behalf_of_add_extra_privilege(std::string(privilege, privilege_len));
|
148
|
+
}
|
149
|
+
|
144
150
|
static lcb_STATUS counter_validate(lcb_INSTANCE *instance, const lcb_CMDCOUNTER *cmd)
|
145
151
|
{
|
146
152
|
if (cmd->key().empty()) {
|
@@ -184,6 +190,12 @@ static lcb_STATUS counter_schedule(lcb_INSTANCE *instance, std::shared_ptr<lcb_C
|
|
184
190
|
if (err != LCB_SUCCESS) {
|
185
191
|
return err;
|
186
192
|
}
|
193
|
+
for (const auto &privilege : cmd->extra_privileges()) {
|
194
|
+
err = lcb::flexible_framing_extras::encode_impersonate_users_extra_privilege(privilege, framing_extras);
|
195
|
+
if (err != LCB_SUCCESS) {
|
196
|
+
return err;
|
197
|
+
}
|
198
|
+
}
|
187
199
|
}
|
188
200
|
|
189
201
|
hdr.request.magic = framing_extras.empty() ? PROTOCOL_BINARY_REQ : PROTOCOL_BINARY_AREQ;
|
@@ -112,6 +112,12 @@ LIBCOUCHBASE_API lcb_STATUS lcb_cmdexists_on_behalf_of(lcb_CMDEXISTS *cmd, const
|
|
112
112
|
return cmd->on_behalf_of(std::string(data, data_len));
|
113
113
|
}
|
114
114
|
|
115
|
+
LIBCOUCHBASE_API lcb_STATUS lcb_cmdexists_on_behalf_of_extra_privilege(lcb_CMDEXISTS *cmd, const char *privilege,
|
116
|
+
size_t privilege_len)
|
117
|
+
{
|
118
|
+
return cmd->on_behalf_of_add_extra_privilege(std::string(privilege, privilege_len));
|
119
|
+
}
|
120
|
+
|
115
121
|
static lcb_STATUS exists_validate(lcb_INSTANCE *instance, const lcb_CMDEXISTS *cmd)
|
116
122
|
{
|
117
123
|
if (cmd->key().empty()) {
|
@@ -139,6 +145,12 @@ static lcb_STATUS exists_schedule(lcb_INSTANCE *instance, std::shared_ptr<lcb_CM
|
|
139
145
|
if (err != LCB_SUCCESS) {
|
140
146
|
return err;
|
141
147
|
}
|
148
|
+
for (const auto &privilege : cmd->extra_privileges()) {
|
149
|
+
err = lcb::flexible_framing_extras::encode_impersonate_users_extra_privilege(privilege, framing_extras);
|
150
|
+
if (err != LCB_SUCCESS) {
|
151
|
+
return err;
|
152
|
+
}
|
153
|
+
}
|
142
154
|
}
|
143
155
|
|
144
156
|
hdr.request.magic = framing_extras.empty() ? PROTOCOL_BINARY_REQ : PROTOCOL_BINARY_AREQ;
|
@@ -129,6 +129,12 @@ LIBCOUCHBASE_API lcb_STATUS lcb_cmdget_on_behalf_of(lcb_CMDGET *cmd, const char
|
|
129
129
|
return cmd->on_behalf_of(std::string(data, data_len));
|
130
130
|
}
|
131
131
|
|
132
|
+
LIBCOUCHBASE_API lcb_STATUS lcb_cmdget_on_behalf_of_extra_privilege(lcb_CMDGET *cmd, const char *privilege,
|
133
|
+
size_t privilege_len)
|
134
|
+
{
|
135
|
+
return cmd->on_behalf_of_add_extra_privilege(std::string(privilege, privilege_len));
|
136
|
+
}
|
137
|
+
|
132
138
|
static lcb_STATUS get_validate(lcb_INSTANCE *instance, const lcb_CMDGET *cmd)
|
133
139
|
{
|
134
140
|
if (cmd->key().empty()) {
|
@@ -159,6 +165,12 @@ static lcb_STATUS get_schedule(lcb_INSTANCE *instance, std::shared_ptr<lcb_CMDGE
|
|
159
165
|
if (err != LCB_SUCCESS) {
|
160
166
|
return err;
|
161
167
|
}
|
168
|
+
for (const auto &privilege : cmd->extra_privileges()) {
|
169
|
+
err = lcb::flexible_framing_extras::encode_impersonate_users_extra_privilege(privilege, framing_extras);
|
170
|
+
if (err != LCB_SUCCESS) {
|
171
|
+
return err;
|
172
|
+
}
|
173
|
+
}
|
162
174
|
}
|
163
175
|
|
164
176
|
hdr.request.magic = framing_extras.empty() ? PROTOCOL_BINARY_REQ : PROTOCOL_BINARY_AREQ;
|
@@ -144,6 +144,12 @@ LIBCOUCHBASE_API lcb_STATUS lcb_cmdgetreplica_on_behalf_of(lcb_CMDGETREPLICA *cm
|
|
144
144
|
return cmd->on_behalf_of(std::string(data, data_len));
|
145
145
|
}
|
146
146
|
|
147
|
+
LIBCOUCHBASE_API lcb_STATUS lcb_cmdgetreplica_on_behalf_of_extra_privilege(lcb_CMDGETREPLICA *cmd,
|
148
|
+
const char *privilege, size_t privilege_len)
|
149
|
+
{
|
150
|
+
return cmd->on_behalf_of_add_extra_privilege(std::string(privilege, privilege_len));
|
151
|
+
}
|
152
|
+
|
147
153
|
struct RGetCookie : mc_REQDATAEX {
|
148
154
|
RGetCookie(void *cookie, lcb_INSTANCE *instance, get_replica_mode, int vb);
|
149
155
|
void decref()
|
@@ -349,20 +355,26 @@ static lcb_STATUS get_replica_schedule(lcb_INSTANCE *instance, std::shared_ptr<l
|
|
349
355
|
return LCB_ERR_NO_MATCHING_SERVER;
|
350
356
|
}
|
351
357
|
|
352
|
-
/* Initialize the cookie */
|
353
|
-
auto *rck = new RGetCookie(cmd->cookie(), instance, cmd->mode(), vbid);
|
354
|
-
rck->start = cmd->start_time_or_default_in_nanoseconds(gethrtime());
|
355
|
-
rck->deadline =
|
356
|
-
rck->start + cmd->timeout_or_default_in_nanoseconds(LCB_US2NS(LCBT_SETTING(instance, operation_timeout)));
|
357
|
-
|
358
358
|
std::vector<std::uint8_t> framing_extras;
|
359
359
|
if (cmd->want_impersonation()) {
|
360
360
|
lcb_STATUS err = lcb::flexible_framing_extras::encode_impersonate_user(cmd->impostor(), framing_extras);
|
361
361
|
if (err != LCB_SUCCESS) {
|
362
362
|
return err;
|
363
363
|
}
|
364
|
+
for (const auto &privilege : cmd->extra_privileges()) {
|
365
|
+
err = lcb::flexible_framing_extras::encode_impersonate_users_extra_privilege(privilege, framing_extras);
|
366
|
+
if (err != LCB_SUCCESS) {
|
367
|
+
return err;
|
368
|
+
}
|
369
|
+
}
|
364
370
|
}
|
365
371
|
|
372
|
+
/* Initialize the cookie */
|
373
|
+
auto *rck = new RGetCookie(cmd->cookie(), instance, cmd->mode(), vbid);
|
374
|
+
rck->start = cmd->start_time_or_default_in_nanoseconds(gethrtime());
|
375
|
+
rck->deadline =
|
376
|
+
rck->start + cmd->timeout_or_default_in_nanoseconds(LCB_US2NS(LCBT_SETTING(instance, operation_timeout)));
|
377
|
+
|
366
378
|
/* Initialize the packet */
|
367
379
|
req.request.magic = framing_extras.empty() ? PROTOCOL_BINARY_REQ : PROTOCOL_BINARY_AREQ;
|
368
380
|
req.request.opcode = PROTOCOL_BINARY_CMD_GET_REPLICA;
|
@@ -117,6 +117,12 @@ LIBCOUCHBASE_API lcb_STATUS lcb_cmdremove_on_behalf_of(lcb_CMDREMOVE *cmd, const
|
|
117
117
|
return cmd->on_behalf_of(std::string(data, data_len));
|
118
118
|
}
|
119
119
|
|
120
|
+
LIBCOUCHBASE_API lcb_STATUS lcb_cmdremove_on_behalf_of_extra_privilege(lcb_CMDREMOVE *cmd, const char *privilege,
|
121
|
+
size_t privilege_len)
|
122
|
+
{
|
123
|
+
return cmd->on_behalf_of_add_extra_privilege(std::string(privilege, privilege_len));
|
124
|
+
}
|
125
|
+
|
120
126
|
static lcb_STATUS remove_validate(lcb_INSTANCE *instance, const lcb_CMDREMOVE *cmd)
|
121
127
|
{
|
122
128
|
if (cmd->key().empty()) {
|
@@ -159,6 +165,12 @@ static lcb_STATUS remove_schedule(lcb_INSTANCE *instance, std::shared_ptr<lcb_CM
|
|
159
165
|
if (err != LCB_SUCCESS) {
|
160
166
|
return err;
|
161
167
|
}
|
168
|
+
for (const auto &privilege : cmd->extra_privileges()) {
|
169
|
+
err = lcb::flexible_framing_extras::encode_impersonate_users_extra_privilege(privilege, framing_extras);
|
170
|
+
if (err != LCB_SUCCESS) {
|
171
|
+
return err;
|
172
|
+
}
|
173
|
+
}
|
162
174
|
}
|
163
175
|
|
164
176
|
hdr.request.magic = framing_extras.empty() ? PROTOCOL_BINARY_REQ : PROTOCOL_BINARY_AREQ;
|
@@ -234,6 +234,12 @@ LIBCOUCHBASE_API lcb_STATUS lcb_cmdstore_on_behalf_of(lcb_CMDSTORE *cmd, const c
|
|
234
234
|
return cmd->on_behalf_of(std::string(data, data_len));
|
235
235
|
}
|
236
236
|
|
237
|
+
LIBCOUCHBASE_API lcb_STATUS lcb_cmdstore_on_behalf_of_extra_privilege(lcb_CMDSTORE *cmd, const char *privilege,
|
238
|
+
size_t privilege_len)
|
239
|
+
{
|
240
|
+
return cmd->on_behalf_of_add_extra_privilege(std::string(privilege, privilege_len));
|
241
|
+
}
|
242
|
+
|
237
243
|
struct DurStoreCtx : mc_REQDATAEX {
|
238
244
|
lcb_INSTANCE *instance;
|
239
245
|
lcb_U16 persist_to;
|
@@ -400,6 +406,12 @@ static lcb_STATUS store_schedule(lcb_INSTANCE *instance, std::shared_ptr<lcb_CMD
|
|
400
406
|
if (err != LCB_SUCCESS) {
|
401
407
|
return err;
|
402
408
|
}
|
409
|
+
for (const auto &privilege : cmd->extra_privileges()) {
|
410
|
+
err = lcb::flexible_framing_extras::encode_impersonate_users_extra_privilege(privilege, framing_extras);
|
411
|
+
if (err != LCB_SUCCESS) {
|
412
|
+
return err;
|
413
|
+
}
|
414
|
+
}
|
403
415
|
}
|
404
416
|
auto ffextlen = static_cast<std::uint8_t>(framing_extras.size());
|
405
417
|
hdr.request.magic = (ffextlen == 0) ? PROTOCOL_BINARY_REQ : PROTOCOL_BINARY_AREQ;
|
@@ -409,6 +409,12 @@ LIBCOUCHBASE_API lcb_STATUS lcb_cmdsubdoc_on_behalf_of(lcb_CMDSUBDOC *cmd, const
|
|
409
409
|
return cmd->on_behalf_of(std::string(data, data_len));
|
410
410
|
}
|
411
411
|
|
412
|
+
LIBCOUCHBASE_API lcb_STATUS lcb_cmdsubdoc_on_behalf_of_extra_privilege(lcb_CMDSUBDOC *cmd, const char *privilege,
|
413
|
+
size_t privilege_len)
|
414
|
+
{
|
415
|
+
return cmd->on_behalf_of_add_extra_privilege(std::string(privilege, privilege_len));
|
416
|
+
}
|
417
|
+
|
412
418
|
namespace SubdocCmdTraits
|
413
419
|
{
|
414
420
|
enum Options {
|
@@ -798,6 +804,12 @@ static lcb_STATUS subdoc_schedule(lcb_INSTANCE *instance, std::shared_ptr<lcb_CM
|
|
798
804
|
if (rc != LCB_SUCCESS) {
|
799
805
|
return rc;
|
800
806
|
}
|
807
|
+
for (const auto &privilege : cmd->extra_privileges()) {
|
808
|
+
rc = lcb::flexible_framing_extras::encode_impersonate_users_extra_privilege(privilege, framing_extras);
|
809
|
+
if (rc != LCB_SUCCESS) {
|
810
|
+
return rc;
|
811
|
+
}
|
812
|
+
}
|
801
813
|
}
|
802
814
|
hdr.request.magic = framing_extras.empty() ? PROTOCOL_BINARY_REQ : PROTOCOL_BINARY_AREQ;
|
803
815
|
auto ffextlen = static_cast<std::uint8_t>(framing_extras.size());
|
@@ -117,6 +117,12 @@ LIBCOUCHBASE_API lcb_STATUS lcb_cmdtouch_on_behalf_of(lcb_CMDTOUCH *cmd, const c
|
|
117
117
|
return cmd->on_behalf_of(std::string(data, data_len));
|
118
118
|
}
|
119
119
|
|
120
|
+
LIBCOUCHBASE_API lcb_STATUS lcb_cmdtouch_on_behalf_of_extra_privilege(lcb_CMDTOUCH *cmd, const char *privilege,
|
121
|
+
size_t privilege_len)
|
122
|
+
{
|
123
|
+
return cmd->on_behalf_of_add_extra_privilege(std::string(privilege, privilege_len));
|
124
|
+
}
|
125
|
+
|
120
126
|
static lcb_STATUS touch_validate(lcb_INSTANCE *instance, const lcb_CMDTOUCH *cmd)
|
121
127
|
{
|
122
128
|
if (cmd->key().empty()) {
|
@@ -142,6 +148,12 @@ static lcb_STATUS touch_schedule(lcb_INSTANCE *instance, std::shared_ptr<lcb_CMD
|
|
142
148
|
if (err != LCB_SUCCESS) {
|
143
149
|
return err;
|
144
150
|
}
|
151
|
+
for (const auto &privilege : cmd->extra_privileges()) {
|
152
|
+
err = lcb::flexible_framing_extras::encode_impersonate_users_extra_privilege(privilege, framing_extras);
|
153
|
+
if (err != LCB_SUCCESS) {
|
154
|
+
return err;
|
155
|
+
}
|
156
|
+
}
|
145
157
|
}
|
146
158
|
|
147
159
|
hdr.request.magic = framing_extras.empty() ? PROTOCOL_BINARY_REQ : PROTOCOL_BINARY_AREQ;
|
@@ -106,6 +106,12 @@ LIBCOUCHBASE_API lcb_STATUS lcb_cmdunlock_on_behalf_of(lcb_CMDUNLOCK *cmd, const
|
|
106
106
|
return cmd->on_behalf_of(std::string(data, data_len));
|
107
107
|
}
|
108
108
|
|
109
|
+
LIBCOUCHBASE_API lcb_STATUS lcb_cmdunlock_on_behalf_of_extra_privilege(lcb_CMDUNLOCK *cmd, const char *privilege,
|
110
|
+
size_t privilege_len)
|
111
|
+
{
|
112
|
+
return cmd->on_behalf_of_add_extra_privilege(std::string(privilege, privilege_len));
|
113
|
+
}
|
114
|
+
|
109
115
|
static lcb_STATUS unlock_validate(lcb_INSTANCE *instance, const lcb_CMDUNLOCK *cmd)
|
110
116
|
{
|
111
117
|
if (cmd->key().empty()) {
|
@@ -137,6 +143,12 @@ static lcb_STATUS unlock_schedule(lcb_INSTANCE *instance, std::shared_ptr<lcb_CM
|
|
137
143
|
if (err != LCB_SUCCESS) {
|
138
144
|
return err;
|
139
145
|
}
|
146
|
+
for (const auto &privilege : cmd->extra_privileges()) {
|
147
|
+
err = lcb::flexible_framing_extras::encode_impersonate_users_extra_privilege(privilege, framing_extras);
|
148
|
+
if (err != LCB_SUCCESS) {
|
149
|
+
return err;
|
150
|
+
}
|
151
|
+
}
|
140
152
|
}
|
141
153
|
|
142
154
|
hdr.request.magic = framing_extras.empty() ? PROTOCOL_BINARY_REQ : PROTOCOL_BINARY_AREQ;
|
@@ -97,8 +97,7 @@ void lcb_SEARCH_HANDLE_::invoke_row(lcb_RESPSEARCH *resp)
|
|
97
97
|
} else if (resp->ctx.http_response_code == 400) {
|
98
98
|
if (error_message_.find("not_found") != std::string::npos) {
|
99
99
|
resp->ctx.rc = LCB_ERR_INDEX_NOT_FOUND;
|
100
|
-
} else if (error_message_.find("
|
101
|
-
std::string::npos) {
|
100
|
+
} else if (error_message_.find("num_fts_indexes") != std::string::npos) {
|
102
101
|
resp->ctx.rc = LCB_ERR_QUOTA_LIMITED;
|
103
102
|
}
|
104
103
|
} else if (resp->ctx.http_response_code == 429) {
|
@@ -359,7 +359,7 @@ lcbio_pSSLCTX lcbio_ssl_new(const char *tsfile, const char *cafile, const char *
|
|
359
359
|
}
|
360
360
|
if (cafile && keyfile) {
|
361
361
|
lcb_log(LOGARGS_S(settings, LCB_LOG_DEBUG), "Authenticate with key \"%s\", cert \"%s\"", keyfile, cafile);
|
362
|
-
if (!
|
362
|
+
if (!SSL_CTX_use_certificate_chain_file(ret->ctx, cafile)) {
|
363
363
|
*errp = LCB_ERR_SSL_ERROR;
|
364
364
|
goto GT_ERR;
|
365
365
|
}
|
@@ -214,3 +214,24 @@ lcb_STATUS lcb::flexible_framing_extras::encode_impersonate_user(const std::stri
|
|
214
214
|
}
|
215
215
|
return LCB_SUCCESS;
|
216
216
|
}
|
217
|
+
|
218
|
+
lcb_STATUS lcb::flexible_framing_extras::encode_impersonate_users_extra_privilege(
|
219
|
+
const std::string &privilege, std::vector<std::uint8_t> &flexible_framing_extras)
|
220
|
+
{
|
221
|
+
auto privilege_len = privilege.size();
|
222
|
+
if (privilege_len > std::numeric_limits<std::uint8_t>::max() + 0xfU) {
|
223
|
+
return LCB_ERR_INVALID_ARGUMENT;
|
224
|
+
}
|
225
|
+
std::uint8_t frame_id = 0x06;
|
226
|
+
if (privilege_len < 15) {
|
227
|
+
auto frame_size = static_cast<std::uint8_t>(privilege_len);
|
228
|
+
flexible_framing_extras.emplace_back(frame_id << 4U | frame_size);
|
229
|
+
} else {
|
230
|
+
flexible_framing_extras.emplace_back(frame_id << 4U | 0xfU);
|
231
|
+
flexible_framing_extras.emplace_back(privilege_len - 0xfU);
|
232
|
+
}
|
233
|
+
for (const auto byte : privilege) {
|
234
|
+
flexible_framing_extras.emplace_back(byte);
|
235
|
+
}
|
236
|
+
return LCB_SUCCESS;
|
237
|
+
}
|
package/deps/lcb/src/utilities.h
CHANGED
@@ -29,6 +29,9 @@ namespace lcb
|
|
29
29
|
namespace flexible_framing_extras
|
30
30
|
{
|
31
31
|
lcb_STATUS encode_impersonate_user(const std::string &username, std::vector<std::uint8_t> &flexible_framing_extras);
|
32
|
+
|
33
|
+
lcb_STATUS encode_impersonate_users_extra_privilege(const std::string &privilege,
|
34
|
+
std::vector<std::uint8_t> &flexible_framing_extras);
|
32
35
|
} // namespace flexible_framing_extras
|
33
36
|
} // namespace lcb
|
34
37
|
|
@@ -423,7 +423,16 @@ static void statsCallback(lcb_INSTANCE *instance, lcb_CALLBACK_TYPE, const lcb_R
|
|
423
423
|
}
|
424
424
|
break;
|
425
425
|
case 7:
|
426
|
-
|
426
|
+
switch (minor) {
|
427
|
+
case 0:
|
428
|
+
version = MockEnvironment::VERSION_70;
|
429
|
+
break;
|
430
|
+
case 1:
|
431
|
+
version = MockEnvironment::VERSION_71;
|
432
|
+
break;
|
433
|
+
default:
|
434
|
+
break;
|
435
|
+
}
|
427
436
|
break;
|
428
437
|
default:
|
429
438
|
break;
|
@@ -37,10 +37,15 @@ class ServerParams
|
|
37
37
|
void makeConnectParams(lcb_CREATEOPTS *&crst, lcb_io_opt_t io, lcb_INSTANCE_TYPE type = LCB_TYPE_BUCKET)
|
38
38
|
{
|
39
39
|
lcb_createopts_create(&crst, type);
|
40
|
-
if (host.find("couchbase
|
40
|
+
if (host.find("couchbase") == 0) {
|
41
41
|
connstr = host;
|
42
42
|
// deactivate dnssrv and compression, use cccp bootstrap
|
43
|
-
|
43
|
+
if (host.find("?") == std::string::npos) {
|
44
|
+
connstr += "?";
|
45
|
+
} else {
|
46
|
+
connstr += "&";
|
47
|
+
}
|
48
|
+
connstr += "dnssrv=off&bootstrap_on=cccp&compression=off";
|
44
49
|
} else {
|
45
50
|
if (mcNodes.empty() || type == LCB_TYPE_CLUSTER) {
|
46
51
|
connstr = "couchbase://" + host + "=http";
|