Permalink
Browse files

Proper decoding of URL parameters.

  • Loading branch information...
1 parent 87567e2 commit 4448b0fac0fbda2517fa6541679e26a1db0555d1 @nicolasff committed Jan 3, 2011
Showing with 37 additions and 7 deletions.
  1. +1 −1 README.markdown
  2. +36 −6 cmd.c
View
2 README.markdown
@@ -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
View
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) {

0 comments on commit 4448b0f

Please sign in to comment.