Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Removed content-type in another key, added suffixes instead.

  • Loading branch information...
commit 469e51608b122f7dc3f7421fb75d7c7384b1499e 1 parent 8c8954d
Nicolas Favre-Felix authored
69 cmd.c
View
@@ -33,9 +33,6 @@ cmd_free(struct cmd *c) {
free(c->argv);
free(c->argv_len);
- free(c->mime);
- free(c->mimeKey);
-
free(c);
}
@@ -100,7 +97,6 @@ cmd_run(struct server *s, struct evhttp_request *rq,
struct cmd *cmd;
formatting_fun f_format;
- transform_fun f_transform = NULL;
/* count arguments */
if(qmark) {
@@ -112,6 +108,13 @@ cmd_run(struct server *s, struct evhttp_request *rq,
cmd = cmd_new(rq, param_count);
+ /* parse URI parameters */
+ evhttp_parse_query(uri, &cmd->uri_params);
+
+ /* get output formatting function */
+ uri_len = cmd_read_params(cmd, uri, uri_len, &f_format);
+
+ /* check if we only have one command or more. */
slash = memchr(uri, '/', uri_len);
if(slash) {
cmd_len = slash - uri;
@@ -119,12 +122,6 @@ cmd_run(struct server *s, struct evhttp_request *rq,
cmd_len = uri_len;
}
- /* parse URI parameters */
- evhttp_parse_query(uri, &cmd->uri_params);
-
- /* get output formatting function */
- cmd_read_params(cmd, &f_format, &f_transform);
-
/* there is always a first parameter, it's the command name */
cmd->argv[0] = uri;
cmd->argv_len[0] = cmd_len;
@@ -170,9 +167,6 @@ cmd_run(struct server *s, struct evhttp_request *rq,
cur_param++;
}
- /* transform command if we need to. */
- if(f_transform) f_transform(cmd);
-
/* push command to Redis. */
redisAsyncCommandArgv(s->ac, f_format, cmd, cmd->count, cmd->argv, cmd->argv_len);
@@ -187,33 +181,42 @@ cmd_run(struct server *s, struct evhttp_request *rq,
* Return 2 functions, one to format the reply and
* one to transform the command before processing it.
*/
-void
-cmd_read_params(struct cmd *cmd, formatting_fun *f_format, transform_fun *f_transform) {
+int
+cmd_read_params(struct cmd *cmd, const char *uri, size_t uri_len, formatting_fun *f_format) {
+
+ const char *ext;
+ int ext_len = -1;
+ unsigned int i;
- struct evkeyval *kv;
+ 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"},
+ {.s = "txt", .sz = 3, .f = custom_type_reply, .ct = "text/plain"},
+ {.s = "html", .sz = 4, .f = custom_type_reply, .ct = "text/html"},
+ {.s = "png", .sz = 3, .f = custom_type_reply, .ct = "image/png"},
+ };
/* defaults */
*f_format = json_reply;
- *f_transform = NULL;
-
- /* loop over the query string */
- TAILQ_FOREACH(kv, &cmd->uri_params, next) {
- if(strcmp(kv->key, "format") == 0) { /* output format */
- if(strcmp(kv->value, "raw") == 0) {
- *f_format = raw_reply;
- } else if(strcmp(kv->value, "json") == 0) {
- *f_format = json_reply;
- }
+
+ /* find extension */
+ for(ext = uri + uri_len - 1; ext != uri && *ext != '/'; --ext) {
+ if(*ext == '.') {
+ ext++;
+ ext_len = uri + uri_len - ext;
break;
- } else if(strcmp(kv->key, "typeKey") == 0) { /* MIME type in a key. */
- cmd->mimeKey = strdup(kv->value);
- *f_transform = custom_type_process_cmd;
- *f_format = custom_type_reply;
- } else if(strcmp(kv->key, "type") == 0) { /* MIME type directly in parameter */
- cmd->mime = strdup(kv->value);
- *f_format = custom_type_reply;
}
}
+ if(!ext_len) return uri_len;
+
+ /* find function for the given extension */
+ for(i = 0; i < sizeof(funs)/sizeof(funs[0]); ++i) {
+ if(ext_len == (int)funs[i].sz && strncmp(ext, funs[i].s, ext_len) == 0) {
+ *f_format = funs[i].f;
+ cmd->mime = funs[i].ct;
+ }
+ }
+ return uri_len - ext_len - 1;
}
int
15 cmd.h
View
@@ -12,7 +12,6 @@ struct server;
struct cmd;
typedef void (*formatting_fun)(redisAsyncContext *, void *, void *);
-typedef void (*transform_fun)(struct cmd *);
struct cmd {
@@ -26,8 +25,7 @@ struct cmd {
int started_responding;
/* HTTP data */
- char *mime;
- char *mimeKey;
+ const char *mime;
char *if_none_match;
};
@@ -37,6 +35,13 @@ 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);
@@ -47,8 +52,8 @@ int
cmd_run(struct server *s, struct evhttp_request *rq,
const char *uri, size_t uri_len);
-void
-cmd_read_params(struct cmd *cmd, formatting_fun *f_format, transform_fun *f_transform);
+int
+cmd_read_params(struct cmd *cmd, const char *uri, size_t uri_len, formatting_fun *f_format);
int
cmd_is_subscribe(struct cmd *cmd);
40 formats/custom-type.c
View
@@ -28,16 +28,24 @@ custom_type_reply(redisAsyncContext *c, void *r, void *privdata) {
}
if(cmd->mime) { /* use the given content-type */
- if(reply->type != REDIS_REPLY_STRING) {
- custom_400(cmd);
- return;
+ switch(reply->type) {
+
+ case REDIS_REPLY_NIL:
+ 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;
}
- format_send_reply(cmd, reply->str, reply->len, cmd->mime);
- return;
}
/* we expect array(string, string) */
- if(!cmd->mimeKey || reply->type != REDIS_REPLY_ARRAY || reply->elements != 2 || reply->element[0]->type != REDIS_REPLY_STRING) {
+ if(reply->type != REDIS_REPLY_ARRAY || reply->elements != 2 || reply->element[0]->type != REDIS_REPLY_STRING) {
custom_400(cmd);
return;
}
@@ -54,23 +62,3 @@ custom_type_reply(redisAsyncContext *c, void *r, void *privdata) {
return;
}
-/* This will change a GET command into MGET if a key is provided to get the response MIME-type from. */
-void
-custom_type_process_cmd(struct cmd *cmd) {
- /* MGET if mode is “custom” */
- if(cmd->count == 2 && cmd->argv_len[0] == 3 &&
- strncasecmp(cmd->argv[0], "GET", 3) == 0 && cmd->mimeKey) {
-
- cmd->count++; /* space for content-type key */
- cmd->argv = realloc(cmd->argv, cmd->count * sizeof(char*));
- cmd->argv_len = realloc(cmd->argv_len, cmd->count * sizeof(size_t));
-
- /* replace command with MGET */
- cmd->argv[0] = "MGET";
- cmd->argv_len[0] = 4;
-
- /* add mime key after the key. */
- cmd->argv[2] = strdup(cmd->mimeKey);
- cmd->argv_len[2] = strlen(cmd->mimeKey);
- }
-}
3  formats/custom-type.h
View
@@ -9,7 +9,4 @@ struct cmd;
void
custom_type_reply(redisAsyncContext *c, void *r, void *privdata);
-void
-custom_type_process_cmd(struct cmd *cmd);
-
#endif
2  formats/raw.c
View
@@ -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, "binary/octet-stream");
+ format_send_reply(cmd, raw_out, sz, cmd->mime?cmd->mime:"binary/octet-stream");
/* cleanup */
free(raw_out);
Please sign in to comment.
Something went wrong with that request. Please try again.