initial version of query decoding patch

svn:r1146
This commit is contained in:
Niels Provos 2009-04-10 05:18:18 +00:00
parent f98385a407
commit f43f1d14c5
2 changed files with 45 additions and 5 deletions

17
http.c
View File

@ -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;

View 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),