Skip to content
This repository was archived by the owner on Apr 20, 2022. It is now read-only.

Commit 0a70cca

Browse files
committed
PCBC-226 Use HTTP POST if "keys" are specified
Unfortunately we need to mix arguments on the URL and in the payload of the HTTP POST due to a limitation inside the CouchDB layer. It will silently ignore ALL other options than the "keys" attribute in the payload :-( Change-Id: I89c0c8f47f6b8fe5a602bd8d4eb26525698966c4 Reviewed-on: http://review.couchbase.org/28721 Reviewed-by: Trond Norbye <trond.norbye@gmail.com> Tested-by: Trond Norbye <trond.norbye@gmail.com>
1 parent 8416381 commit 0a70cca

File tree

1 file changed

+51
-13
lines changed

1 file changed

+51
-13
lines changed

views.c

Lines changed: 51 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -110,15 +110,14 @@ static int append_view_option(php_couchbase_res *res,
110110

111111

112112
static void extract_view_options(php_couchbase_res *couchbase_res,
113-
zval *options,
113+
zval *options, char **payload,
114114
smart_str *uri TSRMLS_DC)
115115
{
116116
smart_str_appendc(uri, '?');
117117

118-
for (
119-
zend_hash_internal_pointer_reset(Z_ARRVAL_P(options));
120-
zend_hash_has_more_elements(Z_ARRVAL_P(options)) == SUCCESS;
121-
zend_hash_move_forward(Z_ARRVAL_P(options))) {
118+
for (zend_hash_internal_pointer_reset(Z_ARRVAL_P(options));
119+
zend_hash_has_more_elements(Z_ARRVAL_P(options)) == SUCCESS;
120+
zend_hash_move_forward(Z_ARRVAL_P(options))) {
122121

123122
char *key;
124123
uint klen;
@@ -137,17 +136,44 @@ static void extract_view_options(php_couchbase_res *couchbase_res,
137136
continue;
138137
}
139138

140-
if (FAILURE ==
141-
zend_hash_get_current_data(
142-
Z_ARRVAL_P(options), (void **)&ppzval)) {
139+
if (zend_hash_get_current_data(Z_ARRVAL_P(options), (void **)&ppzval) == FAILURE) {
143140

144141
php_error_docref(NULL TSRMLS_CC, E_ERROR,
145142
"Couldn't get value for %*s", klen, key);
146143
continue;
147144
}
148145

149-
/* Yes! The length *includes* the NUL byte */
150-
append_view_option(couchbase_res, uri, key, klen - 1, *ppzval TSRMLS_CC);
146+
if (strcasecmp("keys", key) == 0) {
147+
smart_str buf = {0};
148+
char *body;
149+
lcb_size_t nbody;
150+
151+
pcbc_json_encode(&buf, *ppzval TSRMLS_CC);
152+
if (buf.len == 0) {
153+
php_error_docref(NULL TSRMLS_CC, E_ERROR,
154+
"Failed to encode key array");
155+
return;
156+
}
157+
158+
nbody = buf.len + 15;
159+
body = calloc(nbody, 1);
160+
161+
if (body == NULL) {
162+
php_error_docref(NULL TSRMLS_CC, E_ERROR,
163+
"Failed to allocate memory");
164+
smart_str_free(&buf);
165+
return;
166+
}
167+
168+
sprintf(body, "{ \"keys\" : ");
169+
strncat(body, buf.c, buf.len);
170+
strcat(body, " }");
171+
*payload = body;
172+
smart_str_free(&buf);
173+
} else {
174+
/* Yes! The length *includes* the NUL byte */
175+
append_view_option(couchbase_res, uri, key, klen - 1, *ppzval TSRMLS_CC);
176+
}
151177
}
152178

153179
/* trim the last '&' from the uri */
@@ -259,6 +285,7 @@ void php_couchbase_view_impl(INTERNAL_FUNCTION_PARAMETERS, int oo, int uri_only)
259285
lcb_http_cmd_t cmd = {0};
260286
lcb_timer_t timer;
261287
struct tc_cookie tcc;
288+
char *body = NULL;
262289
long view_timeout = INI_INT(PCBC_INIENT_VIEW_TIMEOUT);
263290

264291
int argflags = oo ? PHP_COUCHBASE_ARG_F_OO : PHP_COUCHBASE_ARG_F_FUNCTIONAL;
@@ -274,7 +301,12 @@ void php_couchbase_view_impl(INTERNAL_FUNCTION_PARAMETERS, int oo, int uri_only)
274301
view_name, view_name_len);
275302

276303
if (options && memchr(uri.c, '?', uri.len) == NULL) {
277-
extract_view_options(couchbase_res, options, &uri TSRMLS_CC);
304+
extract_view_options(couchbase_res, options, &body, &uri TSRMLS_CC);
305+
}
306+
307+
/* Strip off the '?' if it is at the end */
308+
if (uri.len > 0 && uri.c[uri.len] == '\0' && uri.c[uri.len - 1] == '?') {
309+
--uri.len;
278310
}
279311

280312
if (uri_only) {
@@ -289,18 +321,24 @@ void php_couchbase_view_impl(INTERNAL_FUNCTION_PARAMETERS, int oo, int uri_only)
289321
}
290322

291323
ctx.res = couchbase_res;
292-
293324
memset(&cmd, 0, sizeof(cmd));
294325
cmd.v.v0.path = uri.c;
295326
cmd.v.v0.npath = uri.len;
296-
cmd.v.v0.method = LCB_HTTP_METHOD_GET;
327+
cmd.v.v0.body = body;
328+
if (body) {
329+
cmd.v.v0.nbody = strlen(body);
330+
cmd.v.v0.method = LCB_HTTP_METHOD_POST;
331+
} else {
332+
cmd.v.v0.method = LCB_HTTP_METHOD_GET;
333+
}
297334
cmd.v.v0.content_type = "application/json";
298335

299336
retval = lcb_make_http_request(couchbase_res->handle,
300337
(const void *)&ctx,
301338
LCB_HTTP_TYPE_VIEW,
302339
&cmd, &tcc.request);
303340
smart_str_free(&uri);
341+
free(body);
304342

305343
if (retval != LCB_SUCCESS) {
306344
couchbase_res->rc = retval;

0 commit comments

Comments
 (0)