From 5492922f379d3c01ee58d1e39a0a7689e2ea23f6 Mon Sep 17 00:00:00 2001 From: Nicolas Favre-Felix Date: Mon, 20 Dec 2010 23:15:48 +0100 Subject: [PATCH] Added POST support, ideas. --- Makefile | 1 - README.markdown | 14 ++++++++++++-- turnip.c | 31 +++++++++++++++++-------------- 3 files changed, 29 insertions(+), 17 deletions(-) diff --git a/Makefile b/Makefile index c977b25..d846e54 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,6 @@ OUT=turnip OBJS=turnip.o hiredis/hiredis.o hiredis/sds.o hiredis/net.o hiredis/async.o CFLAGS=-O0 -ggdb -Wall -Wextra -I. LDFLAGS=-levent -prefix=/usr all: $(OUT) Makefile diff --git a/README.markdown b/README.markdown index 811d470..ddb7292 100644 --- a/README.markdown +++ b/README.markdown @@ -1,5 +1,4 @@ -About ------ +# About A very simple prototype providing an HTTP interface to Redis. @@ -11,3 +10,14 @@ curl http://127.0.0.1:7379/GET/hello → “world” + +# Ideas + +* Add meta-data info per key (MIME type in a second key, for instance) +* Find a way to format multi-bulk data +* Support PUT, DELETE, HEAD? +* Add JSON output +* Add JSONP callbacks +* Add a config file + * Provide host, port, timeout + * Restrict commands by IP range diff --git a/turnip.c b/turnip.c index 911426c..a971b91 100644 --- a/turnip.c +++ b/turnip.c @@ -40,7 +40,6 @@ cmdCallback(redisAsyncContext *c, void *r, void *privdata) { default: evhttp_send_reply(rq, 500, "Unknown redis format", NULL); } - } static void @@ -58,11 +57,9 @@ disconnectCallback(const redisAsyncContext *c, int status) { } void -run_async_command(redisAsyncContext *c, struct evhttp_request *rq, const char *uri) { - - int uri_len = strlen(uri); +run_async_command(redisAsyncContext *c, struct evhttp_request *rq, const char *uri, size_t uri_len) { - char *slash = strchr(uri + 1, '/'); + char *slash = strchr(uri, '/'); int cmd_len; int param_count = 0, cur_param = 1; @@ -80,13 +77,13 @@ run_async_command(redisAsyncContext *c, struct evhttp_request *rq, const char *u argument_sizes = calloc(param_count, sizeof(size_t)); if(slash) { - cmd_len = slash - uri - 1; + cmd_len = slash - uri; } else { - cmd_len = uri_len - 1; + cmd_len = uri_len; } /* there is always a first parameter, it's the command name */ - arguments[0] = uri + 1; + arguments[0] = uri; argument_sizes[0] = cmd_len; if(!slash) { @@ -126,17 +123,24 @@ run_async_command(redisAsyncContext *c, struct evhttp_request *rq, const char *u void on_request(struct evhttp_request *rq, void *ctx) { - struct evkeyvalq headers; const char *uri = evhttp_request_uri(rq); /* get context */ redisAsyncContext *c = ctx; - /* parse URI */ - evhttp_parse_query(uri, &headers); + switch(rq->type) { + case EVHTTP_REQ_GET: + run_async_command(c, rq, 1+uri, strlen(uri)-1); + break; + case EVHTTP_REQ_POST: + run_async_command(c, rq, + (const char*)EVBUFFER_DATA(rq->input_buffer), + EVBUFFER_LENGTH(rq->input_buffer)); + break; - if(rq->type == EVHTTP_REQ_GET) { - run_async_command(c, rq, uri); + default: + evhttp_send_reply(rq, 500, "Unknown redis format", NULL); + return; } } @@ -155,7 +159,6 @@ main(int argc, char *argv[]) { return 1; } - /* start http server */ evhttp_bind_socket(http, "0.0.0.0", 7379); evhttp_set_gencb(http, on_request, c);