commit a88b8de6a2c3500a44df312d0dd341d5b1a12705
parent b3cdccbc872f108c6e3e2775385824c54e16b6f2
Author: Joris Vink <joris@coders.se>
Date: Fri, 3 May 2013 09:09:27 +0200
add proper query argument parsing, modules must call
http_populate_arguments() before using http_argument_lookup() to lookup a given argument.
population uses the appropriate query string (from GET or POST) automatically.
Diffstat:
2 files changed, 73 insertions(+), 0 deletions(-)
diff --git a/includes/http.h b/includes/http.h
@@ -19,6 +19,7 @@
#define HTTP_HEADER_MAX_LEN 8192
#define HTTP_REQ_HEADER_MAX 25
+#define HTTP_MAX_QUERY_ARGS 10
struct http_header {
char *header;
@@ -27,6 +28,13 @@ struct http_header {
TAILQ_ENTRY(http_header) list;
};
+struct http_arg {
+ char *name;
+ char *value;
+
+ TAILQ_ENTRY(http_arg) list;
+};
+
#define HTTP_METHOD_GET 0
#define HTTP_METHOD_POST 1
@@ -43,6 +51,7 @@ struct http_request {
TAILQ_HEAD(, http_header) req_headers;
TAILQ_HEAD(, http_header) resp_headers;
+ TAILQ_HEAD(, http_arg) arguments;
TAILQ_ENTRY(http_request) list;
};
@@ -59,5 +68,8 @@ int http_request_new(struct connection *, struct spdy_stream *,
int http_header_recv(struct netbuf *);
char *http_post_data_text(struct http_request *);
+int http_populate_arguments(struct http_request *);
+int http_argument_lookup(struct http_request *,
+ const char *, char **);
#endif /* !__H_HTTP_H */
diff --git a/src/http.c b/src/http.c
@@ -66,6 +66,7 @@ http_request_new(struct connection *c, struct spdy_stream *s, char *host,
req->path = kore_strdup(path);
TAILQ_INIT(&(req->resp_headers));
TAILQ_INIT(&(req->req_headers));
+ TAILQ_INIT(&(req->arguments));
if (!strcasecmp(method, "get")) {
req->method = HTTP_METHOD_GET;
@@ -102,6 +103,7 @@ http_response_header_add(struct http_request *req, char *header, char *value)
void
http_request_free(struct http_request *req)
{
+ struct http_arg *q, *qnext;
struct http_header *hdr, *next;
for (hdr = TAILQ_FIRST(&(req->resp_headers)); hdr != NULL; hdr = next) {
@@ -122,6 +124,15 @@ http_request_free(struct http_request *req)
free(hdr);
}
+ for (q = TAILQ_FIRST(&(req->arguments)); q != NULL; q = qnext) {
+ qnext = TAILQ_NEXT(q, list);
+
+ TAILQ_REMOVE(&(req->arguments), q, list);
+ free(q->name);
+ free(q->value);
+ free(q);
+ }
+
free(req->path);
free(req->host);
free(req);
@@ -387,6 +398,55 @@ http_header_recv(struct netbuf *nb)
return (KORE_RESULT_OK);
}
+int
+http_populate_arguments(struct http_request *req)
+{
+ struct http_arg *q;
+ int i, v, c, count;
+ char *query, *args[HTTP_MAX_QUERY_ARGS], *val[3];
+
+ if (req->method == HTTP_METHOD_POST) {
+ query = http_post_data_text(req);
+ } else {
+ kore_log("HTTP_METHOD_GET not supported for arguments");
+ return (0);
+ }
+
+ count = 0;
+ v = kore_split_string(query, "&", args, HTTP_MAX_QUERY_ARGS);
+ for (i = 0; i < v; i++) {
+ c = kore_split_string(args[i], "=", val, 3);
+ if (c != 2) {
+ kore_log("malformed query argument");
+ continue;
+ }
+
+ q = (struct http_arg *)kore_malloc(sizeof(*q));
+ q->name = kore_strdup(val[0]);
+ q->value = kore_strdup(val[1]);
+ TAILQ_INSERT_TAIL(&(req->arguments), q, list);
+ count++;
+ }
+
+ free(query);
+ return (count);
+}
+
+int
+http_argument_lookup(struct http_request *req, const char *name, char **out)
+{
+ struct http_arg *q;
+
+ TAILQ_FOREACH(q, &(req->arguments), list) {
+ if (!strcmp(q->name, name)) {
+ *out = kore_strdup(q->value);
+ return (KORE_RESULT_OK);
+ }
+ }
+
+ return (KORE_RESULT_ERROR);
+}
+
char *
http_post_data_text(struct http_request *req)
{
@@ -399,6 +459,7 @@ http_post_data_text(struct http_request *req)
text = (char *)kore_malloc(len);
kore_strlcpy(text, (char *)data, len);
+ free(data);
return (text);
}