diff --git a/cmd.c b/cmd.c index f769dbf..24199a0 100644 --- a/cmd.c +++ b/cmd.c @@ -112,7 +112,7 @@ cmd_run(struct server *s, struct evhttp_request *rq, evhttp_parse_query(uri, &cmd->uri_params); /* get output formatting function */ - uri_len = cmd_read_params(cmd, uri, uri_len, &f_format); + uri_len = cmd_select_format(cmd, uri, uri_len, &f_format); /* check if we only have one command or more. */ slash = memchr(uri, '/', uri_len); @@ -135,9 +135,9 @@ cmd_run(struct server *s, struct evhttp_request *rq, /* check if we have to split the connection */ if(cmd_is_subscribe(cmd)) { struct pubsub_client *ps; + ps = calloc(1, sizeof(struct pubsub_client)); ps->s = s = server_copy(s); - ps->rq = rq; evhttp_connection_set_closecb(rq->evcon, on_http_disconnect, ps); @@ -177,17 +177,24 @@ cmd_run(struct server *s, struct evhttp_request *rq, return 0; } + /** - * Return 2 functions, one to format the reply and - * one to transform the command before processing it. + * Select Content-Type and processing function. */ int -cmd_read_params(struct cmd *cmd, const char *uri, size_t uri_len, formatting_fun *f_format) { +cmd_select_format(struct cmd *cmd, const char *uri, size_t uri_len, formatting_fun *f_format) { const char *ext; int ext_len = -1; unsigned int i; + /* those are the available reply formats */ + struct reply_format { + const char *s; + size_t sz; + formatting_fun f; + const char *ct; + }; struct reply_format funs[] = { {.s = "json", .sz = 4, .f = json_reply, .ct = "application/json"}, {.s = "raw", .sz = 3, .f = raw_reply, .ct = "binary/octet-stream"}, @@ -196,7 +203,7 @@ cmd_read_params(struct cmd *cmd, const char *uri, size_t uri_len, formatting_fun {.s = "png", .sz = 3, .f = custom_type_reply, .ct = "image/png"}, }; - /* defaults */ + /* default */ *f_format = json_reply; /* find extension */ @@ -207,7 +214,7 @@ cmd_read_params(struct cmd *cmd, const char *uri, size_t uri_len, formatting_fun break; } } - if(!ext_len) return uri_len; + if(!ext_len) return uri_len; /* nothing found */ /* find function for the given extension */ for(i = 0; i < sizeof(funs)/sizeof(funs[0]); ++i) { diff --git a/cmd.h b/cmd.h index cd94b2a..a477336 100644 --- a/cmd.h +++ b/cmd.h @@ -35,13 +35,6 @@ struct pubsub_client { struct evhttp_request *rq; }; -struct reply_format { - const char *s; - size_t sz; - formatting_fun f; - const char *ct; -}; - struct cmd * cmd_new(struct evhttp_request *rq, int count); @@ -53,7 +46,7 @@ cmd_run(struct server *s, struct evhttp_request *rq, const char *uri, size_t uri_len); int -cmd_read_params(struct cmd *cmd, const char *uri, size_t uri_len, formatting_fun *f_format); +cmd_select_format(struct cmd *cmd, const char *uri, size_t uri_len, formatting_fun *f_format); int cmd_is_subscribe(struct cmd *cmd); diff --git a/formats/custom-type.c b/formats/custom-type.c index c378440..a58ba7f 100644 --- a/formats/custom-type.c +++ b/formats/custom-type.c @@ -6,59 +6,35 @@ #include #include -static void -custom_400(struct cmd *cmd) { - evhttp_send_reply(cmd->rq, 400, "Bad request", NULL); - cmd_free(cmd); -} - void custom_type_reply(redisAsyncContext *c, void *r, void *privdata) { redisReply *reply = r; struct cmd *cmd = privdata; - char *ct; (void)c; evhttp_clear_headers(&cmd->uri_params); - if (reply == NULL) { + if(reply == NULL) { evhttp_send_reply(cmd->rq, 404, "Not Found", NULL); return; } - if(cmd->mime) { /* use the given content-type */ + if(cmd->mime) { /* use the given content-type, but only for strings */ switch(reply->type) { - case REDIS_REPLY_NIL: + case REDIS_REPLY_NIL: /* or nil values */ format_send_reply(cmd, "", 0, cmd->mime); return; case REDIS_REPLY_STRING: format_send_reply(cmd, reply->str, reply->len, cmd->mime); return; - - default: - custom_400(cmd); - return; } } - /* we expect array(string, string) */ - if(reply->type != REDIS_REPLY_ARRAY || reply->elements != 2 || reply->element[0]->type != REDIS_REPLY_STRING) { - custom_400(cmd); - return; - } - - /* case of MGET, we need to have a string for content-type in element[1] */ - if(reply->element[1]->type == REDIS_REPLY_STRING) { - ct = reply->element[1]->str; - } else { - ct = "binary/octet-stream"; - } - - /* send reply */ - format_send_reply(cmd, reply->element[0]->str, reply->element[0]->len, ct); - return; + /* couldn't make sense of what the client wanted. */ + evhttp_send_reply(cmd->rq, 400, "Bad request", NULL); + cmd_free(cmd); } diff --git a/formats/raw.c b/formats/raw.c index b6fdad7..33ce8a6 100644 --- a/formats/raw.c +++ b/formats/raw.c @@ -28,7 +28,7 @@ raw_reply(redisAsyncContext *c, void *r, void *privdata) { raw_out = raw_wrap(r, &sz); /* send reply */ - format_send_reply(cmd, raw_out, sz, cmd->mime?cmd->mime:"binary/octet-stream"); + format_send_reply(cmd, raw_out, sz, "binary/octet-stream"); /* cleanup */ free(raw_out);