Add evhttp_parse_query_str to be used with evhttp_uri_parse.

The old evhttp_parse_query() doesn't work well with struct
evhttp_uri.query, since it expects to get whole URIs, rather than
just the query portion.
This commit is contained in:
Nick Mathewson 2010-10-19 13:15:48 -04:00
parent 3a33462827
commit 2075fbcff0
2 changed files with 56 additions and 22 deletions

44
http.c
View File

@ -2449,30 +2449,39 @@ evhttp_uridecode(const char *uri, int decode_plus, size_t *size_out)
*/
int
evhttp_parse_query__checked_20(const char *uri, struct evkeyvalq *headers)
evhttp_parse_query__checked_20(const char *str, struct evkeyvalq *headers,
int is_whole_uri)
{
char *line;
char *line=NULL;
char *argument;
char *p;
const char *query_part;
int result = -1;
struct evhttp_uri *uri=NULL;
TAILQ_INIT(headers);
/* No arguments - we are done */
if (strchr(uri, '?') == NULL)
return 0;
if ((line = mm_strdup(uri)) == NULL) {
event_warn("%s: strdup", __func__);
return -1;
if (is_whole_uri) {
uri = evhttp_uri_parse(str);
if (!uri)
goto error;
query_part = uri->query;
} else {
query_part = str;
}
argument = line;
/* No arguments - we are done */
if (!query_part || !strlen(query_part)) {
result = 0;
goto done;
}
/* We already know that there has to be a ? */
strsep(&argument, "?");
if ((line = mm_strdup(query_part)) == NULL) {
event_warn("%s: strdup", __func__);
goto error;
}
p = argument;
p = argument = line;
while (p != NULL && *p != '\0') {
char *key, *value, *decoded_value;
argument = strsep(&p, "&");
@ -2499,7 +2508,10 @@ evhttp_parse_query__checked_20(const char *uri, struct evkeyvalq *headers)
error:
evhttp_clear_headers(headers);
done:
mm_free(line);
if (line)
mm_free(line);
if (uri)
evhttp_uri_free(uri);
return result;
}
@ -2512,11 +2524,9 @@ void evhttp_parse_query(const char *uri, struct evkeyvalq *headers);
void
evhttp_parse_query(const char *uri, struct evkeyvalq *headers)
{
evhttp_parse_query__checked_20(uri, headers);
evhttp_parse_query__checked_20(uri, headers, 1);
}
static struct evhttp_cb *
evhttp_dispatch_callback(struct httpcbq *callbacks, struct evhttp_request *req)
{

View File

@ -573,7 +573,7 @@ char *evhttp_uridecode(const char *uri, int decode_plus,
/**
Helper function to parse out arguments in a query.
Parsing a uri like
Parsing a URI like
http://foo.com/?q=test&s=some+thing
@ -582,17 +582,41 @@ char *evhttp_uridecode(const char *uri, int decode_plus,
The first entry is: key="q", value="test"
The second entry is: key="s", value="some thing"
@deprecated This function is deprecated as of Libevent 2.0.9. Use
evhttp_uri_parse and evhttp_parse_query_str instead.
@param uri the request URI
@param headers the head of the evkeyval queue
@return 0 on success, -1 on failure
*/
#define evhttp_parse_query(uri, headers) \
evhttp_parse_query__checked_20((uri), (headers))
evhttp_parse_query__checked_20((uri), (headers), 1)
/**
Helper function to parse out arguments from the query portion of an
HTTP URI.
Parsing a query string like
q=test&s=some+thing
will result in two entries in the key value queue.
The first entry is: key="q", value="test"
The second entry is: key="s", value="some thing"
@param query_parse the query portion of the URI
@param headers the head of the evkeyval queue
@return 0 on success, -1 on failure
*/
#define evhttp_parse_query_str(query, headers) \
evhttp_parse_query__checked_20((uri), (headers), 0)
/* Do not call this function directly; it is a temporary alias introduced
* to avoid changing the old signature for evhttp_parse_query
*/
int evhttp_parse_query__checked_20(const char *uri, struct evkeyvalq *headers);
int evhttp_parse_query__checked_20(const char *uri, struct evkeyvalq *headers,
int is_whole_url);
/**
* Escape HTML character entities in a string.
@ -637,8 +661,8 @@ struct evhttp_uri {
* specified, the port is set to -1.
*
* Note that no decoding is performed on percent-escaped characters in
* the string; if you want to parse them, use evhttp_uridecode as
* appropriate.
* the string; if you want to parse them, use evhttp_uridecode or
* evhttp_parse_query_str as appropriate.
*
* Note also that most URI schemes will have additional constraints that
* this function does not know about, and cannot check. For example,