libcouchbase 0.3.3 → 1.0.0

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.
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
@@ -20,60 +20,104 @@
20
20
  #include <libcouchbase/couchbase.h>
21
21
  #include <libcouchbase/views.h>
22
22
  #include "contrib/jsonsl/jsonsl.h"
23
- #include "simplestring.h"
23
+ #include "contrib/lcb-jsoncpp/lcb-jsoncpp.h"
24
+ #include <string>
24
25
 
25
- #ifdef __cplusplus
26
- extern "C" {
27
- #endif
26
+ namespace lcb {
27
+ namespace jsparse {
28
28
 
29
- typedef struct lcbvrow_PARSER_st lcbjsp_PARSER;
29
+ struct Parser;
30
30
 
31
- typedef enum {
32
- LCBJSP_MODE_VIEWS,
33
- LCBJSP_MODE_N1QL,
34
- LCBJSP_MODE_FTS
35
- } lcbjsp_MODE;
31
+ struct Row {
32
+ lcb_IOV docid;
33
+ lcb_IOV key;
34
+ lcb_IOV value;
35
+ lcb_IOV row;
36
+ lcb_IOV geo;
37
+ };
36
38
 
37
- typedef enum {
38
- /**This is a row of view data. You can parse this as JSON from your
39
- * favorite decoder/converter */
40
- LCBJSP_TYPE_ROW,
39
+ struct Parser {
40
+ enum Mode {
41
+ MODE_VIEWS,
42
+ MODE_N1QL,
43
+ MODE_FTS
44
+ };
45
+
46
+ struct Actions {
47
+ /**
48
+ * Called when a row is received.
49
+ * This is a row of view data. You can parse this as JSON from your
50
+ * favorite decoder/converter
51
+ */
52
+ virtual void JSPARSE_on_row(const Row&) = 0;
53
+
54
+ /**
55
+ * A JSON parse error occured. The payload will contain string data. This
56
+ * may be JSON (but this is not likely).
57
+ * The callback will be delivered twice. First when the error is noticed,
58
+ * and second at the end (instead of a COMPLETE callback)
59
+ */
60
+ virtual void JSPARSE_on_error(const std::string& buf) = 0;
61
+
62
+ /**
63
+ * All the rows have been returned. In this case, the data is the 'meta'.
64
+ * This is a valid JSON payload which was returned from the server.
65
+ * The "rows" : [] array will be empty.
66
+ */
67
+ virtual void JSPARSE_on_complete(const std::string& meta) = 0;
68
+
69
+ virtual ~Actions(){}
70
+ };
41
71
 
42
72
  /**
43
- * All the rows have been returned. In this case, the data is the 'meta'.
44
- * This is a valid JSON payload which was returned from the server.
45
- * The "rows" : [] array will be empty.
73
+ * Creates a new vrow context object.
74
+ * You must set callbacks on this object if you wish it to be useful.
75
+ * You must feed it data (calling vrow_feed) as well. The data may be fed
76
+ * in chunks and callbacks will be invoked as each row is read.
46
77
  */
47
- LCBJSP_TYPE_COMPLETE,
78
+ Parser(Mode mode, Actions* actions_);
79
+ ~Parser();
48
80
 
49
81
  /**
50
- * A JSON parse error occured. The payload will contain string data. This
51
- * may be JSON (but this is not likely).
52
- * The callback will be delivered twice. First when the error is noticed,
53
- * and second at the end (instead of a COMPLETE callback)
82
+ * Feeds data into the vrow. The callback may be invoked multiple times
83
+ * in this function. In the context of normal lcb usage, this will typically
84
+ * be invoked from within an http_data_callback.
54
85
  */
55
- LCBJSP_TYPE_ERROR
56
- } lcbjsp_ROWTYPE;
86
+ void feed(const char *s, size_t n);
87
+ void feed(const std::string& s) {
88
+ feed(s.c_str(), s.size());
89
+ }
57
90
 
91
+ /**
92
+ * Parse the row buffer into its constituent parts. This should be called
93
+ * if you want to split the row into its basic 'docid', 'key' and 'value'
94
+ * fields
95
+ * @param vp The parser to use
96
+ * @param vr The row to parse. This assumes the row's "row" field is properly
97
+ * set.
98
+ */
99
+ void parse_viewrow(Row& vr);
58
100
 
59
- typedef struct {
60
- lcbjsp_ROWTYPE type; /**< The type of data encapsulated */
61
- lcb_IOV docid;
62
- lcb_IOV key;
63
- lcb_IOV value;
64
- lcb_IOV row;
65
- lcb_IOV geo;
66
- } lcbjsp_ROW;
101
+ /**
102
+ * Get the raw contents of the current buffer. This can be used to debug errors.
103
+ *
104
+ * Note that the buffer may be partial or malformed or otherwise unsuitable
105
+ * for structured inspection, but may help human observers debug problems.
106
+ *
107
+ * @param out The iov structure to contain the buffer/offset
108
+ */
109
+ void get_postmortem(lcb_IOV& out) const;
67
110
 
68
- typedef void (*lcbjsp_CALLBACK)(lcbjsp_PARSER*,const lcbjsp_ROW*);
111
+ inline const char *get_buffer_region(size_t pos, size_t desired, size_t* actual);
112
+ inline void combine_meta();
113
+ inline static const char *jprstr_for_mode(Mode);
69
114
 
70
- struct lcbvrow_PARSER_st {
71
115
  jsonsl_t jsn; /**< Parser for the row itself */
72
116
  jsonsl_t jsn_rdetails; /**< Parser for the row details */
73
117
  jsonsl_jpr_t jpr; /**< jsonpointer match object */
74
- lcb_string meta_buf; /**< String containing the skeleton (outer layer) */
75
- lcb_string current_buf; /**< Scratch/read buffer */
76
- lcb_string last_hk; /**< Last hashkey */
118
+ std::string meta_buf; /**< String containing the skeleton (outer layer) */
119
+ std::string current_buf; /**< Scratch/read buffer */
120
+ std::string last_hk; /**< Last hashkey */
77
121
 
78
122
  lcb_U8 mode;
79
123
 
@@ -101,73 +145,15 @@ struct lcbvrow_PARSER_st {
101
145
  */
102
146
  size_t last_row_endpos;
103
147
 
104
- void *data;
105
-
106
148
  /**
107
149
  * std::string to contain parsed document ID.
108
150
  */
109
- void *cxx_data;
151
+ Json::Value cxx_data;
110
152
 
111
153
  /* callback to invoke */
112
- lcbjsp_CALLBACK callback;
154
+ Actions *actions;
113
155
  };
114
156
 
115
- /**
116
- * Creates a new vrow context object.
117
- * You must set callbacks on this object if you wish it to be useful.
118
- * You must feed it data (calling vrow_feed) as well. The data may be fed
119
- * in chunks and callbacks will be invoked as each row is read.
120
- */
121
- lcbjsp_PARSER*
122
- lcbjsp_create(int);
123
-
124
- /**
125
- * Resets the context to a pristine state. Callbacks and cookies are kept.
126
- * This may be more efficient than allocating/freeing a context each time
127
- * (as this can be expensive with the jsonsl structures)
128
- */
129
- void
130
- lcbjsp_reset(lcbjsp_PARSER *ctx);
131
-
132
- /**
133
- * Frees a vrow object created by vrow_create
134
- */
135
- void
136
- lcbjsp_free(lcbjsp_PARSER *ctx);
137
-
138
- /**
139
- * Feeds data into the vrow. The callback may be invoked multiple times
140
- * in this function. In the context of normal lcb usage, this will typically
141
- * be invoked from within an http_data_callback.
142
- */
143
- void
144
- lcbjsp_feed(lcbjsp_PARSER *ctx, const char *data, size_t ndata);
145
-
146
- /**
147
- * Parse the row buffer into its constituent parts. This should be called
148
- * if you want to split the row into its basic 'docid', 'key' and 'value'
149
- * fields
150
- * @param vp The parser to use
151
- * @param vr The row to parse. This assumes the row's "row" field is properly
152
- * set.
153
- */
154
- void
155
- lcbjsp_parse_viewrow(lcbjsp_PARSER *vp, lcbjsp_ROW *vr);
156
-
157
- /**
158
- * Get the raw contents of the current buffer. This can be used to debug errors.
159
- *
160
- * Note that the buffer may be partial or malformed or otherwise unsuitable
161
- * for structured inspection, but may help human observers debug problems.
162
- *
163
- * @param v The parser
164
- * @param out The iov structure to contain the buffer/offset
165
- */
166
- void
167
- lcbjsp_get_postmortem(const lcbjsp_PARSER *v, lcb_IOV *out);
168
-
169
- #ifdef __cplusplus
170
157
  }
171
- #endif
172
-
158
+ }
173
159
  #endif /* LCB_VIEWROW_H_ */
@@ -0,0 +1,177 @@
1
+ /* -*- Mode: C; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2
+ /*
3
+ * Copyright 2014 Couchbase, Inc.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+
18
+ #include "lcbht.h"
19
+ #include "contrib/http_parser/http_parser.h"
20
+ #include "settings.h"
21
+
22
+ using namespace lcb::htparse;
23
+
24
+
25
+ Parser::Parser(lcb_settings_st *settings_)
26
+ : http_parser(), settings(settings_), lastcall(CB_NONE),
27
+ last_body(0), last_bodylen(0), paused(false), is_ex(false) {
28
+ lcb_settings_ref(settings);
29
+ reset();
30
+ }
31
+
32
+ Parser::~Parser() {
33
+ lcb_settings_unref(settings);
34
+ }
35
+
36
+ static int on_hdr_key(http_parser *pb, const char *s, size_t n) {
37
+ return Parser::from_htp(pb)->on_hdr_key(s, n);
38
+ }
39
+ int Parser::on_hdr_key(const char *s, size_t n) {
40
+ if (lastcall != CB_HDR_KEY) {
41
+ /* new key */
42
+ resp.headers.push_back(MimeHeader());
43
+ }
44
+
45
+ resp.headers.back().key.append(s, n);
46
+ lastcall = CB_HDR_KEY;
47
+ return 0;
48
+ }
49
+
50
+ static int on_hdr_value(http_parser *pb, const char *s, size_t n) {
51
+ return Parser::from_htp(pb)->on_hdr_value(s, n);
52
+ }
53
+
54
+ int Parser::on_hdr_value(const char *s, size_t n) {
55
+ MimeHeader *header = &resp.headers.back();
56
+ header->value.append(s, n);
57
+ lastcall = CB_HDR_VALUE;
58
+ return 0;
59
+ }
60
+
61
+ static int on_hdr_done(http_parser *pb) {
62
+ return Parser::from_htp(pb)->on_hdr_done();
63
+ }
64
+ int Parser::on_hdr_done() {
65
+ resp.state |= S_HTSTATUS|S_HEADER;
66
+
67
+ /* extract the status */
68
+ resp.status = http_parser::status_code;
69
+ lastcall = CB_HDR_DONE;
70
+ return 0;
71
+ }
72
+
73
+ static int on_body(http_parser *pb, const char *s, size_t n) {
74
+ return Parser::from_htp(pb)->on_body(s, n);
75
+ }
76
+ int Parser::on_body(const char *s, size_t n) {
77
+ if (is_ex) {
78
+ last_body = s;
79
+ last_bodylen = n;
80
+ paused = true;
81
+ _lcb_http_parser_pause(this, 1);
82
+ } else {
83
+ resp.body.append(s, n);
84
+ }
85
+
86
+ lastcall = CB_BODY;
87
+ resp.state |= S_BODY;
88
+ return 0;
89
+ }
90
+
91
+ static int on_msg_done(http_parser *pb) {
92
+ return Parser::from_htp(pb)->on_msg_done();
93
+ }
94
+
95
+ int Parser::on_msg_done() {
96
+ resp.state |= S_DONE;
97
+ return 0;
98
+ }
99
+
100
+
101
+ static struct http_parser_settings Parser_Settings = {
102
+ NULL, /* msg_begin */
103
+ NULL, /* on_url */
104
+ ::on_hdr_key,
105
+ ::on_hdr_value,
106
+ ::on_hdr_done,
107
+ ::on_body,
108
+ ::on_msg_done
109
+ };
110
+
111
+ unsigned
112
+ Parser::parse(const void *data_, size_t ndata) {
113
+ is_ex = false;
114
+ size_t nb = _lcb_http_parser_execute(this,
115
+ &Parser_Settings,
116
+ reinterpret_cast<const char *>(data_), ndata);
117
+
118
+ if (nb != ndata) {
119
+ resp.state |= S_ERROR;
120
+ }
121
+
122
+ return resp.state;
123
+ }
124
+
125
+ unsigned
126
+ Parser::parse_ex(const void *data_, unsigned ndata,
127
+ unsigned *nused, unsigned *nbody, const char **pbody)
128
+ {
129
+ is_ex = true;
130
+ size_t nb = _lcb_http_parser_execute(this,
131
+ &Parser_Settings, reinterpret_cast<const char*>(data_), ndata);
132
+ if (nb != ndata) {
133
+ if (paused) {
134
+ _lcb_http_parser_pause(this, 0);
135
+ paused = false;
136
+ } else {
137
+ resp.state |= S_ERROR;
138
+ return resp.state;
139
+ }
140
+ }
141
+
142
+ *nused = nb;
143
+ *nbody = last_bodylen;
144
+ *pbody = last_body;
145
+
146
+ last_body = NULL;
147
+ last_bodylen = 0;
148
+ return resp.state;
149
+ }
150
+
151
+ bool Parser::can_keepalive() const {
152
+ if (!(resp.state & S_DONE)) {
153
+ return 0;
154
+ }
155
+
156
+ if (resp.state & S_ERROR) {
157
+ return 0;
158
+ }
159
+
160
+ return _lcb_http_should_keep_alive(
161
+ const_cast<http_parser*>(static_cast<const http_parser*>(this)));
162
+ }
163
+
164
+ void Parser::reset() {
165
+ resp.clear();
166
+ _lcb_http_parser_init(this, HTTP_RESPONSE);
167
+ }
168
+
169
+ const MimeHeader* Response::get_header(const std::string& key) const {
170
+ std::list<MimeHeader>::const_iterator it;
171
+ for (it = headers.begin(); it != headers.end(); ++it) {
172
+ if (it->key == key) {
173
+ return &*it;
174
+ }
175
+ }
176
+ return NULL;
177
+ }
@@ -19,14 +19,11 @@
19
19
  #define LCB_HTTP_H
20
20
 
21
21
  #include <libcouchbase/couchbase.h>
22
- #include "simplestring.h"
23
- #include "sllist.h"
24
- struct lcb_settings_st;
25
-
26
- #ifdef __cplusplus
27
- extern "C" {
28
- #endif
22
+ #include "contrib/http_parser/http_parser.h"
23
+ #include <list>
24
+ #include <string>
29
25
 
26
+ struct lcb_settings_st;
30
27
 
31
28
  /**
32
29
  * @file
@@ -39,161 +36,175 @@ extern "C" {
39
36
  * body.
40
37
  */
41
38
 
42
- /** Response state */
43
- typedef enum {
44
- LCBHT_S_HTSTATUS = 1 << 0, /**< Have HTTP status */
45
- LCBHT_S_HEADER = 1 << 1, /**< Have HTTP header */
46
- LCBHT_S_BODY = 1 << 2, /**< Have HTTP body */
47
- LCBHT_S_DONE = 1 << 3, /**< Have a full message */
48
-
49
- /**Have a parse error. Note this is not the same as a HTTP error */
50
- LCBHT_S_ERROR = 1 << 4
51
- } lcbht_RESPSTATE;
52
-
53
- typedef struct {
54
- sllist_node slnode; /**< Next header in list */
55
- const char *key;
56
- const char *value;
57
- lcb_string buf_; /**< Storage for the key and value */
58
- } lcbht_MIMEHDR;
59
-
60
- typedef struct {
61
- unsigned short status; /**< HTTP Status code */
62
- lcbht_RESPSTATE state;
63
- sllist_root headers; /**< List of response headers */
64
- lcb_string body; /**< Body */
65
- } lcbht_RESPONSE;
66
-
67
- typedef struct lcbht_PARSER *lcbht_pPARSER;
68
-
69
- /**
70
- * Initialize the parser object
71
- * @param settings the settings structure used for logging
72
- * @return a new parser object
73
- */
74
- lcbht_pPARSER
75
- lcbht_new(struct lcb_settings_st *settings);
76
-
77
- /** Free the parser object */
78
- void
79
- lcbht_free(lcbht_pPARSER);
80
-
81
- void
82
- lcbht_reset(lcbht_pPARSER);
83
-
84
- /**
85
- * Parse incoming data into a message
86
- * @param parser The parser
87
- * @param data Pointer to new data
88
- * @param ndata Size of the data
89
- *
90
- * @return The current state of the parser. If `state & LCBHT_S_DONE` then
91
- * the current response should be handled before continuing.
92
- * If `state & LCBHT_S_ERROR` then there was an error parsing the contents
93
- * as it violated the HTTP protocol.
94
- */
95
- lcbht_RESPSTATE
96
- lcbht_parse(lcbht_pPARSER parser, const void *data, unsigned ndata);
97
-
98
- /**
99
- * Parse incoming data without buffering
100
- * @param parser The parser to use
101
- * @param data The data to parse
102
- * @param ndata Length of the data
103
- * @param[out] nused How much of the data was actually consumed
104
- * @param[out] nbody Size of the body pointer
105
- * @param[out] pbody a pointer for the body
106
- *
107
- * @return See lcbht_set_bufmode for the meaning of this value
108
- *
109
- * @note It is not an error if `pbody` is NULL. It may mean that the parse state
110
- * is still within the headers and there is no body to parse yet.
111
- *
112
- * This function is intended to be used in a loop, until there is no input
113
- * remaining. The use of the `nused` pointer is to determine by how much the
114
- * `data` pointer should be incremented (and the `ndata` decremented) for the
115
- * next call. When this function returns with a non-error status, `pbody`
116
- * will contain a pointer to a buffer of data (but see note above) which can
117
- * then be processed by the application.
118
- *
119
- * @code{.c}
120
- * char **body, *input;
121
- * unsigned inlen = get_input_len(), nused, bodylen;
122
- * lcbht_RESPSTATE res;
123
- * do {
124
- * res = lcbht_parse_ex(parser, input, inlen, &nused, &nbody, &body);
125
- * if (res & LCBHT_S_ERROR) {
126
- * // handle error
127
- * break;
128
- * }
129
- * if (nbody) {
130
- * // handle body
131
- * }
132
- * input += nused;
133
- * inlen -= nused;
134
- * } while (!(res & LCBHT_S_DONE));
135
- * @endcode
136
- */
137
- lcbht_RESPSTATE
138
- lcbht_parse_ex(lcbht_pPARSER parser, const void *data, unsigned ndata,
139
- unsigned *nused, unsigned *nbody, const char **pbody);
140
-
141
-
142
- /**
143
- * Obtain the current response being processed.
144
- * @param parser The parser
145
- * @return a pointer to a response object. The response object is only valid
146
- * until the next call into another parser API
147
- */
148
- lcbht_RESPONSE *
149
- lcbht_get_response(lcbht_pPARSER parser);
150
-
151
- /**
152
- * Determine whether HTTP/1.1 keepalive is enabled on the connection
153
- * @param parser The parser
154
- * @return true if keepalive is enabled, false otherwise.
155
- */
156
- int
157
- lcbht_can_keepalive(lcbht_pPARSER parser);
158
-
159
- /**
160
- * Clear the response object
161
- * @param resp the response to clear
162
- */
163
- void
164
- lcbht_clear_response(lcbht_RESPONSE *resp);
165
-
166
- /**
167
- * Get a header value for a key
168
- * @param response The response
169
- * @param key The key to look up
170
- * @return A string containing the value. If the header has no value then the
171
- * empty string will be returned. If the header does not exist NULL will be
172
- * returned.
173
- */
174
- const char *
175
- lcbht_get_resphdr(const lcbht_RESPONSE *response, const char *key);
39
+ namespace lcb {
40
+ namespace htparse {
41
+
42
+
43
+ struct MimeHeader {
44
+ std::string key;
45
+ std::string value;
46
+ };
47
+
48
+ struct Response {
49
+ void clear() {
50
+ status = 0;
51
+ state = 0;
52
+ headers.clear();
53
+ body.clear();
54
+ }
55
+
56
+ /**
57
+ * Get a header value for a key
58
+ * @param response The response
59
+ * @param key The key to look up
60
+ * @return A string containing the value. If the header has no value then the
61
+ * empty string will be returned. If the header does not exist NULL will be
62
+ * returned.
63
+ */
64
+ const MimeHeader* get_header(const std::string& key) const;
65
+
66
+ /**
67
+ * Get a header value for a key
68
+ * @param key The key to look up
69
+ * @return A string containing the value. If the header has no value then the
70
+ * empty string will be returned. If the header does not exist NULL will be
71
+ * returned.
72
+ */
73
+ const char *get_header_value(const std::string& key) const {
74
+ const MimeHeader *header = get_header(key);
75
+ if (header) {
76
+ return header->value.c_str();
77
+ }
78
+ return NULL;
79
+ }
176
80
 
177
- /**
178
- * Return a list of headers
179
- * @param response The response
180
- * @return A list of headers. Iterate over this value like so:
181
- * @code{.c}
182
- * char **hdrlist = lcbht_make_resphdrlist(response);
183
- * for (char **cur = hdrlist; *cur; cur += 2) {
184
- * char *key = cur[0];
185
- * char *value = cur[1];
186
- * // do something
187
- * free(key);
188
- * free(value);
189
- * }
190
- * free(hdrlist);
191
- * @endcode
192
- */
193
- char **
194
- lcbht_make_resphdrlist(lcbht_RESPONSE *response);
195
-
196
- #ifdef __cplusplus
197
- }
198
- #endif
81
+ unsigned short status; /**< HTTP Status code */
82
+ unsigned state;
83
+ typedef std::list<MimeHeader> HeaderList;
84
+ HeaderList headers;
85
+ std::string body; /**< Body */
86
+ };
87
+
88
+ class Parser : private http_parser {
89
+ public:
90
+ /**
91
+ * Initialize the parser object
92
+ * @param settings the settings structure used for logging
93
+ */
94
+ Parser(lcb_settings_st*);
95
+ ~Parser();
96
+
97
+ /** Response state */
98
+ enum State {
99
+ S_NONE = 0,
100
+ S_HTSTATUS = 1 << 0, /**< Have HTTP status */
101
+ S_HEADER = 1 << 1, /**< Have HTTP header */
102
+ S_BODY = 1 << 2, /**< Have HTTP body */
103
+ S_DONE = 1 << 3, /**< Have a full message */
104
+
105
+ /**Have a parse error. Note this is not the same as a HTTP error */
106
+ S_ERROR = 1 << 4
107
+ };
108
+
109
+ /**
110
+ * Parse incoming data into a message
111
+ * @param data Pointer to new data
112
+ * @param ndata Size of the data
113
+ *
114
+ * @return The current state of the parser. If `state & LCBHT_S_DONE` then
115
+ * the current response should be handled before continuing.
116
+ * If `state & LCBHT_S_ERROR` then there was an error parsing the contents
117
+ * as it violated the HTTP protocol.
118
+ */
119
+ unsigned parse(const void *data, size_t ndata);
120
+
121
+ /**
122
+ * Parse incoming data without buffering
123
+ * @param data The data to parse
124
+ * @param ndata Length of the data
125
+ * @param[out] nused How much of the data was actually consumed
126
+ * @param[out] nbody Size of the body pointer
127
+ * @param[out] pbody a pointer for the body
128
+ *
129
+ * @return See lcbht_set_bufmode for the meaning of this value
130
+ *
131
+ * @note It is not an error if `pbody` is NULL. It may mean that the parse state
132
+ * is still within the headers and there is no body to parse yet.
133
+ *
134
+ * This function is intended to be used in a loop, until there is no input
135
+ * remaining. The use of the `nused` pointer is to determine by how much the
136
+ * `data` pointer should be incremented (and the `ndata` decremented) for the
137
+ * next call. When this function returns with a non-error status, `pbody`
138
+ * will contain a pointer to a buffer of data (but see note above) which can
139
+ * then be processed by the application.
140
+ *
141
+ * @code{.c++}
142
+ * char **body, *input;
143
+ * unsigned inlen = get_input_len(), nused, bodylen;
144
+ * unsigned res;
145
+ * do {
146
+ * res = parser->parse_ex(input, inlen, &nused, &nbody, &body);
147
+ * if (res & Parser::S_ERROR) {
148
+ * // handle error
149
+ * break;
150
+ * }
151
+ * if (nbody) {
152
+ * // handle body
153
+ * }
154
+ * input += nused;
155
+ * inlen -= nused;
156
+ * } while (!(res & Parser::S_DONE));
157
+ * @endcode
158
+ */
159
+ unsigned parse_ex(const void *data, unsigned ndata,
160
+ unsigned* nused, unsigned *nbody, const char **pbody);
161
+
162
+ /**
163
+ * Obtain the current response being processed.
164
+ * @return a reference to a response object. The response object is only valid
165
+ * until the next call into another parser API
166
+ */
167
+ Response& get_cur_response() {
168
+ return resp;
169
+ }
170
+
171
+ /**
172
+ * Determine whether HTTP/1.1 keepalive is enabled on the connection
173
+ * @return true if keepalive is enabled, false otherwise.
174
+ */
175
+ bool can_keepalive() const;
176
+
177
+ void reset();
178
+
179
+ // Callbacks:
180
+ inline int on_hdr_key(const char *, size_t);
181
+ inline int on_hdr_value(const char *, size_t);
182
+ inline int on_hdr_done();
183
+ inline int on_body(const char *, size_t);
184
+ inline int on_msg_done();
185
+
186
+ static Parser* from_htp(http_parser *p) {
187
+ return static_cast<Parser*>(p);
188
+ }
189
+
190
+ private:
191
+ Response resp;
192
+ lcb_settings_st *settings;
193
+
194
+ enum last_call_type {
195
+ CB_NONE, CB_HDR_KEY, CB_HDR_VALUE,
196
+ CB_HDR_DONE, CB_BODY, CB_MSG_DONE
197
+ };
198
+ last_call_type lastcall;
199
+
200
+ /* For parse_ex */
201
+ const char *last_body;
202
+ unsigned last_bodylen;
203
+
204
+ bool paused;
205
+ bool is_ex;
206
+ };
207
+
208
+ } // namespace htparse
209
+ } // namespace lcb
199
210
  #endif