Added JSONP.

master
Nicolas Favre-Felix 14 years ago
parent f69263ef7c
commit 9d2beaceec

@ -19,7 +19,6 @@ curl -d "GET/hello" http://127.0.0.1:7379/
* Add meta-data info per key (MIME type in a second key, for instance). * Add meta-data info per key (MIME type in a second key, for instance).
* Find a way to format multi-bulk data without JSON. * Find a way to format multi-bulk data without JSON.
* Support PUT, DELETE, HEAD? * Support PUT, DELETE, HEAD?
* Add JSONP callbacks.
* Add logging. * Add logging.
* Add support for Redis UNIX socket. * Add support for Redis UNIX socket.
* Enrich config file: * Enrich config file:
@ -58,4 +57,9 @@ $ curl http://127.0.0.1:7379/TYPE/y
// error, which is basically a status // error, which is basically a status
$ curl http://127.0.0.1:7379/MAKE-ME-COFFEE $ curl http://127.0.0.1:7379/MAKE-ME-COFFEE
{"MAKE-ME-COFFEE":[false,"ERR unknown command 'MAKE-ME-COFFEE'"]} {"MAKE-ME-COFFEE":[false,"ERR unknown command 'MAKE-ME-COFFEE'"]}
// JSONP callback:
$ curl "http://127.0.0.1:7379/TYPE/y?jsonp=myCustomFunction"
myCustomFunction({"TYPE":[true,"string"]})
</pre> </pre>

10
cmd.c

@ -30,8 +30,10 @@ cmd_free(struct cmd *c) {
} }
void void
cmd_run(redisAsyncContext *c, struct evhttp_request *rq, const char *uri, size_t uri_len) { cmd_run(redisAsyncContext *c, struct evhttp_request *rq,
const char *uri, size_t uri_len) {
char *qmark = strchr(uri, '?');
char *slash = strchr(uri, '/'); char *slash = strchr(uri, '/');
int cmd_len; int cmd_len;
int param_count = 0, cur_param = 1; int param_count = 0, cur_param = 1;
@ -41,6 +43,9 @@ cmd_run(redisAsyncContext *c, struct evhttp_request *rq, const char *uri, size_t
const char *p; const char *p;
/* count arguments */ /* count arguments */
if(qmark) {
uri_len = qmark - uri;
}
for(p = uri; p && p < uri + uri_len; param_count++) { for(p = uri; p && p < uri + uri_len; param_count++) {
p = strchr(p+1, '/'); p = strchr(p+1, '/');
} }
@ -53,6 +58,9 @@ cmd_run(redisAsyncContext *c, struct evhttp_request *rq, const char *uri, size_t
cmd_len = uri_len; cmd_len = uri_len;
} }
/* parse URI parameters */
evhttp_parse_query(uri, &cmd->uri_params);
/* there is always a first parameter, it's the command name */ /* there is always a first parameter, it's the command name */
cmd->argv[0] = uri; cmd->argv[0] = uri;
cmd->argv_len[0] = cmd_len; cmd->argv_len[0] = cmd_len;

@ -3,6 +3,9 @@
#include <stdlib.h> #include <stdlib.h>
#include <hiredis/async.h> #include <hiredis/async.h>
#include <sys/queue.h>
#include <evhttp.h>
#include <event.h>
struct evhttp_request; struct evhttp_request;
@ -12,6 +15,8 @@ struct cmd {
const char **argv; const char **argv;
size_t *argv_len; size_t *argv_len;
struct evhttp_request *rq; struct evhttp_request *rq;
struct evkeyvalq uri_params;
}; };
struct cmd * struct cmd *
@ -21,6 +26,7 @@ void
cmd_free(struct cmd *c); cmd_free(struct cmd *c);
void void
cmd_run(redisAsyncContext *c, struct evhttp_request *rq, const char *uri, size_t uri_len); cmd_run(redisAsyncContext *c, struct evhttp_request *rq,
const char *uri, size_t uri_len);
#endif #endif

@ -28,8 +28,9 @@ json_reply(redisAsyncContext *c, void *r, void *privdata) {
/* encode redis reply as JSON */ /* encode redis reply as JSON */
j = json_wrap_redis_reply(cmd, r); j = json_wrap_redis_reply(cmd, r);
/* get JSON as string */ /* get JSON as string, possibly with JSONP wrapper */
json_reply = json_dumps(j, JSON_COMPACT); json_reply = json_string_output(j, cmd);
/* send reply */ /* send reply */
body = evbuffer_new(); body = evbuffer_new();
@ -103,3 +104,32 @@ json_wrap_redis_reply(const struct cmd *cmd, const redisReply *r) {
return jroot; return jroot;
} }
char *
json_string_output(json_t *j, struct cmd *cmd) {
struct evkeyval *kv;
char *json_reply = json_dumps(j, JSON_COMPACT);
/* check for JSONP */
TAILQ_FOREACH(kv, &cmd->uri_params, next) {
if(strcmp(kv->key, "jsonp") == 0) {
size_t json_len = strlen(json_reply);
size_t val_len = strlen(kv->value);
size_t ret_len = val_len + 1 + json_len + 1;
char *ret = calloc(1 + ret_len, 1);
memcpy(ret, kv->value, val_len);
ret[val_len]='(';
memcpy(ret + val_len + 1, json_reply, json_len);
ret[val_len + 1 + json_len] = ')';
free(json_reply);
return ret;
}
}
return json_reply;
}

@ -10,5 +10,7 @@ struct cmd;
void void
json_reply(redisAsyncContext *c, void *r, void *privdata); json_reply(redisAsyncContext *c, void *r, void *privdata);
char *
json_string_output(json_t *j, struct cmd *cmd);
#endif #endif

Loading…
Cancel
Save