]> granicus.if.org Git - libevent/commitdiff
initial version of query decoding patch
authorNiels Provos <provos@gmail.com>
Fri, 10 Apr 2009 05:18:18 +0000 (05:18 +0000)
committerNiels Provos <provos@gmail.com>
Fri, 10 Apr 2009 05:18:18 +0000 (05:18 +0000)
svn:r1146

http.c
test/regress_http.c

diff --git a/http.c b/http.c
index 189843688101f4fdc7bf07502d65d46918339cfa..5865f65f53eff12998fb37744da9bdd76cab620b 100644 (file)
--- a/http.c
+++ b/http.c
@@ -218,7 +218,7 @@ static void evhttp_read_cb(struct bufferevent *, void *);
 static void evhttp_write_cb(struct bufferevent *, void *);
 static void evhttp_error_cb(struct bufferevent *bufev, short what, void *arg);
 static int evhttp_decode_uri_internal(const char *uri, size_t length,
-    char *ret);
+    char *ret, int optional_decode_plus);
 
 #ifndef _EVENT_HAVE_STRSEP
 /* strsep replacement for platforms that lack it.  Only works if
@@ -2112,11 +2112,16 @@ evhttp_encode_uri(const char *uri)
        return (p);
 }
 
+/*
+ * @param optional_decode_plus: when true we transform plus to space only
+ *     if we have seen a ?.
+ */
 static int
-evhttp_decode_uri_internal(const char *uri, size_t length, char *ret)
+evhttp_decode_uri_internal(
+       const char *uri, size_t length, char *ret, int optional_decode_plus)
 {
        char c;
-       int i, j, in_query = 0;
+       int i, j, in_query = !optional_decode_plus;
 
        for (i = j = 0; i < length; i++) {
                c = uri[i];
@@ -2146,7 +2151,8 @@ evhttp_decode_uri(const char *uri)
                event_err(1, "%s: malloc(%lu)", __func__,
                          (unsigned long)(strlen(uri) + 1));
 
-       evhttp_decode_uri_internal(uri, strlen(uri), ret);
+       evhttp_decode_uri_internal(uri, strlen(uri),
+           ret, 0 /*optional_decode_plus*/);
 
        return (ret);
 }
@@ -2214,7 +2220,8 @@ evhttp_dispatch_callback(struct httpcbq *callbacks, struct evhttp_request *req)
 
        if ((translated = mm_malloc(offset + 1)) == NULL)
                return (NULL);
-       offset = evhttp_decode_uri_internal(req->uri, offset, translated);
+       offset = evhttp_decode_uri_internal(req->uri, offset,
+           translated, 1 /* optional_decode_plus */);
 
        TAILQ_FOREACH(cb, callbacks, next) {
                int res = 0;
index 1f6947e11cd0098cc0ca0eebaf84f266feb74d3e..0c2944dce9b1ffae3243c0616b7f53b1a1a87479 100644 (file)
@@ -1359,6 +1359,38 @@ http_bad_header_test(void *ptr)
        evhttp_clear_headers(&headers);
 }
 
+static int validate_header(
+       const struct evkeyvalq* headers,
+       const char *key, const char *value) 
+{
+       const char *real_val = evhttp_find_header(headers, key);
+       tt_assert(real_val != NULL);
+       tt_want(strcmp(real_val, value) == 0);
+end:
+       return (0);
+}
+
+static void
+http_parse_query_test(void *ptr)
+{
+       struct evkeyvalq headers;
+
+       TAILQ_INIT(&headers);
+       
+       evhttp_parse_query("http://www.test.com/?q=test", &headers);
+       tt_want(validate_header(&headers, "q", "test") == 0);
+       evhttp_clear_headers(&headers);
+
+       evhttp_parse_query("http://www.test.com/?q=test&foo=bar", &headers);
+       tt_want(validate_header(&headers, "q", "test") == 0);
+       tt_want(validate_header(&headers, "foo", "bar") == 0);
+       evhttp_clear_headers(&headers);
+
+       evhttp_parse_query("http://www.test.com/?q=test+foo", &headers);
+       tt_want(validate_header(&headers, "q", "test foo") == 0);
+       evhttp_clear_headers(&headers);
+}
+
 static void
 http_base_test(void)
 {
@@ -2148,6 +2180,7 @@ struct testcase_t http_testcases[] = {
        { "primitives", http_primitives, 0, NULL, NULL },
        HTTP_LEGACY(base),
        { "bad_headers", http_bad_header_test, 0, NULL, NULL },
+       { "parse_query", http_parse_query_test, 0, NULL, NULL },
        HTTP_LEGACY(basic),
        HTTP_LEGACY(cancel),
        HTTP_LEGACY(virtual_host),