couchbase 3.2.5 → 3.2.7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. package/deps/lcb/CMakeLists.txt +28 -6
  2. package/deps/lcb/README.markdown +5 -9
  3. package/deps/lcb/RELEASE_NOTES.markdown +80 -12
  4. package/deps/lcb/cmake/Modules/GetVersionInfo.cmake +1 -1
  5. package/deps/lcb/doc/Doxyfile +1 -1
  6. package/deps/lcb/doc/cbc.markdown +10 -0
  7. package/deps/lcb/gyp_config/common/libcouchbase/configuration.h +3 -3
  8. package/deps/lcb/include/libcouchbase/error.h +1 -1
  9. package/deps/lcb/packaging/rpm/libcouchbase.spec.in +1 -1
  10. package/deps/lcb/plugins/io/iocp/iocp_iops.h +1 -1
  11. package/deps/lcb/plugins/io/iocp/iocp_loop.c +3 -3
  12. package/deps/lcb/plugins/io/iocp/iocp_util.c +2 -2
  13. package/deps/lcb/src/bucketconfig/bc_file.cc +29 -15
  14. package/deps/lcb/src/capi/collection_qualifier.hh +0 -3
  15. package/deps/lcb/src/instance.cc +19 -0
  16. package/deps/lcb/src/mcserver/mcserver.cc +5 -0
  17. package/deps/lcb/src/operations/ping.cc +2 -2
  18. package/deps/lcb/src/settings.cc +1 -0
  19. package/deps/lcb/src/ssl/ssl_common.c +111 -22
  20. package/deps/lcb/src/vbucket/vbucket.c +16 -7
  21. package/deps/lcb/tests/CMakeLists.txt +1 -1
  22. package/deps/lcb/tests/ioserver/ssl_connection.cc +8 -5
  23. package/deps/lcb/tests/iotests/mock-environment.cc +3 -0
  24. package/deps/lcb/tests/iotests/mock-environment.h +1 -0
  25. package/deps/lcb/tests/iotests/t_ratelimit.cc +11 -1
  26. package/deps/lcb/tools/CMakeLists.txt +1 -1
  27. package/deps/lcb/tools/cbc-handlers.h +39 -0
  28. package/deps/lcb/tools/cbc-n1qlback.cc +1 -0
  29. package/deps/lcb/tools/cbc-pillowfight.cc +45 -35
  30. package/deps/lcb/tools/cbc.cc +31 -0
  31. package/deps/lcb/tools/docgen/docgen.h +11 -10
  32. package/dist/authenticators.d.ts +1 -1
  33. package/dist/binding.d.ts +5 -5
  34. package/dist/cluster.js +6 -6
  35. package/dist/collection.js +6 -6
  36. package/dist/connection.d.ts +2 -2
  37. package/dist/httpexecutor.d.ts +1 -0
  38. package/dist/scope.js +6 -6
  39. package/dist/sdspecs.js +11 -11
  40. package/dist/searchquery.d.ts +1 -1
  41. package/dist/streamablepromises.d.ts +1 -1
  42. package/dist/usermanager.js +9 -9
  43. package/dist/utilities.d.ts +1 -1
  44. package/dist/viewindexmanager.js +8 -8
  45. package/package.json +1 -1
@@ -32,6 +32,26 @@
32
32
  #define LOGARGS(ssl, lvl) ((lcbio_SOCKET *)SSL_get_app_data(ssl))->settings, "SSL", lvl, __FILE__, __LINE__
33
33
  static char *global_event = "dummy event for ssl";
34
34
 
35
+ static const char *capella_ca_cert = "-----BEGIN CERTIFICATE-----\n"
36
+ "MIIDFTCCAf2gAwIBAgIRANLVkgOvtaXiQJi0V6qeNtswDQYJKoZIhvcNAQELBQAw\n"
37
+ "JDESMBAGA1UECgwJQ291Y2hiYXNlMQ4wDAYDVQQLDAVDbG91ZDAeFw0xOTEyMDYy\n"
38
+ "MjEyNTlaFw0yOTEyMDYyMzEyNTlaMCQxEjAQBgNVBAoMCUNvdWNoYmFzZTEOMAwG\n"
39
+ "A1UECwwFQ2xvdWQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCfvOIi\n"
40
+ "enG4Dp+hJu9asdxEMRmH70hDyMXv5ZjBhbo39a42QwR59y/rC/sahLLQuNwqif85\n"
41
+ "Fod1DkqgO6Ng3vecSAwyYVkj5NKdycQu5tzsZkghlpSDAyI0xlIPSQjoORA/pCOU\n"
42
+ "WOpymA9dOjC1bo6rDyw0yWP2nFAI/KA4Z806XeqLREuB7292UnSsgFs4/5lqeil6\n"
43
+ "rL3ooAw/i0uxr/TQSaxi1l8t4iMt4/gU+W52+8Yol0JbXBTFX6itg62ppb/Eugmn\n"
44
+ "mQRMgL67ccZs7cJ9/A0wlXencX2ohZQOR3mtknfol3FH4+glQFn27Q4xBCzVkY9j\n"
45
+ "KQ20T1LgmGSngBInAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYE\n"
46
+ "FJQOBPvrkU2In1Sjoxt97Xy8+cKNMA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG9w0B\n"
47
+ "AQsFAAOCAQEARgM6XwcXPLSpFdSf0w8PtpNGehmdWijPM3wHb7WZiS47iNen3oq8\n"
48
+ "m2mm6V3Z57wbboPpfI+VEzbhiDcFfVnK1CXMC0tkF3fnOG1BDDvwt4jU95vBiNjY\n"
49
+ "xdzlTP/Z+qr0cnVbGBSZ+fbXstSiRaaAVcqQyv3BRvBadKBkCyPwo+7svQnScQ5P\n"
50
+ "Js7HEHKVms5tZTgKIw1fbmgR2XHleah1AcANB+MAPBCcTgqurqr5G7W2aPSBLLGA\n"
51
+ "fRIiVzm7VFLc7kWbp7ENH39HVG6TZzKnfl9zJYeiklo5vQQhGSMhzBsO70z4RRzi\n"
52
+ "DPFAN/4qZAgD5q3AFNIq2WWADFQGSwVJhg==\n"
53
+ "-----END CERTIFICATE-----\n";
54
+
35
55
  /******************************************************************************
36
56
  ******************************************************************************
37
57
  ** Boilerplate lcbio_TABLE Wrappers **
@@ -221,6 +241,9 @@ static void log_callback(const SSL *ssl, int where, int ret)
221
241
  {
222
242
  int should_log = 0;
223
243
  lcbio_SOCKET *sock = SSL_get_app_data(ssl);
244
+ if (sock == NULL) {
245
+ return;
246
+ }
224
247
  /* Ignore low-level SSL stuff */
225
248
 
226
249
  if (where & SSL_CB_ALERT) {
@@ -298,6 +321,48 @@ static long decode_ssl_protocol(const char *protocol)
298
321
  return disallow;
299
322
  }
300
323
 
324
+ static lcb_STATUS add_certificate_authority(const lcb_settings *settings, SSL_CTX *ctx, const char *certificate_value,
325
+ int certificate_length)
326
+ {
327
+ lcb_STATUS rc = LCB_SUCCESS;
328
+ ERR_clear_error();
329
+
330
+ BIO *bio = BIO_new_mem_buf(certificate_value, certificate_length);
331
+ if (bio) {
332
+ X509_STORE *store = SSL_CTX_get_cert_store(ctx);
333
+ if (store) {
334
+ for (int added = 0;; added = 1) {
335
+ X509 *cert = PEM_read_bio_X509(bio, 0, 0, 0);
336
+ if (!cert) {
337
+ unsigned long err = ERR_get_error();
338
+ if (added && ERR_GET_LIB(err) == ERR_LIB_PEM && ERR_GET_REASON(err) == PEM_R_NO_START_LINE) {
339
+ break;
340
+ }
341
+ lcb_log(LOGARGS_S(settings, LCB_LOG_ERROR),
342
+ "Unable to load default certificate: lib=%s, func=%s, reason=%s", ERR_lib_error_string(err),
343
+ ERR_func_error_string(err), ERR_reason_error_string(err));
344
+ rc = LCB_ERR_SSL_ERROR;
345
+ goto GT_CLEANUP;
346
+ }
347
+
348
+ int ok = X509_STORE_add_cert(store, cert);
349
+ X509_free(cert);
350
+ if (ok != 1) {
351
+ unsigned long err = ERR_get_error();
352
+ lcb_log(LOGARGS_S(settings, LCB_LOG_ERROR),
353
+ "Unable to add default certificate: lib=%s, func=%s, reason=%s", ERR_lib_error_string(err),
354
+ ERR_func_error_string(err), ERR_reason_error_string(err));
355
+ rc = LCB_ERR_SSL_ERROR;
356
+ goto GT_CLEANUP;
357
+ }
358
+ }
359
+ }
360
+ }
361
+ GT_CLEANUP:
362
+ BIO_free(bio);
363
+ return rc;
364
+ }
365
+
301
366
  lcbio_pSSLCTX lcbio_ssl_new(const char *tsfile, const char *cafile, const char *keyfile, int noverify, lcb_STATUS *errp,
302
367
  lcb_settings *settings)
303
368
  {
@@ -351,28 +416,41 @@ lcbio_pSSLCTX lcbio_ssl_new(const char *tsfile, const char *cafile, const char *
351
416
  }
352
417
  #endif
353
418
 
354
- if (cafile || tsfile) {
419
+ if (tsfile) {
355
420
  lcb_log(LOGARGS_S(settings, LCB_LOG_DEBUG), "Load verify locations from \"%s\"", tsfile ? tsfile : cafile);
356
421
  if (!SSL_CTX_load_verify_locations(ret->ctx, tsfile ? tsfile : cafile, NULL)) {
357
422
  *errp = LCB_ERR_SSL_ERROR;
358
423
  goto GT_ERR;
359
424
  }
360
- if (cafile && keyfile) {
361
- lcb_log(LOGARGS_S(settings, LCB_LOG_DEBUG), "Authenticate with key \"%s\", cert \"%s\"", keyfile, cafile);
362
- if (!SSL_CTX_use_certificate_chain_file(ret->ctx, cafile)) {
363
- *errp = LCB_ERR_SSL_ERROR;
364
- goto GT_ERR;
365
- }
366
- if (!SSL_CTX_use_PrivateKey_file(ret->ctx, keyfile, SSL_FILETYPE_PEM)) {
367
- lcb_log(LOGARGS_S(settings, LCB_LOG_ERROR), "Unable to load private key \"%s\"", keyfile);
368
- *errp = LCB_ERR_SSL_ERROR;
369
- goto GT_ERR;
370
- }
371
- if (!SSL_CTX_check_private_key(ret->ctx)) {
372
- lcb_log(LOGARGS_S(settings, LCB_LOG_ERROR), "Unable to verify private key \"%s\"", keyfile);
373
- *errp = LCB_ERR_SSL_ERROR;
374
- goto GT_ERR;
375
- }
425
+ } else {
426
+ lcb_log(LOGARGS_S(settings, LCB_LOG_DEBUG), "Use default CA for TLS verify");
427
+ if (SSL_CTX_set_default_verify_paths(ret->ctx) != 1) {
428
+ unsigned long err = ERR_get_error();
429
+ lcb_log(LOGARGS_S(settings, LCB_LOG_WARN), "Unable to load system certificates: lib=%s, reason=%s",
430
+ ERR_lib_error_string(err), ERR_reason_error_string(err));
431
+ }
432
+ // add the capella Root CA if no other CA was specified.
433
+ *errp = add_certificate_authority(settings, ret->ctx, capella_ca_cert, strlen(capella_ca_cert));
434
+ if (*errp != LCB_SUCCESS) {
435
+ goto GT_ERR;
436
+ }
437
+ }
438
+
439
+ if (cafile && keyfile) {
440
+ lcb_log(LOGARGS_S(settings, LCB_LOG_DEBUG), "Authenticate with key \"%s\", cert \"%s\"", keyfile, cafile);
441
+ if (!SSL_CTX_use_certificate_chain_file(ret->ctx, cafile)) {
442
+ *errp = LCB_ERR_SSL_ERROR;
443
+ goto GT_ERR;
444
+ }
445
+ if (!SSL_CTX_use_PrivateKey_file(ret->ctx, keyfile, SSL_FILETYPE_PEM)) {
446
+ lcb_log(LOGARGS_S(settings, LCB_LOG_ERROR), "Unable to load private key \"%s\"", keyfile);
447
+ *errp = LCB_ERR_SSL_ERROR;
448
+ goto GT_ERR;
449
+ }
450
+ if (!SSL_CTX_check_private_key(ret->ctx)) {
451
+ lcb_log(LOGARGS_S(settings, LCB_LOG_ERROR), "Unable to verify private key \"%s\"", keyfile);
452
+ *errp = LCB_ERR_SSL_ERROR;
453
+ goto GT_ERR;
376
454
  }
377
455
  }
378
456
 
@@ -422,15 +500,25 @@ GT_ERR:
422
500
  return NULL;
423
501
  }
424
502
 
503
+ struct proto_ctx_ssl {
504
+ lcbio_PROTOCTX proto;
505
+ SSL *ssl;
506
+ };
507
+
425
508
  static void noop_dtor(lcbio_PROTOCTX *arg)
426
509
  {
427
- free(arg);
510
+ if (!arg) {
511
+ return;
512
+ }
513
+ struct proto_ctx_ssl *sproto = (struct proto_ctx_ssl *)arg;
514
+ SSL_set_app_data(sproto->ssl, NULL);
515
+ free(sproto);
428
516
  }
429
517
 
430
518
  lcb_STATUS lcbio_ssl_apply(lcbio_SOCKET *sock, lcbio_pSSLCTX sctx)
431
519
  {
432
520
  lcbio_pTABLE old_iot = sock->io, new_iot;
433
- lcbio_PROTOCTX *sproto;
521
+ struct proto_ctx_ssl *sproto;
434
522
 
435
523
  if (old_iot->model == LCB_IOMODEL_EVENT) {
436
524
  new_iot = lcbio_Essl_new(old_iot, sock->u.fd, sctx->ctx);
@@ -440,12 +528,13 @@ lcb_STATUS lcbio_ssl_apply(lcbio_SOCKET *sock, lcbio_pSSLCTX sctx)
440
528
 
441
529
  if (new_iot) {
442
530
  sproto = calloc(1, sizeof(*sproto));
443
- sproto->id = LCBIO_PROTOCTX_SSL;
444
- sproto->dtor = noop_dtor;
445
- lcbio_protoctx_add(sock, sproto);
531
+ sproto->proto.id = LCBIO_PROTOCTX_SSL;
532
+ sproto->proto.dtor = noop_dtor;
533
+ lcbio_protoctx_add(sock, &sproto->proto);
446
534
  lcbio_table_unref(old_iot);
447
535
  sock->io = new_iot;
448
536
  /* just for logging */
537
+ sproto->ssl = ((lcbio_XSSL *)new_iot)->ssl;
449
538
  SSL_set_app_data(((lcbio_XSSL *)new_iot)->ssl, sock);
450
539
  return LCB_SUCCESS;
451
540
 
@@ -932,12 +932,19 @@ char *lcbvb_save_json(lcbvb_CONFIG *cfg)
932
932
  cJSON *tmp = NULL, *nodes = NULL;
933
933
  cJSON *root = cJSON_CreateObject();
934
934
 
935
- if (cfg->dtype == LCBVB_DIST_VBUCKET) {
936
- tmp = cJSON_CreateString("vbucket");
937
- } else {
938
- tmp = cJSON_CreateString("ketama");
935
+ switch (cfg->dtype) {
936
+ case LCBVB_DIST_VBUCKET:
937
+ tmp = cJSON_CreateString("vbucket");
938
+ break;
939
+ case LCBVB_DIST_KETAMA:
940
+ tmp = cJSON_CreateString("ketama");
941
+ break;
942
+ default:
943
+ break;
944
+ }
945
+ if (tmp) {
946
+ cJSON_AddItemToObject(root, "nodeLocator", tmp);
939
947
  }
940
- cJSON_AddItemToObject(root, "nodeLocator", tmp);
941
948
 
942
949
  if (cfg->buuid) {
943
950
  tmp = cJSON_CreateString(cfg->buuid);
@@ -951,8 +958,10 @@ char *lcbvb_save_json(lcbvb_CONFIG *cfg)
951
958
  tmp = cJSON_CreateInt64(cfg->revid);
952
959
  cJSON_AddItemToObject(root, "rev", tmp);
953
960
  }
954
- tmp = cJSON_CreateString(cfg->bname);
955
- cJSON_AddItemToObject(root, "name", tmp);
961
+ if (cfg->bname != NULL) {
962
+ tmp = cJSON_CreateString(cfg->bname);
963
+ cJSON_AddItemToObject(root, "name", tmp);
964
+ }
956
965
 
957
966
  nodes = cJSON_CreateArray();
958
967
  cJSON_AddItemToObject(root, "nodesExt", nodes);
@@ -173,7 +173,7 @@ MACRO(DEFINE_MOCKTEST plugin test)
173
173
  --gtest_filter="ContaminatingUnitTest.*"
174
174
  --gtest_throw_on_failure=1
175
175
  --gtest_print_time=1
176
- --gtest_output=xml:"${PROJECT_BINARY_DIR}/REPORT_${plugin}_${test}.xml")
176
+ --gtest_output=xml:"${PROJECT_BINARY_DIR}/REPORT_${plugin}_${test}_contaminating.xml")
177
177
  SET_TESTS_PROPERTIES(check-contaminating-${plugin}-${test} PROPERTIES LABELS "contaminating" )
178
178
  ENDMACRO()
179
179
 
@@ -69,14 +69,16 @@ static void log_callback(const SSL *ssl, int where, int ret)
69
69
  }
70
70
  }
71
71
 
72
- // http://stackoverflow.com/questions/256405/programmatically-create-x509-certificate-using-openss l
72
+ // http://stackoverflow.com/questions/256405/programmatically-create-x509-certificate-using-openssl
73
73
  // http://www.opensource.apple.com/source/OpenSSL/OpenSSL-22/openssl/demos/x509/mkcert.c
74
74
  // Note we deviate from the examples by directly setting the certificate.
75
75
 
76
- static void genCertificate(SSL_CTX *ctx)
77
- {
78
- EVP_PKEY *pkey = EVP_PKEY_new();
76
+ static void genCertificate(SSL_CTX *ctx) {
79
77
  X509 *x509 = X509_new();
78
+ #if OPENSSL_VERSION_NUMBER >= 0x3000000fL
79
+ EVP_PKEY *pkey = EVP_RSA_gen(2048);
80
+ #else
81
+ EVP_PKEY *pkey = EVP_PKEY_new();
80
82
  RSA *rsa = RSA_new();
81
83
  BIGNUM *exponent = BN_new();
82
84
  BN_set_word(exponent, RSA_F4);
@@ -84,6 +86,7 @@ static void genCertificate(SSL_CTX *ctx)
84
86
  BN_free(exponent);
85
87
 
86
88
  EVP_PKEY_assign_RSA(pkey, rsa);
89
+ #endif
87
90
  ASN1_INTEGER_set(X509_get_serialNumber(x509), 1);
88
91
  X509_gmtime_adj(X509_get_notBefore(x509), 0);
89
92
  X509_gmtime_adj(X509_get_notAfter(x509), 31536000L);
@@ -94,7 +97,7 @@ static void genCertificate(SSL_CTX *ctx)
94
97
  X509_NAME_add_entry_by_txt(name, "O", MBSTRING_ASC, (unsigned char *)"MyCompany Inc.", -1, -1, 0);
95
98
  X509_NAME_add_entry_by_txt(name, "CN", MBSTRING_ASC, (unsigned char *)"localhost", -1, -1, 0);
96
99
  X509_set_issuer_name(x509, name);
97
- X509_sign(x509, pkey, EVP_sha1());
100
+ X509_sign(x509, pkey, EVP_sha384());
98
101
 
99
102
  SSL_CTX_use_PrivateKey(ctx, pkey);
100
103
  SSL_CTX_use_certificate(ctx, x509);
@@ -430,6 +430,9 @@ static void statsCallback(lcb_INSTANCE *instance, lcb_CALLBACK_TYPE, const lcb_R
430
430
  case 1:
431
431
  version = MockEnvironment::VERSION_71;
432
432
  break;
433
+ case 2:
434
+ version = MockEnvironment::VERSION_72;
435
+ break;
433
436
  default:
434
437
  break;
435
438
  }
@@ -248,6 +248,7 @@ class MockEnvironment : public ::testing::Environment
248
248
  VERSION_66 = 12,
249
249
  VERSION_70 = 13,
250
250
  VERSION_71 = 14,
251
+ VERSION_72 = 15,
251
252
  };
252
253
 
253
254
  void SetUp() override;
@@ -89,6 +89,7 @@ TEST_F(RateLimitTest, testRateLimitsKVNumOps)
89
89
  {
90
90
  SKIP_IF_MOCK()
91
91
  SKIP_IF_CLUSTER_VERSION_IS_LOWER_THAN(MockEnvironment::VERSION_71)
92
+ SKIP_IF_CLUSTER_VERSION_IS_HIGHER_THAN(MockEnvironment::VERSION_72)
92
93
  HandleWrap hw;
93
94
  lcb_INSTANCE *instance;
94
95
  createConnection(hw, &instance);
@@ -131,6 +132,7 @@ TEST_F(RateLimitTest, testRateLimitsKVIngress)
131
132
  {
132
133
  SKIP_IF_MOCK()
133
134
  SKIP_IF_CLUSTER_VERSION_IS_LOWER_THAN(MockEnvironment::VERSION_71)
135
+ SKIP_IF_CLUSTER_VERSION_IS_HIGHER_THAN(MockEnvironment::VERSION_72)
134
136
  HandleWrap hw;
135
137
  lcb_INSTANCE *instance;
136
138
  createConnection(hw, &instance);
@@ -162,6 +164,7 @@ TEST_F(RateLimitTest, testRateLimitsKVEgress)
162
164
  {
163
165
  SKIP_IF_MOCK()
164
166
  SKIP_IF_CLUSTER_VERSION_IS_LOWER_THAN(MockEnvironment::VERSION_71)
167
+ SKIP_IF_CLUSTER_VERSION_IS_HIGHER_THAN(MockEnvironment::VERSION_72)
165
168
  HandleWrap hw;
166
169
  lcb_INSTANCE *instance;
167
170
  createConnection(hw, &instance);
@@ -198,6 +201,7 @@ TEST_F(RateLimitTest, testRateLimitsKVMaxConnections)
198
201
  {
199
202
  SKIP_IF_MOCK()
200
203
  SKIP_IF_CLUSTER_VERSION_IS_LOWER_THAN(MockEnvironment::VERSION_71)
204
+ SKIP_IF_CLUSTER_VERSION_IS_HIGHER_THAN(MockEnvironment::VERSION_72)
201
205
  HandleWrap hw;
202
206
  lcb_INSTANCE *instance;
203
207
  createConnection(hw, &instance);
@@ -438,6 +442,7 @@ TEST_F(RateLimitTest, testRateLimitsKVScopeDataSize)
438
442
  {
439
443
  SKIP_IF_MOCK()
440
444
  SKIP_IF_CLUSTER_VERSION_IS_LOWER_THAN(MockEnvironment::VERSION_71)
445
+ SKIP_IF_CLUSTER_VERSION_IS_HIGHER_THAN(MockEnvironment::VERSION_72)
441
446
  HandleWrap hw;
442
447
  lcb_INSTANCE *instance;
443
448
  createConnection(hw, &instance);
@@ -478,6 +483,7 @@ TEST_F(RateLimitTest, testRateLimitsQueryNumIndexes)
478
483
  {
479
484
  SKIP_IF_MOCK()
480
485
  SKIP_IF_CLUSTER_VERSION_IS_LOWER_THAN(MockEnvironment::VERSION_71)
486
+ SKIP_IF_CLUSTER_VERSION_IS_HIGHER_THAN(MockEnvironment::VERSION_72)
481
487
  HandleWrap hw;
482
488
  lcb_INSTANCE *instance;
483
489
  createConnection(hw, &instance);
@@ -527,6 +533,7 @@ TEST_F(RateLimitTest, testRateLimitsSearchNumQueries)
527
533
  {
528
534
  SKIP_IF_MOCK()
529
535
  SKIP_IF_CLUSTER_VERSION_IS_LOWER_THAN(MockEnvironment::VERSION_71)
536
+ SKIP_IF_CLUSTER_VERSION_IS_HIGHER_THAN(MockEnvironment::VERSION_72)
530
537
  HandleWrap hw;
531
538
  lcb_INSTANCE *instance;
532
539
  createConnection(hw, &instance);
@@ -576,6 +583,7 @@ TEST_F(RateLimitTest, testRateLimitsSearchEgress)
576
583
  {
577
584
  SKIP_IF_MOCK()
578
585
  SKIP_IF_CLUSTER_VERSION_IS_LOWER_THAN(MockEnvironment::VERSION_71)
586
+ SKIP_IF_CLUSTER_VERSION_IS_HIGHER_THAN(MockEnvironment::VERSION_72)
579
587
  HandleWrap hw;
580
588
  lcb_INSTANCE *instance;
581
589
  createConnection(hw, &instance);
@@ -631,6 +639,7 @@ TEST_F(RateLimitTest, testRateLimitsSearchIngress)
631
639
  {
632
640
  SKIP_IF_MOCK()
633
641
  SKIP_IF_CLUSTER_VERSION_IS_LOWER_THAN(MockEnvironment::VERSION_71)
642
+ SKIP_IF_CLUSTER_VERSION_IS_HIGHER_THAN(MockEnvironment::VERSION_72)
634
643
  HandleWrap hw;
635
644
  lcb_INSTANCE *instance;
636
645
  createConnection(hw, &instance);
@@ -684,6 +693,7 @@ TEST_F(RateLimitTest, testRateLimitsSearchConcurrentRequests)
684
693
  {
685
694
  SKIP_IF_MOCK()
686
695
  SKIP_IF_CLUSTER_VERSION_IS_LOWER_THAN(MockEnvironment::VERSION_71)
696
+ SKIP_IF_CLUSTER_VERSION_IS_HIGHER_THAN(MockEnvironment::VERSION_72)
687
697
  HandleWrap hw;
688
698
  lcb_INSTANCE *instance;
689
699
  createConnection(hw, &instance);
@@ -726,4 +736,4 @@ TEST_F(RateLimitTest, testRateLimitsSearchConcurrentRequests)
726
736
  ASSERT_TRUE(found_error);
727
737
 
728
738
  drop_user(instance, username);
729
- }
739
+ }
@@ -75,7 +75,7 @@ IF(NOT WIN32)
75
75
  LIST(APPEND CBC_SUBCOMMANDS
76
76
  cat create observe observe-seqno incr decr hash lock
77
77
  unlock rm stats version verbosity view n1ql admin ping
78
- bucket-create bucket-delete bucket-flush connstr write-config strerror
78
+ bucket-list bucket-create bucket-delete bucket-flush connstr write-config strerror
79
79
  touch role-list user-list user-upsert user-delete watch
80
80
  mcversion keygen collection-manifest collection-id
81
81
  )
@@ -827,6 +827,45 @@ class UserUpsertHandler : public AdminHandler
827
827
  std::string body;
828
828
  };
829
829
 
830
+ class BucketListHandler : public AdminHandler
831
+ {
832
+ public:
833
+ HANDLER_DESCRIPTION("List buckets")
834
+ HANDLER_USAGE("NAME [OPTIONS ...]")
835
+ BucketListHandler() : AdminHandler("bucket-list"), o_raw('r', "raw")
836
+ {
837
+ o_raw.description("Do not reformat output from server (display JSON response)");
838
+ }
839
+
840
+ protected:
841
+ void run() override;
842
+ void format();
843
+
844
+ void addOptions() override
845
+ {
846
+ AdminHandler::addOptions();
847
+ parser.addOption(o_raw);
848
+ }
849
+
850
+ std::string getURI() override
851
+ {
852
+ return "/pools/default/buckets";
853
+ }
854
+
855
+ std::string getContentType() override
856
+ {
857
+ return "application/json";
858
+ }
859
+
860
+ lcb_HTTP_METHOD getMethod() override
861
+ {
862
+ return LCB_HTTP_METHOD_GET;
863
+ }
864
+
865
+ private:
866
+ cliopts::BoolOption o_raw;
867
+ };
868
+
830
869
  class BucketCreateHandler : public AdminHandler
831
870
  {
832
871
  public:
@@ -458,6 +458,7 @@ class ThreadContext
458
458
  lcb_STATUS rc = lcb_query(m_instance, &qctx, m_cmd);
459
459
  if (rc != LCB_SUCCESS) {
460
460
  log_error(rc, query.payload.c_str(), query.payload.size());
461
+ lcb_tick_nowait(m_instance);
461
462
  } else {
462
463
  lcb_wait(m_instance, LCB_WAIT_DEFAULT);
463
464
  m_metrics.lock();