kore

An easy to use, scalable and secure web application framework for writing web APIs in C.
Commits | Files | Refs | README | LICENSE | git clone https://git.kore.io/kore.git

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:
includes/http.h | 12++++++++++++
src/http.c | 61+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
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); }