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.
This commit is contained in:
Joris Vink 2013-05-03 09:09:27 +02:00
parent b3cdccbc87
commit a88b8de6a2
2 changed files with 73 additions and 0 deletions

View File

@ -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 */

View File

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