Added POST support, ideas.

master
Nicolas Favre-Felix 14 years ago
parent a2049b0e73
commit 5492922f37

@ -2,7 +2,6 @@ OUT=turnip
OBJS=turnip.o hiredis/hiredis.o hiredis/sds.o hiredis/net.o hiredis/async.o OBJS=turnip.o hiredis/hiredis.o hiredis/sds.o hiredis/net.o hiredis/async.o
CFLAGS=-O0 -ggdb -Wall -Wextra -I. CFLAGS=-O0 -ggdb -Wall -Wextra -I.
LDFLAGS=-levent LDFLAGS=-levent
prefix=/usr
all: $(OUT) Makefile all: $(OUT) Makefile

@ -1,5 +1,4 @@
About # About
-----
A very simple prototype providing an HTTP interface to Redis. A very simple prototype providing an HTTP interface to Redis.
@ -11,3 +10,14 @@ curl http://127.0.0.1:7379/GET/hello
→ “world” → “world”
</pre> </pre>
# 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

@ -40,7 +40,6 @@ cmdCallback(redisAsyncContext *c, void *r, void *privdata) {
default: default:
evhttp_send_reply(rq, 500, "Unknown redis format", NULL); evhttp_send_reply(rq, 500, "Unknown redis format", NULL);
} }
} }
static void static void
@ -58,11 +57,9 @@ disconnectCallback(const redisAsyncContext *c, int status) {
} }
void void
run_async_command(redisAsyncContext *c, struct evhttp_request *rq, const char *uri) { run_async_command(redisAsyncContext *c, struct evhttp_request *rq, const char *uri, size_t uri_len) {
int uri_len = strlen(uri);
char *slash = strchr(uri + 1, '/'); char *slash = strchr(uri, '/');
int cmd_len; int cmd_len;
int param_count = 0, cur_param = 1; 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)); argument_sizes = calloc(param_count, sizeof(size_t));
if(slash) { if(slash) {
cmd_len = slash - uri - 1; cmd_len = slash - uri;
} else { } else {
cmd_len = uri_len - 1; cmd_len = uri_len;
} }
/* there is always a first parameter, it's the command name */ /* there is always a first parameter, it's the command name */
arguments[0] = uri + 1; arguments[0] = uri;
argument_sizes[0] = cmd_len; argument_sizes[0] = cmd_len;
if(!slash) { if(!slash) {
@ -126,17 +123,24 @@ run_async_command(redisAsyncContext *c, struct evhttp_request *rq, const char *u
void void
on_request(struct evhttp_request *rq, void *ctx) { on_request(struct evhttp_request *rq, void *ctx) {
struct evkeyvalq headers;
const char *uri = evhttp_request_uri(rq); const char *uri = evhttp_request_uri(rq);
/* get context */ /* get context */
redisAsyncContext *c = ctx; redisAsyncContext *c = ctx;
/* parse URI */ switch(rq->type) {
evhttp_parse_query(uri, &headers); 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) { default:
run_async_command(c, rq, uri); evhttp_send_reply(rq, 500, "Unknown redis format", NULL);
return;
} }
} }
@ -155,7 +159,6 @@ main(int argc, char *argv[]) {
return 1; return 1;
} }
/* start http server */ /* start http server */
evhttp_bind_socket(http, "0.0.0.0", 7379); evhttp_bind_socket(http, "0.0.0.0", 7379);
evhttp_set_gencb(http, on_request, c); evhttp_set_gencb(http, on_request, c);

Loading…
Cancel
Save