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
@@ -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