]> granicus.if.org Git - libevent/commitdiff
Add evhttp_parse_query_str to be used with evhttp_uri_parse.
authorNick Mathewson <nickm@torproject.org>
Tue, 19 Oct 2010 17:15:48 +0000 (13:15 -0400)
committerNick Mathewson <nickm@torproject.org>
Tue, 19 Oct 2010 17:15:48 +0000 (13:15 -0400)
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.

http.c
include/event2/http.h

diff --git a/http.c b/http.c
index 2bf48498a8793339cac1bc4a8773718e5559010b..e4b8e31a3a3e7ed6348fdf7dafcbaecf38adb5b5 100644 (file)
--- a/http.c
+++ b/http.c
@@ -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);
 
+       if (is_whole_uri) {
+               uri = evhttp_uri_parse(str);
+               if (!uri)
+                       goto error;
+               query_part = uri->query;
+       } else {
+               query_part = str;
+       }
+
        /* No arguments - we are done */
-       if (strchr(uri, '?') == NULL)
-               return 0;
+       if (!query_part || !strlen(query_part)) {
+               result = 0;
+               goto done;
+       }
 
-       if ((line = mm_strdup(uri)) == NULL) {
+       if ((line = mm_strdup(query_part)) == NULL) {
                event_warn("%s: strdup", __func__);
-               return -1;
+               goto error;
        }
 
-       argument = line;
-
-       /* We already know that there has to be a ? */
-       strsep(&argument, "?");
-
-       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)
 {
index e2c6942e3c543eaec4f2650651900f3bf170dbd8..d882061c738eae54e76e00291d2f486b9c68ff02 100644 (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,