Proper decoding of URL parameters.

master
Nicolas Favre-Felix 14 years ago
parent 87567e2a9a
commit 4448b0fac0

@ -25,6 +25,7 @@ curl -d "GET/hello" http://127.0.0.1:7379/
* Possible Redis authentication in the config file.
* Pub/Sub using `Transfer-Encoding: chunked`, works with JSONP as well. Webdis can be used as a Comet server.
* Drop privileges on startup.
* URL-encoded parameters for binary data or slashes. For instance, `%2f` is decoded as `/` but not used as a command separator.
# Ideas, TODO...
* Add meta-data info per key (MIME type in a second key, for instance).
@ -37,7 +38,6 @@ curl -d "GET/hello" http://127.0.0.1:7379/
* Multi-server support, using consistent hashing.
* Send your ideas using the github tracker, on twitter [@yowgi](http://twitter.com/yowgi) or by mail to n.favrefelix@gmail.com.
* Add WebSocket support, allow cross-origin XHR.
* Support URL-encoded parameters, the current implementation is pretty limited (no `/` support, for instance).
# HTTP error codes
* Unknown HTTP verb: 405 Method Not Allowed

42
cmd.c

@ -9,6 +9,7 @@
#include <stdlib.h>
#include <string.h>
#include <hiredis/hiredis.h>
#include <ctype.h>
struct cmd *
cmd_new(struct evhttp_request *rq, int count) {
@ -53,6 +54,35 @@ void on_http_disconnect(struct evhttp_connection *evcon, void *ctx) {
free(ps);
}
/* taken from libevent */
static char *
decode_uri(const char *uri, size_t length, size_t *out_len, int always_decode_plus) {
char c;
size_t i, j;
int in_query = always_decode_plus;
char *ret = malloc(length);
for (i = j = 0; i < length; i++) {
c = uri[i];
if (c == '?') {
in_query = 1;
} else if (c == '+' && in_query) {
c = ' ';
} else if (c == '%' && isxdigit((unsigned char)uri[i+1]) &&
isxdigit((unsigned char)uri[i+2])) {
char tmp[] = { uri[i+1], uri[i+2], '\0' };
c = (char)strtol(tmp, NULL, 16);
i += 2;
}
ret[j++] = c;
}
*out_len = (size_t)j;
return ret;
}
int
cmd_run(struct server *s, struct evhttp_request *rq,
const char *uri, size_t uri_len) {
@ -61,7 +91,7 @@ cmd_run(struct server *s, struct evhttp_request *rq,
char *slash = strchr(uri, '/');
const char *p;
int cmd_len;
int param_count = 0, cur_param = 1;
int param_count = 0, cur_param = 1, i;
struct cmd *cmd;
formatting_fun fun;
@ -128,18 +158,18 @@ cmd_run(struct server *s, struct evhttp_request *rq,
}
/* record argument */
cmd->argv[cur_param] = arg;
cmd->argv_len[cur_param] = arg_len;
cmd->argv[cur_param] = decode_uri(arg, arg_len, &cmd->argv_len[cur_param], 1);
cur_param++;
}
redisAsyncCommandArgv(s->ac, fun, cmd, param_count, cmd->argv, cmd->argv_len);
for(i = 1; i < cur_param; ++i) {
free((char*)cmd->argv[i]);
}
return 0;
}
formatting_fun
get_formatting_function(struct evkeyvalq *params) {

Loading…
Cancel
Save