Permalink
Browse files

Added separator param for custom list responses.

  • Loading branch information...
1 parent 6b82319 commit 006186f429fc3a723e78930c045c1b4fe7e48770 @nicolasff committed Feb 12, 2012
Showing with 42 additions and 3 deletions.
  1. +1 −0 README.markdown
  2. +3 −0 client.c
  3. +1 −0 client.h
  4. +6 −0 cmd.c
  5. +1 −0 cmd.h
  6. +13 −3 formats/custom-type.c
  7. +17 −0 tests/basic.py
View
@@ -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"
View
@@ -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);
}
View
@@ -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;
View
6 cmd.c
@@ -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;
View
1 cmd.h
@@ -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 */
View
@@ -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,17 +73,23 @@ 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;
for(i = 0; i < r->elements; ++i) {
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;
View
@@ -92,6 +92,23 @@ def test_error(self):
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):

0 comments on commit 006186f

Please sign in to comment.