libcouchbase 0.3.3 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (167) hide show
  1. checksums.yaml +4 -4
  2. data/ext/libcouchbase/CMakeLists.txt +6 -8
  3. data/ext/libcouchbase/README.markdown +2 -2
  4. data/ext/libcouchbase/RELEASE_NOTES.markdown +229 -2
  5. data/ext/libcouchbase/cmake/Modules/ConfigureDtrace.cmake +11 -0
  6. data/ext/libcouchbase/cmake/Modules/GenerateConfigDotH.cmake +18 -0
  7. data/ext/libcouchbase/cmake/Modules/GetLibcouchbaseFlags.cmake +3 -2
  8. data/ext/libcouchbase/cmake/Modules/GetVersionInfo.cmake +3 -3
  9. data/ext/libcouchbase/cmake/config-cmake.h.in +4 -0
  10. data/ext/libcouchbase/cmake/defs.mk.in +0 -2
  11. data/ext/libcouchbase/cmake/source_files.cmake +21 -5
  12. data/ext/libcouchbase/contrib/cJSON/cJSON.c +1 -1
  13. data/ext/libcouchbase/contrib/cbsasl/src/client.c +2 -0
  14. data/ext/libcouchbase/example/users/README +48 -0
  15. data/ext/libcouchbase/example/users/users.c +147 -0
  16. data/ext/libcouchbase/include/libcouchbase/auth.h +175 -31
  17. data/ext/libcouchbase/include/libcouchbase/cntl.h +82 -1
  18. data/ext/libcouchbase/include/libcouchbase/couchbase.h +45 -3
  19. data/ext/libcouchbase/include/libcouchbase/error.h +19 -1
  20. data/ext/libcouchbase/include/libcouchbase/iops.h +3 -0
  21. data/ext/libcouchbase/include/libcouchbase/n1ql.h +31 -1
  22. data/ext/libcouchbase/include/libcouchbase/plugins/io/bsdio-inl.c +4 -1
  23. data/ext/libcouchbase/include/libcouchbase/subdoc.h +36 -2
  24. data/ext/libcouchbase/include/libcouchbase/views.h +7 -1
  25. data/ext/libcouchbase/include/libcouchbase/visibility.h +1 -0
  26. data/ext/libcouchbase/include/memcached/protocol_binary.h +24 -1146
  27. data/ext/libcouchbase/packaging/parse-git-describe.pl +1 -1
  28. data/ext/libcouchbase/plugins/io/libev/libev_io_opts.h +3 -2
  29. data/ext/libcouchbase/src/README.md +0 -2
  30. data/ext/libcouchbase/src/auth-priv.h +23 -4
  31. data/ext/libcouchbase/src/auth.cc +51 -43
  32. data/ext/libcouchbase/src/bootstrap.cc +244 -0
  33. data/ext/libcouchbase/src/bootstrap.h +58 -38
  34. data/ext/libcouchbase/src/bucketconfig/bc_cccp.cc +120 -158
  35. data/ext/libcouchbase/src/bucketconfig/bc_file.cc +281 -0
  36. data/ext/libcouchbase/src/bucketconfig/bc_http.cc +526 -0
  37. data/ext/libcouchbase/src/bucketconfig/bc_http.h +50 -25
  38. data/ext/libcouchbase/src/bucketconfig/bc_static.cc +150 -0
  39. data/ext/libcouchbase/src/bucketconfig/clconfig.h +410 -386
  40. data/ext/libcouchbase/src/bucketconfig/confmon.cc +393 -0
  41. data/ext/libcouchbase/src/cbft.cc +22 -27
  42. data/ext/libcouchbase/src/cntl.cc +56 -22
  43. data/ext/libcouchbase/src/connspec.cc +47 -6
  44. data/ext/libcouchbase/src/connspec.h +27 -0
  45. data/ext/libcouchbase/src/dns-srv.cc +147 -0
  46. data/ext/libcouchbase/src/dump.cc +3 -3
  47. data/ext/libcouchbase/src/errmap.cc +173 -0
  48. data/ext/libcouchbase/src/errmap.h +198 -0
  49. data/ext/libcouchbase/src/getconfig.cc +7 -33
  50. data/ext/libcouchbase/src/handler.cc +118 -7
  51. data/ext/libcouchbase/src/hostlist.cc +0 -36
  52. data/ext/libcouchbase/src/hostlist.h +44 -62
  53. data/ext/libcouchbase/src/http/http-priv.h +125 -112
  54. data/ext/libcouchbase/src/http/http.cc +27 -35
  55. data/ext/libcouchbase/src/http/http.h +1 -34
  56. data/ext/libcouchbase/src/http/http_io.cc +28 -36
  57. data/ext/libcouchbase/src/instance.cc +131 -34
  58. data/ext/libcouchbase/src/internal.h +58 -26
  59. data/ext/libcouchbase/src/jsparse/parser.cc +136 -210
  60. data/ext/libcouchbase/src/jsparse/parser.h +84 -98
  61. data/ext/libcouchbase/src/lcbht/lcbht.cc +177 -0
  62. data/ext/libcouchbase/src/lcbht/lcbht.h +174 -163
  63. data/ext/libcouchbase/src/lcbio/connect.cc +569 -0
  64. data/ext/libcouchbase/src/lcbio/connect.h +16 -7
  65. data/ext/libcouchbase/src/lcbio/ctx.c +1 -1
  66. data/ext/libcouchbase/src/lcbio/iotable.h +101 -16
  67. data/ext/libcouchbase/src/lcbio/{ioutils.c → ioutils.cc} +30 -51
  68. data/ext/libcouchbase/src/lcbio/ioutils.h +29 -90
  69. data/ext/libcouchbase/src/lcbio/manager.cc +543 -0
  70. data/ext/libcouchbase/src/lcbio/manager.h +133 -96
  71. data/ext/libcouchbase/src/lcbio/protoctx.c +2 -2
  72. data/ext/libcouchbase/src/lcbio/timer-cxx.h +87 -0
  73. data/ext/libcouchbase/src/mc/mcreq.c +11 -2
  74. data/ext/libcouchbase/src/mc/mcreq.h +9 -2
  75. data/ext/libcouchbase/src/mcserver/mcserver.cc +175 -43
  76. data/ext/libcouchbase/src/mcserver/mcserver.h +9 -13
  77. data/ext/libcouchbase/src/mcserver/negotiate.cc +181 -62
  78. data/ext/libcouchbase/src/mcserver/negotiate.h +1 -3
  79. data/ext/libcouchbase/src/mctx-helper.h +51 -0
  80. data/ext/libcouchbase/src/n1ql/ixmgmt.cc +1 -2
  81. data/ext/libcouchbase/src/n1ql/n1ql.cc +74 -42
  82. data/ext/libcouchbase/src/netbuf/netbuf.c +4 -4
  83. data/ext/libcouchbase/src/newconfig.cc +6 -6
  84. data/ext/libcouchbase/src/nodeinfo.cc +2 -2
  85. data/ext/libcouchbase/src/operations/{cbflush.c → cbflush.cc} +7 -15
  86. data/ext/libcouchbase/src/operations/{counter.c → counter.cc} +0 -0
  87. data/ext/libcouchbase/src/operations/durability.cc +6 -26
  88. data/ext/libcouchbase/src/operations/durability_internal.h +6 -3
  89. data/ext/libcouchbase/src/operations/{get.c → get.cc} +24 -26
  90. data/ext/libcouchbase/src/operations/{observe.c → observe.cc} +68 -93
  91. data/ext/libcouchbase/src/operations/{pktfwd.c → pktfwd.cc} +0 -0
  92. data/ext/libcouchbase/src/operations/{remove.c → remove.cc} +0 -0
  93. data/ext/libcouchbase/src/operations/stats.cc +3 -8
  94. data/ext/libcouchbase/src/operations/{store.c → store.cc} +27 -32
  95. data/ext/libcouchbase/src/operations/subdoc.cc +129 -42
  96. data/ext/libcouchbase/src/operations/{touch.c → touch.cc} +0 -0
  97. data/ext/libcouchbase/src/packetutils.h +30 -2
  98. data/ext/libcouchbase/src/probes.d +1 -1
  99. data/ext/libcouchbase/src/rdb/rope.c +1 -1
  100. data/ext/libcouchbase/src/{retrychk.c → retrychk.cc} +2 -3
  101. data/ext/libcouchbase/src/retryq.cc +52 -14
  102. data/ext/libcouchbase/src/retryq.h +3 -3
  103. data/ext/libcouchbase/src/settings.c +5 -0
  104. data/ext/libcouchbase/src/settings.h +11 -0
  105. data/ext/libcouchbase/src/ssl/ssl_c.c +1 -0
  106. data/ext/libcouchbase/src/ssl/ssl_common.c +2 -0
  107. data/ext/libcouchbase/src/ssl/ssl_e.c +0 -1
  108. data/ext/libcouchbase/src/strcodecs/strcodecs.h +1 -1
  109. data/ext/libcouchbase/src/trace.h +4 -4
  110. data/ext/libcouchbase/src/vbucket/vbucket.c +6 -10
  111. data/ext/libcouchbase/src/views/{docreq.c → docreq.cc} +48 -54
  112. data/ext/libcouchbase/src/views/docreq.h +24 -30
  113. data/ext/libcouchbase/src/views/viewreq.cc +318 -0
  114. data/ext/libcouchbase/src/views/viewreq.h +43 -13
  115. data/ext/libcouchbase/tests/basic/t_connstr.cc +88 -50
  116. data/ext/libcouchbase/tests/basic/t_creds.cc +47 -5
  117. data/ext/libcouchbase/tests/basic/t_host.cc +67 -75
  118. data/ext/libcouchbase/tests/basic/t_jsparse.cc +27 -82
  119. data/ext/libcouchbase/tests/basic/t_misc.cc +1 -1
  120. data/ext/libcouchbase/tests/basic/t_n1qlstrings.cc +0 -1
  121. data/ext/libcouchbase/tests/htparse/t_basic.cc +58 -78
  122. data/ext/libcouchbase/tests/ioserver/connection.cc +1 -1
  123. data/ext/libcouchbase/tests/ioserver/ioserver.cc +19 -6
  124. data/ext/libcouchbase/tests/iotests/mock-environment.cc +28 -2
  125. data/ext/libcouchbase/tests/iotests/mock-environment.h +51 -1
  126. data/ext/libcouchbase/tests/iotests/t_behavior.cc +1 -7
  127. data/ext/libcouchbase/tests/iotests/t_confmon.cc +97 -115
  128. data/ext/libcouchbase/tests/iotests/t_durability.cc +0 -1
  129. data/ext/libcouchbase/tests/iotests/t_eerrs.cc +119 -0
  130. data/ext/libcouchbase/tests/iotests/t_errmap.cc +178 -0
  131. data/ext/libcouchbase/tests/iotests/t_misc.cc +3 -3
  132. data/ext/libcouchbase/tests/iotests/t_netfail.cc +1 -1
  133. data/ext/libcouchbase/tests/iotests/t_obseqno.cc +0 -1
  134. data/ext/libcouchbase/tests/iotests/t_subdoc.cc +18 -11
  135. data/ext/libcouchbase/tests/mc/t_alloc.cc +9 -9
  136. data/ext/libcouchbase/tests/socktests/socktest.cc +7 -10
  137. data/ext/libcouchbase/tests/socktests/socktest.h +2 -3
  138. data/ext/libcouchbase/tests/socktests/t_basic.cc +6 -6
  139. data/ext/libcouchbase/tests/socktests/t_manager.cc +5 -6
  140. data/ext/libcouchbase/tests/socktests/t_ssl.cc +1 -1
  141. data/ext/libcouchbase/tests/vbucket/confdata/ketama_expected.json +2562 -0
  142. data/ext/libcouchbase/tests/vbucket/confdata/memd_ketama_config.json +31 -0
  143. data/ext/libcouchbase/tests/vbucket/t_config.cc +35 -5
  144. data/ext/libcouchbase/tools/CMakeLists.txt +2 -2
  145. data/ext/libcouchbase/tools/cbc-handlers.h +128 -0
  146. data/ext/libcouchbase/tools/cbc-n1qlback.cc +64 -10
  147. data/ext/libcouchbase/tools/cbc-pillowfight.cc +2 -2
  148. data/ext/libcouchbase/tools/cbc.cc +143 -10
  149. data/ext/libcouchbase/tools/docgen/loc.h +1 -1
  150. data/lib/libcouchbase/connection.rb +4 -3
  151. data/lib/libcouchbase/version.rb +1 -1
  152. metadata +37 -28
  153. data/ext/libcouchbase/include/memcached/vbucket.h +0 -42
  154. data/ext/libcouchbase/src/bootstrap.c +0 -269
  155. data/ext/libcouchbase/src/bucketconfig/bc_file.c +0 -347
  156. data/ext/libcouchbase/src/bucketconfig/bc_http.c +0 -630
  157. data/ext/libcouchbase/src/bucketconfig/bc_mcraw.c +0 -150
  158. data/ext/libcouchbase/src/bucketconfig/confmon.c +0 -474
  159. data/ext/libcouchbase/src/lcbht/lcbht.c +0 -282
  160. data/ext/libcouchbase/src/lcbio/connect.c +0 -557
  161. data/ext/libcouchbase/src/lcbio/manager.c +0 -584
  162. data/ext/libcouchbase/src/packetutils.c +0 -37
  163. data/ext/libcouchbase/src/simplestring.c +0 -211
  164. data/ext/libcouchbase/src/simplestring.h +0 -228
  165. data/ext/libcouchbase/src/ssobuf.h +0 -82
  166. data/ext/libcouchbase/src/views/viewreq.c +0 -358
  167. data/ext/libcouchbase/tests/basic/t_string.cc +0 -112
@@ -21,6 +21,8 @@
21
21
  #include "mc/compress.h"
22
22
  #include "trace.h"
23
23
 
24
+ #define LOGARGS(obj, lvl) (obj)->settings, "handler", LCB_LOG_##lvl, __FILE__, __LINE__
25
+
24
26
  using lcb::MemcachedResponse;
25
27
 
26
28
  template <typename T>
@@ -28,12 +30,60 @@ class ResponsePack {
28
30
  public:
29
31
  T resp;
30
32
  lcb_MUTATION_TOKEN mt;
33
+ const char *value;
34
+ lcb_SIZE nvalue;
35
+ char *err_ref;
36
+ char *err_ctx;
37
+
38
+ ~ResponsePack() {
39
+ free(err_ref);
40
+ free(err_ctx);
41
+ }
31
42
 
32
43
  static const lcb_MUTATION_TOKEN*
33
44
  get_mt(const lcb_RESPBASE *rb) {
34
45
  const ResponsePack *rp = reinterpret_cast<const ResponsePack*>(rb);
35
46
  return &rp->mt;
36
47
  }
48
+
49
+ static const char*
50
+ get_err_ctx(const lcb_RESPBASE *rb) {
51
+ const ResponsePack *rp = reinterpret_cast<const ResponsePack*>(rb);
52
+ if (rp->resp.rflags & LCB_RESP_F_ERRINFO) {
53
+ if (rp->err_ctx) {
54
+ return rp->err_ctx;
55
+ } else {
56
+ parse_enhanced_error(rp);
57
+ return rp->err_ctx;
58
+ }
59
+ }
60
+ return NULL;
61
+ }
62
+
63
+ static const char*
64
+ get_err_ref(const lcb_RESPBASE *rb) {
65
+ const ResponsePack *rp = reinterpret_cast<const ResponsePack*>(rb);
66
+ if (rp->resp.rflags & LCB_RESP_F_ERRINFO) {
67
+ if (rp->err_ref) {
68
+ return rp->err_ref;
69
+ } else {
70
+ parse_enhanced_error(rp);
71
+ return rp->err_ref;
72
+ }
73
+ }
74
+ return NULL;
75
+ }
76
+
77
+ private:
78
+
79
+ static void
80
+ parse_enhanced_error(const ResponsePack *rp) {
81
+ ResponsePack *mrp = const_cast<ResponsePack *>(rp);
82
+ lcb_error_t rc = MemcachedResponse::parse_enhanced_error(mrp->value, mrp->nvalue, &mrp->err_ref, &mrp->err_ctx);
83
+ if (rc != LCB_SUCCESS) {
84
+ mrp->resp.rflags &= ~LCB_RESP_F_ERRINFO;
85
+ }
86
+ }
37
87
  };
38
88
 
39
89
  LIBCOUCHBASE_API
@@ -53,7 +103,7 @@ lcb_errmap_default(lcb_t instance, lcb_uint16_t in)
53
103
  case PROTOCOL_BINARY_RESPONSE_EINTERNAL:
54
104
  default:
55
105
  if (instance) {
56
- lcb_log(instance->settings, "handler", LCB_LOG_ERROR, __FILE__, __LINE__, "Got unhandled memcached error 0x%X", in);
106
+ lcb_log(LOGARGS(instance, ERROR), "Got unhandled memcached error 0x%X", in);
57
107
  } else {
58
108
  fprintf(stderr, "COUCHBASE: Unhandled memcached status=0x%x\n", in);
59
109
  }
@@ -113,6 +163,8 @@ map_error(lcb_t instance, int in)
113
163
  return LCB_UNKNOWN_COMMAND;
114
164
  case PROTOCOL_BINARY_RESPONSE_NOT_SUPPORTED:
115
165
  return LCB_NOT_SUPPORTED;
166
+ case PROTOCOL_BINARY_RESPONSE_EACCESS:
167
+ return LCB_NOT_AUTHORIZED;
116
168
  default:
117
169
  if (instance != NULL) {
118
170
  return instance->callbacks.errmap(instance, in);
@@ -174,6 +226,18 @@ void make_error(lcb_t instance, T* resp,
174
226
  }
175
227
  }
176
228
 
229
+ template <typename T>
230
+ void handle_error_info(const MemcachedResponse* mc_resp, ResponsePack<T>* rp)
231
+ {
232
+ if (mc_resp->status() != PROTOCOL_BINARY_RESPONSE_SUCCESS
233
+ && mc_resp->datatype() & PROTOCOL_BINARY_DATATYPE_JSON
234
+ && mc_resp->vallen() > 0) {
235
+ rp->resp.rflags |= LCB_RESP_F_ERRINFO;
236
+ rp->value = mc_resp->value();
237
+ rp->nvalue = mc_resp->vallen();
238
+ }
239
+ }
240
+
177
241
  template <typename T>
178
242
  void init_resp(lcb_t instance, const MemcachedResponse* mc_resp,
179
243
  const mc_PACKET *req, lcb_error_t immerr, T *resp) {
@@ -289,10 +353,12 @@ static void
289
353
  H_get(mc_PIPELINE *pipeline, mc_PACKET *request, MemcachedResponse* response,
290
354
  lcb_error_t immerr)
291
355
  {
292
- lcb_RESPGET resp = { 0 };
356
+ ResponsePack<lcb_RESPGET> w = {{ 0 }};
357
+ lcb_RESPGET& resp = w.resp;
293
358
 
294
359
  lcb_t o = get_instance(pipeline);
295
360
  init_resp(o, response, request, immerr, &resp);
361
+ handle_error_info(response, &w);
296
362
  resp.rflags |= LCB_RESP_F_FINAL;
297
363
 
298
364
  if (resp.rc == LCB_SUCCESS) {
@@ -317,12 +383,14 @@ static void
317
383
  H_getreplica(mc_PIPELINE *pipeline, mc_PACKET *request,
318
384
  MemcachedResponse *response, lcb_error_t immerr)
319
385
  {
320
- lcb_RESPGET resp = { 0 };
386
+ ResponsePack<lcb_RESPGET> w = {{ 0 }};
387
+ lcb_RESPGET& resp = w.resp;
321
388
  lcb_t instance = get_instance(pipeline);
322
389
  void *freeptr = NULL;
323
390
  mc_REQDATAEX *rd = request->u_rdata.exdata;
324
391
 
325
392
  init_resp(instance, response, request, immerr, &resp);
393
+ handle_error_info(response, &w);
326
394
 
327
395
  if (resp.rc == LCB_SUCCESS) {
328
396
  const protocol_binary_response_get *get =
@@ -511,6 +579,7 @@ H_delete(mc_PIPELINE *pipeline, mc_PACKET *packet, MemcachedResponse *response,
511
579
  ResponsePack<lcb_RESPREMOVE> w = { { 0 } };
512
580
  w.resp.rflags |= LCB_RESP_F_EXTDATA | LCB_RESP_F_FINAL;
513
581
  init_resp(root, response, packet, immerr, &w.resp);
582
+ handle_error_info(response, &w);
514
583
  handle_mutation_token(root, response, packet, &w.mt);
515
584
  TRACE_REMOVE_END(response, &w.resp);
516
585
  invoke_callback(packet, root, &w.resp, LCB_CALLBACK_REMOVE);
@@ -628,6 +697,7 @@ H_store(mc_PIPELINE *pipeline, mc_PACKET *request, MemcachedResponse *response,
628
697
  ResponsePack<lcb_RESPSTORE> w = { { 0 } };
629
698
  uint8_t opcode;
630
699
  init_resp(root, response, request, immerr, &w.resp);
700
+ handle_error_info(response, &w);
631
701
  if (!immerr) {
632
702
  opcode = response->opcode();
633
703
  } else {
@@ -669,6 +739,8 @@ H_arithmetic(mc_PIPELINE *pipeline, mc_PACKET *request,
669
739
  w.resp.value = lcb_ntohll(w.resp.value);
670
740
  w.resp.rflags |= LCB_RESP_F_EXTDATA;
671
741
  handle_mutation_token(root, response, request, &w.mt);
742
+ } else {
743
+ handle_error_info(response, &w);
672
744
  }
673
745
  w.resp.rflags |= LCB_RESP_F_FINAL;
674
746
  w.resp.cas = response->cas();
@@ -741,8 +813,10 @@ H_touch(mc_PIPELINE *pipeline, mc_PACKET *request, MemcachedResponse *response,
741
813
  lcb_error_t immerr)
742
814
  {
743
815
  lcb_t root = get_instance(pipeline);
744
- lcb_RESPTOUCH resp = { 0 };
816
+ ResponsePack<lcb_RESPTOUCH> w = {{ 0 }};
817
+ lcb_RESPTOUCH& resp = w.resp;
745
818
  init_resp(root, response, request, immerr, &resp);
819
+ handle_error_info(response, &w);
746
820
  resp.rflags |= LCB_RESP_F_FINAL;
747
821
  TRACE_TOUCH_END(response, &resp);
748
822
  invoke_callback(request, root, &resp, LCB_CALLBACK_TOUCH);
@@ -764,8 +838,10 @@ H_unlock(mc_PIPELINE *pipeline, mc_PACKET *request, MemcachedResponse *response,
764
838
  lcb_error_t immerr)
765
839
  {
766
840
  lcb_t root = get_instance(pipeline);
767
- lcb_RESPUNLOCK resp = { 0 };
841
+ ResponsePack<lcb_RESPUNLOCK> w = {{ 0 }};
842
+ lcb_RESPUNLOCK& resp = w.resp;
768
843
  init_resp(root, response, request, immerr, &resp);
844
+ handle_error_info(response, &w);
769
845
  resp.rflags |= LCB_RESP_F_FINAL;
770
846
  TRACE_UNLOCK_END(response, &resp);
771
847
  invoke_callback(request, root, &resp, LCB_CALLBACK_UNLOCK);
@@ -822,8 +898,6 @@ mcreq_dispatch_response(
822
898
  break;
823
899
 
824
900
  switch (res->opcode()) {
825
- case PROTOCOL_BINARY_CMD_GETQ:
826
- case PROTOCOL_BINARY_CMD_GATQ:
827
901
  case PROTOCOL_BINARY_CMD_GET:
828
902
  case PROTOCOL_BINARY_CMD_GAT:
829
903
  case PROTOCOL_BINARY_CMD_GET_LOCKED:
@@ -934,3 +1008,40 @@ lcb_resp_get_mutation_token(int cbtype, const lcb_RESPBASE *rb)
934
1008
  }
935
1009
  return ss;
936
1010
  }
1011
+
1012
+ #define ERRINFO_CALLBACKS(X) \
1013
+ X(GET) \
1014
+ X(STORE) \
1015
+ X(COUNTER) \
1016
+ X(TOUCH) \
1017
+ X(REMOVE) \
1018
+ X(UNLOCK) \
1019
+
1020
+
1021
+ LIBCOUCHBASE_API
1022
+ const char *
1023
+ lcb_resp_get_error_context(int cbtype, const lcb_RESPBASE *rb)
1024
+ {
1025
+ if ((rb->rflags & LCB_RESP_F_ERRINFO) == 0) {
1026
+ return NULL;
1027
+ }
1028
+
1029
+ #define X(NAME) if (cbtype == LCB_CALLBACK_##NAME) { return ResponsePack<lcb_RESP##NAME>::get_err_ctx(rb); }
1030
+ ERRINFO_CALLBACKS(X);
1031
+ #undef X
1032
+ return NULL;
1033
+ }
1034
+
1035
+ LIBCOUCHBASE_API
1036
+ const char *
1037
+ lcb_resp_get_error_ref(int cbtype, const lcb_RESPBASE *rb)
1038
+ {
1039
+ if ((rb->rflags & LCB_RESP_F_ERRINFO) == 0) {
1040
+ return NULL;
1041
+ }
1042
+
1043
+ #define X(NAME) if (cbtype == LCB_CALLBACK_##NAME) { return ResponsePack<lcb_RESP##NAME>::get_err_ref(rb); }
1044
+ ERRINFO_CALLBACKS(X);
1045
+ #undef X
1046
+ return NULL;
1047
+ }
@@ -16,7 +16,6 @@
16
16
  */
17
17
 
18
18
  #include "hostlist.h"
19
- #include "simplestring.h"
20
19
  #include <stdio.h>
21
20
  #include <ctype.h>
22
21
  #include <limits.h>
@@ -264,38 +263,3 @@ Hostlist::assign(const Hostlist& src)
264
263
  }
265
264
  return *this;
266
265
  }
267
-
268
- extern "C" {
269
- Hostlist* hostlist_create(void) { return new Hostlist(); }
270
- void hostlist_destroy(hostlist_t l) { delete l; }
271
- void hostlist_clear(hostlist_t l) { l->clear(); }
272
- void hostlist_reset_strlist(hostlist_t l) { l->reset_strlist(); }
273
- lcb_error_t hostlist_add_host(hostlist_t l, const lcb_host_t *h) { l->add(*h); return LCB_SUCCESS; }
274
- lcb_host_t *hostlist_shift_next(hostlist_t hl, int wrap) { return hl->next(wrap); }
275
- int hostlist_finished(hostlist_t l) { return l->ix == l->hosts.size(); }
276
- size_t hostlist_size(hostlist_t l) { return l->size(); }
277
- void hostlist_randomize(hostlist_t l) { l->randomize(); }
278
-
279
- lcb_error_t
280
- hostlist_add_string(hostlist_t hl, const char *spec, int len, int deflport) {
281
- return hl->add(spec, len, deflport);
282
- }
283
-
284
- void
285
- hostlist_assign(hostlist_t dst, const hostlist_t src) {
286
- dst->assign(*src);
287
- }
288
-
289
- const lcb_host_t*
290
- hostlist_get(const hostlist_t h, size_t ix) { return &h->hosts[ix]; }
291
-
292
- const char * const *
293
- hostlist_strents(const hostlist_t h) {
294
- h->ensure_strlist();
295
- if (h->hoststrs.size()) {
296
- return &h->hoststrs[0];
297
- } else {
298
- return NULL;
299
- }
300
- }
301
- }
@@ -45,21 +45,59 @@ struct Hostlist {
45
45
  Hostlist() : ix(0) {}
46
46
  ~Hostlist();
47
47
 
48
- void add(const lcb_host_t&);
48
+ /**
49
+ * Adds a string to the hostlist. See lcb_host_parse for details.
50
+ * Note that if the host already exists (see 'lcb_host_equals') it will
51
+ * not be added
52
+ * @param s the string to parse
53
+ * @param len the length of the string
54
+ * @param deflport If `s` does not contain an explicit port, use this
55
+ * port instead.
56
+ * @return LCB_EINVAL if the host string is not valid
57
+ */
49
58
  lcb_error_t add(const char *s, long len, int deflport);
50
59
  lcb_error_t add(const char *s, int deflport) { return add(s, -1, deflport); }
60
+ void add(const lcb_host_t&);
61
+
51
62
  bool exists(const lcb_host_t&) const;
52
63
  bool exists(const char *hostport) const;
64
+
65
+ /**
66
+ * Return the next host in the list.
67
+ * @param wrap If the internal iterator has reached its limit, this
68
+ * indicates whether it should be reset, or if it should return NULL
69
+ * @return a new host if available, or NULL if the list is empty or the
70
+ * iterator is finished.
71
+ */
53
72
  lcb_host_t *next(bool wrap);
54
73
  bool finished() const;
55
74
 
56
75
  size_t size() const { return hosts.size(); }
57
76
  bool empty() const { return hosts.empty(); }
58
77
  Hostlist& assign(const Hostlist& other);
78
+
79
+ /** Clears the hostlist */
59
80
  void clear() { hosts.clear(); reset_strlist(); ix = 0; }
81
+
82
+ /** Randomize the hostlist by shuffling the order. */
60
83
  void randomize();
84
+
85
+ /**
86
+ * String list handling functions. These are used to return the hostlist via
87
+ * the API where we return a char*[] terminated by a NULL pointer.
88
+ */
89
+
90
+ /** Ensure that the string list contains at least one entry */
61
91
  void ensure_strlist();
92
+
93
+ /** Frees the current list of strings */
62
94
  void reset_strlist();
95
+
96
+ const char * const *get_strlist() {
97
+ ensure_strlist();
98
+ return &hoststrs[0];
99
+ }
100
+
63
101
  unsigned int ix;
64
102
  const lcb_host_t& operator[](size_t ix_) const { return hosts[ix_]; }
65
103
 
@@ -68,28 +106,16 @@ struct Hostlist {
68
106
  };
69
107
  }
70
108
  typedef lcb::Hostlist* hostlist_t;
71
- #define hostlist_st lcb::Hostlist
109
+
110
+ struct hostlist_st : lcb::Hostlist {
111
+ hostlist_st() : Hostlist() {
112
+ }
113
+ };
72
114
  #endif
73
115
 
74
116
  #ifdef __cplusplus
75
117
  extern "C" {
76
118
  #endif
77
-
78
- /**
79
- * Creates a new hostlist. Returns NULL on allocation failure
80
- */
81
- hostlist_t hostlist_create(void);
82
-
83
- /**
84
- * Frees resources associated with the hostlist
85
- */
86
- void hostlist_destroy(hostlist_t hostlist);
87
-
88
- /**
89
- * Clears the hostlist
90
- */
91
- void hostlist_clear(hostlist_t hostlist);
92
-
93
119
  /**
94
120
  * Parses a string into a hostlist
95
121
  * @param host the target host to populate
@@ -121,50 +147,6 @@ lcb_host_parse(lcb_host_t *host, const char *spec, int speclen, int deflport);
121
147
  */
122
148
  int lcb_host_equals(const lcb_host_t *a, const lcb_host_t *b);
123
149
 
124
- /**
125
- * Adds a string to the hostlist. See lcb_host_parse for details.
126
- * Note that if the host already exists (see 'lcb_host_equals') it will
127
- * not be added
128
- * @return LCB_EINVAL if the host string is not value, LCB_CLIENT_ENOMEM on
129
- * allocation failure.
130
- */
131
- lcb_error_t hostlist_add_string(hostlist_t hostlist,
132
- const char *spec,
133
- int speclen,
134
- int deflport);
135
-
136
- #define hostlist_add_stringz(hostlist, spec, deflport) \
137
- hostlist_add_string(hostlist, spec, -1, deflport)
138
-
139
- lcb_error_t hostlist_add_host(hostlist_t hostlist, const lcb_host_t *host);
140
-
141
- /**
142
- * Return the next host in the list.
143
- * @param hostlist the hostlist to use
144
- * @param rollover If the internal iterator has reached its limit, this
145
- * indicates whether it should be reset, or if it should return NULL
146
- * @return a new host if available, or NULL if the list is empty or the
147
- * iterator is finished.
148
- */
149
- lcb_host_t *hostlist_shift_next(hostlist_t hostlist, int rollover);
150
-
151
- /**
152
- * Randomize the hostlist
153
- */
154
- void hostlist_randomize(hostlist_t hostlist);
155
-
156
- /**
157
- * String list handling functions. These are used to return the hostlist via
158
- * the API where we return a char*[] terminated by a NULL pointer.
159
- */
160
- void hostlist_reset_strlist(hostlist_t hostlist);
161
-
162
- /** Whether the internal iterator has finished. */
163
- int hostlist_finished(hostlist_t);
164
- size_t hostlist_size(const hostlist_t hl);
165
- void hostlist_assign(hostlist_t dst, const hostlist_t src);
166
- const lcb_host_t *hostlist_get(const hostlist_t, size_t);
167
- const char * const *hostlist_strents(const hostlist_t hl);
168
150
  #ifdef __cplusplus
169
151
  }
170
152
  #endif
@@ -21,6 +21,7 @@
21
21
  #include <libcouchbase/couchbase.h>
22
22
  #include <lcbio/lcbio.h>
23
23
  #include <lcbio/timer-ng.h>
24
+ #include <lcbio/timer-cxx.h>
24
25
  #include <lcbht/lcbht.h>
25
26
  #include "contrib/http_parser/http_parser.h"
26
27
  #include "http.h"
@@ -41,100 +42,34 @@ struct Header {
41
42
  };
42
43
 
43
44
  struct Request {
44
- enum State {
45
- /**
46
- * The request is still ongoing. Callbacks are still active.
47
- * Note that this essentially means the absence of any flags :)
48
- */
49
- ONGOING = 0,
50
-
51
- /**
52
- * This flag is set when the on_complete callback has been invoked. This
53
- * is used as a marker to prevent us from calling that callback more than
54
- * once per request
55
- */
56
- CBINVOKED = 1 << 0,
57
-
58
- /**
59
- * This flag is set by lcb_http_request_finish, and indicates that the
60
- * request is no longer active per se. This means that while the request
61
- * may still be valid in memory, it is simply waiting for any pending I/O
62
- * operations to close, so the reference count can hit zero.
63
- */
64
- FINISHED = 1 << 1,
65
-
66
- /**
67
- * Internal flag used to indicate that finish() should not not attempt
68
- * to modify any instance-level globals. This is currently used
69
- * from within lcb_destroy()
70
- */
71
- NOLCB = 1 << 2
72
- };
73
-
74
- lcb_t instance; /**< Library handle */
75
- std::string url; /**<Base URL: http://host:port/path?query*/
76
- std::string host; /**< Host, derived from URL */
77
- std::string port; /**< Port, derived from URL */
78
-
79
- std::string pending_redirect; /**< New redirected URL */
80
- bool has_pending_redirect() const { return !pending_redirect.empty(); }
81
- const std::vector<char> body; /**< Input body (for POST/PUT) */
82
-
83
- /** Request buffer (excluding body). Reassembled from inputs */
84
- std::vector<char> preamble;
85
-
86
- struct http_parser_url url_info; /**< Parser info for the URL */
87
- const lcb_http_method_t method; /**< Request method constant */
88
- const bool chunked; /**< Whether to invoke callback for each data chunk */
89
- bool paused; /**< See pause() and resume() */
90
- const void * const command_cookie; /** User context for callback */
91
- size_t refcount; /** Initialized to 1. See incref() and decref() */
92
- int redircount; /** Times this request was redirected */
93
-
94
45
  /**
95
- * Whether this request has delivered data to the user. This is relevant
96
- * in cases where a retry is requested. If any data has been passed at
97
- * all, we cannot retry the request.
46
+ * Initializes the request. This simply copies the relevant fields from the
47
+ * body and initializes instance members to their default values. The static
48
+ * ::create() method should be used instead to construct a new object
98
49
  */
99
- bool passed_data;
50
+ inline Request(lcb_t instance, const void *cookie, const lcb_CMDHTTP* cmd);
100
51
 
101
- /** Sparse map indicating which nodes the request was already sent to */
102
- std::vector<int> used_nodes;
52
+ /** Creates a new request object and verifies the input (setup_inputs()) */
53
+ static Request * create(lcb_t instance, const void *cookie,
54
+ const lcb_CMDHTTP *cmd, lcb_error_t *rc);
103
55
 
104
- /**
105
- * Last revision ID of vBucket config. If the current revision does not
106
- * match this number, the ::used_nodes field is cleared
107
- */
108
- int last_vbcrev;
56
+ /** Pause IO on this request */
57
+ void pause();
109
58
 
110
- const lcb_http_type_t reqtype; /**< HTTP API type */
111
- int status; /**< OR'd flags of ::State */
112
- std::vector<Header> request_headers; /**< List of request headers */
59
+ /** Resume previously paused IO */
60
+ void resume();
61
+
62
+ /** Cancel and finish this request, suppressing callbacks */
63
+ void cancel();
113
64
 
114
65
  /**
115
- * Response headers for callback (array of char*). Buffers are mapped to
116
- * ::response_headers
66
+ * Start all operations required to make this request. This should be
67
+ * called once all inputs have been completed. If successful, I/O operations
68
+ * will begin (this function calls start_io())
117
69
  */
118
- std::vector<const char*> response_headers_clist;
119
-
120
- /** Backing buffers for response headers */
121
- std::vector<Header> response_headers;
122
-
123
- /** Callback to invoke */
124
- lcb_RESPCALLBACK callback;
125
-
126
- // IO variables
127
- lcbio_pTABLE io;
128
- lcbio_pCTX ioctx;
129
- lcbio_pTIMER timer;
130
- lcbio_CONNREQ creq;
131
-
132
- /** HTTP Protocol parser */
133
- lcbht_pPARSER parser;
134
-
135
- /** overrides default timeout if nonzero */
136
- const uint32_t user_timeout;
70
+ lcb_error_t submit();
137
71
 
72
+ bool has_pending_redirect() const { return !pending_redirect.empty(); }
138
73
  /**
139
74
  * @return The effective timeout. This is either the user timeout or the
140
75
  * default timeout for the API type
@@ -152,13 +87,6 @@ struct Request {
152
87
  */
153
88
  bool is_ongoing() const { return status == ONGOING; }
154
89
 
155
- /**
156
- * Initializes the request. This simply copies the relevant fields from the
157
- * body and initializes instance members to their default values. The static
158
- * ::create() method should be used instead to construct a new object
159
- */
160
- inline Request(lcb_t instance, const void *cookie, const lcb_CMDHTTP* cmd);
161
-
162
90
  /**
163
91
  * Sets up inputs from the command. This should really be in the
164
92
  * constructor, however we also need a return value. The ::create()
@@ -180,10 +108,6 @@ struct Request {
180
108
  const char *get_api_node(lcb_error_t &rc);
181
109
  const char *get_api_node() { lcb_error_t dummy; return get_api_node(dummy); }
182
110
 
183
- /** Creates a new request object and verifies the input (setup_inputs()) */
184
- static Request * create(lcb_t instance, const void *cookie,
185
- const lcb_CMDHTTP *cmd, lcb_error_t *rc);
186
-
187
111
  /**
188
112
  * Sets the URL for the field
189
113
  * @param base The URL base (i.e. http://foo.com)
@@ -220,13 +144,6 @@ struct Request {
220
144
  inline void add_to_preamble(const std::string&);
221
145
  inline void add_to_preamble(const Header&);
222
146
 
223
- /**
224
- * Start all operations required to make this request. This should be
225
- * called once all inputs have been completed. If successful, I/O operations
226
- * will begin (this function calls start_io())
227
- */
228
- lcb_error_t submit();
229
-
230
147
  /**
231
148
  * Starts the IO on the current request. This really belongs in submit(),
232
149
  * but submit() handles building the request while start_io() sets up
@@ -241,7 +158,7 @@ struct Request {
241
158
 
242
159
  // Helper functions for parsing response data from network
243
160
  inline int handle_parse_chunked(const char *buf, unsigned nbuf);
244
- inline void assign_response_headers(const lcbht_RESPONSE*);
161
+ inline void assign_response_headers(const lcb::htparse::Response&);
245
162
 
246
163
  /**
247
164
  * Called when a redirect has happened. pending_redirect must not be empty.
@@ -273,14 +190,15 @@ struct Request {
273
190
  **/
274
191
  void finish_or_retry(lcb_error_t rc);
275
192
 
276
- /** Pause IO on this request */
277
- void pause();
278
-
279
- /** Resume previously paused IO */
280
- void resume();
281
-
282
- /** Cancel and finish this request, suppressing callbacks */
283
- void cancel();
193
+ /**
194
+ * Change the callback for this request. This is used to indicate that
195
+ * a custom internal callback is used, rather than the one installed via
196
+ * lcb_install_callback3
197
+ * @param callback_ The internal callback to invoke
198
+ */
199
+ void set_callback(lcb_RESPCALLBACK callback_) {
200
+ callback = callback_;
201
+ }
284
202
 
285
203
  /**
286
204
  * Let the request finish its normal course, suppressing any callbacks.
@@ -297,6 +215,101 @@ struct Request {
297
215
 
298
216
  /** Increment refcount */
299
217
  void incref() { refcount++; }
218
+
219
+ lcb_t instance; /**< Library handle */
220
+ std::string url; /**<Base URL: http://host:port/path?query*/
221
+ std::string host; /**< Host, derived from URL */
222
+ std::string port; /**< Port, derived from URL */
223
+
224
+ std::string pending_redirect; /**< New redirected URL */
225
+
226
+ const std::vector<char> body; /**< Input body (for POST/PUT) */
227
+
228
+ /** Request buffer (excluding body). Reassembled from inputs */
229
+ std::vector<char> preamble;
230
+
231
+ struct http_parser_url url_info; /**< Parser info for the URL */
232
+ const lcb_http_method_t method; /**< Request method constant */
233
+ const bool chunked; /**< Whether to invoke callback for each data chunk */
234
+ bool paused; /**< See pause() and resume() */
235
+ const void * const command_cookie; /** User context for callback */
236
+ size_t refcount; /** Initialized to 1. See incref() and decref() */
237
+ int redircount; /** Times this request was redirected */
238
+
239
+ /**
240
+ * Whether this request has delivered data to the user. This is relevant
241
+ * in cases where a retry is requested. If any data has been passed at
242
+ * all, we cannot retry the request.
243
+ */
244
+ bool passed_data;
245
+
246
+ /** Sparse map indicating which nodes the request was already sent to */
247
+ std::vector<int> used_nodes;
248
+
249
+ /**
250
+ * Last revision ID of vBucket config. If the current revision does not
251
+ * match this number, the ::used_nodes field is cleared
252
+ */
253
+ int last_vbcrev;
254
+
255
+ const lcb_http_type_t reqtype; /**< HTTP API type */
256
+
257
+
258
+ enum State {
259
+ /**
260
+ * The request is still ongoing. Callbacks are still active.
261
+ * Note that this essentially means the absence of any flags :)
262
+ */
263
+ ONGOING = 0,
264
+
265
+ /**
266
+ * This flag is set when the on_complete callback has been invoked. This
267
+ * is used as a marker to prevent us from calling that callback more than
268
+ * once per request
269
+ */
270
+ CBINVOKED = 1 << 0,
271
+
272
+ /**
273
+ * This flag is set by lcb_http_request_finish, and indicates that the
274
+ * request is no longer active per se. This means that while the request
275
+ * may still be valid in memory, it is simply waiting for any pending I/O
276
+ * operations to close, so the reference count can hit zero.
277
+ */
278
+ FINISHED = 1 << 1,
279
+
280
+ /**
281
+ * Internal flag used to indicate that finish() should not not attempt
282
+ * to modify any instance-level globals. This is currently used
283
+ * from within lcb_destroy()
284
+ */
285
+ NOLCB = 1 << 2
286
+ };
287
+ int status; /**< OR'd flags of ::State */
288
+ std::vector<Header> request_headers; /**< List of request headers */
289
+
290
+ /**
291
+ * Response headers for callback (array of char*). Buffers are mapped to
292
+ * ::response_headers
293
+ */
294
+ std::vector<const char*> response_headers_clist;
295
+
296
+ /** Backing buffers for response headers */
297
+ std::vector<lcb::htparse::MimeHeader> response_headers;
298
+
299
+ /** Callback to invoke */
300
+ lcb_RESPCALLBACK callback;
301
+
302
+ // IO variables
303
+ lcbio_pTABLE io;
304
+ lcbio_pCTX ioctx;
305
+ lcbio_pTIMER timer;
306
+ lcb::io::ConnectionRequest *creq;
307
+
308
+ /** HTTP Protocol parser */
309
+ lcb::htparse::Parser* parser;
310
+
311
+ /** overrides default timeout if nonzero */
312
+ const uint32_t user_timeout;
300
313
  };
301
314
 
302
315
  } // namespace: http