Added separator param for custom list responses.

master
Nicolas Favre-Felix 13 years ago
parent 6b8231989e
commit 006186f429

@ -182,6 +182,7 @@ Several content-types are available:
* `.png` for `image/png`
* `jpg` or `jpeg` for `image/jpeg`
* Any other with the `?type=anything/youwant` query string.
* Add a custom separator for list responses with `?sep=,` query string.
<pre>
curl -v "http://127.0.0.1:7379/GET/hello.html"

@ -124,6 +124,9 @@ http_client_on_query_string(struct http_parser *parser, const char *at, size_t s
|| (key_len == 8 && strncmp(key, "callback", 8) == 0)) {
c->jsonp = calloc(1 + val_len, 1);
memcpy(c->jsonp, val, val_len);
} else if(key_len == 3 && strncmp(key, "sep", 3) == 0) {
c->separator = calloc(1 + val_len, 1);
memcpy(c->separator, val, val_len);
} else if(key_len == 8 && strncmp(key, "filename", 8) == 0) {
c->filename = wrap_filename(val, val_len);
}

@ -51,6 +51,7 @@ struct http_client {
char *type; /* forced output content-type */
char *jsonp; /* jsonp wrapper */
char *separator; /* list separator for raw lists */
char *filename; /* content-disposition */
struct cmd *pub_sub;

@ -48,6 +48,7 @@ cmd_free(struct cmd *c) {
free(c->argv_len);
free(c->jsonp);
free(c->separator);
free(c->if_none_match);
if(c->mime_free) free(c->mime);
@ -113,6 +114,11 @@ cmd_setup(struct cmd *cmd, struct http_client *client) {
client->jsonp = NULL;
}
if(client->separator) { /* transfer pointer ownership */
cmd->separator = client->separator;
client->separator = NULL;
}
if(client->filename) { /* transfer pointer ownership */
cmd->filename = client->filename;
client->filename = NULL;

@ -34,6 +34,7 @@ struct cmd {
char *if_none_match; /* used with ETags */
char *jsonp; /* jsonp wrapper */
char *separator; /* list separator for raw lists */
int keep_alive;
/* various flags */

@ -8,7 +8,7 @@
#include <hiredis/async.h>
static char *
custom_array(const redisReply *r, size_t *sz);
custom_array(struct cmd *cmd, const redisReply *r, size_t *sz);
void
custom_type_reply(redisAsyncContext *c, void *r, void *privdata) {
@ -54,7 +54,7 @@ custom_type_reply(redisAsyncContext *c, void *r, void *privdata) {
format_send_reply(cmd, int_buffer, int_len, cmd->mime);
return;
case REDIS_REPLY_ARRAY:
array_out = custom_array(r, &sz);
array_out = custom_array(cmd, r, &sz);
format_send_reply(cmd, array_out, sz, cmd->mime);
free(array_out);
return;
@ -73,10 +73,14 @@ custom_type_reply(redisAsyncContext *c, void *r, void *privdata) {
}
static char *
custom_array(const redisReply *r, size_t *sz) {
custom_array(struct cmd *cmd, const redisReply *r, size_t *sz) {
unsigned int i;
char *ret, *p;
size_t sep_len = 0;
if(cmd->separator)
sep_len = strlen(cmd->separator);
/* compute size */
*sz = 0;
@ -84,6 +88,8 @@ custom_array(const redisReply *r, size_t *sz) {
redisReply *e = r->element[i];
switch(e->type) {
case REDIS_REPLY_STRING:
if(sep_len && i != 0)
*sz += sep_len;
*sz += e->len;
break;
@ -98,6 +104,10 @@ custom_array(const redisReply *r, size_t *sz) {
redisReply *e = r->element[i];
switch(e->type) {
case REDIS_REPLY_STRING:
if(sep_len && i != 0) {
memcpy(p, cmd->separator, sep_len);
p += sep_len;
}
memcpy(p, e->str, e->len);
p += e->len;
break;

@ -92,6 +92,23 @@ class TestJSON(TestWebdis):
self.assertTrue(obj['UNKNOWN'][0] == False)
self.assertTrue(isinstance(obj['UNKNOWN'][1], unicode))
class TestCustom(TestWebdis):
def test_list(self):
"List responses with custom format"
self.query('DEL/hello')
self.query('RPUSH/hello/a/b/c')
f = self.query('LRANGE/hello/0/-1.txt')
self.assertTrue(f.headers.getheader('Content-Type') == 'text/plain')
self.assertTrue(f.read() == "abc")
def test_separator(self):
"Separator in list responses with custom format"
self.query('DEL/hello')
self.query('RPUSH/hello/a/b/c')
f = self.query('LRANGE/hello/0/-1.txt?sep=--')
self.assertTrue(f.headers.getheader('Content-Type') == 'text/plain')
self.assertTrue(f.read() == "a--b--c")
class TestRaw(TestWebdis):
def test_set(self):

Loading…
Cancel
Save