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 2401bd1a9f779cfe6737b2e343636ce9c7215c1c
parent f34831c6cbdc8b249dc342022c603b29adc3f120
Author: Joris Vink <joris@coders.se>
Date:   Fri,  3 May 2013 07:35:11 +0200

support for POST in both spdy and normal connections

Diffstat:
includes/kore.h | 1+
src/http.c | 71++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------
src/spdy.c | 4+++-
3 files changed, 68 insertions(+), 8 deletions(-)

diff --git a/includes/kore.h b/includes/kore.h @@ -40,6 +40,7 @@ struct netbuf { u_int8_t flags; void *owner; + void *extra; int (*cb)(struct netbuf *); TAILQ_ENTRY(netbuf) list; diff --git a/src/http.c b/src/http.c @@ -41,7 +41,7 @@ TAILQ_HEAD(, http_request) http_requests; static int http_generic_404(struct http_request *); - +static int http_post_data_recv(struct netbuf *); void http_init(void) { @@ -252,39 +252,52 @@ http_process(void) int http_header_recv(struct netbuf *nb) { - char *p; struct http_header *hdr; struct http_request *req; + struct netbuf *nnb; int h, i, v, skip; + u_int8_t *end_headers, ch; + size_t clen, len, bytes_left; char *request[4], *host[3], *hbuf; - char *headers[HTTP_REQ_HEADER_MAX]; + char *p, *headers[HTTP_REQ_HEADER_MAX]; struct connection *c = (struct connection *)nb->owner; kore_log("http_header_recv(%p)", nb); + ch = nb->buf[nb->len]; nb->buf[nb->len] = '\0'; - if ((p = strrchr((char *)nb->buf, '\r')) == NULL) + + if ((end_headers = (u_int8_t *)strrchr((char *)nb->buf, '\r')) == NULL) return (KORE_RESULT_OK); - if (nb->len > 2 && strncmp((p - 2), "\r\n\r\n", 4)) + if (nb->len > 2 && strncmp(((char *)end_headers - 2), "\r\n\r\n", 4)) return (KORE_RESULT_OK); + nb->buf[nb->len] = ch; nb->flags |= NETBUF_FORCE_REMOVE; - hbuf = kore_strdup((const char *)nb->buf); + end_headers += 2; + + len = end_headers - nb->buf; + hbuf = (char *)kore_malloc(len + 1); + kore_strlcpy(hbuf, (char *)nb->buf, len + 1); h = kore_split_string(hbuf, "\r\n", headers, HTTP_REQ_HEADER_MAX); if (h < 2) { free(hbuf); + kore_log("err 1"); return (KORE_RESULT_ERROR); } - if (strlen(headers[0]) > 3 && strncasecmp(headers[0], "get", 3)) { + if ((strlen(headers[0]) > 3 && strncasecmp(headers[0], "get", 3)) && + (strlen(headers[0]) > 4 && strncasecmp(headers[0], "post", 4))) { free(hbuf); + kore_log("err 2"); return (KORE_RESULT_ERROR); } v = kore_split_string(headers[0], " ", request, 4); if (v != 3) { free(hbuf); + kore_log("err 3"); return (KORE_RESULT_ERROR); } @@ -297,12 +310,14 @@ http_header_recv(struct netbuf *nb) v = kore_split_string(headers[i], ":", host, 3); if (v != 2) { free(hbuf); + kore_log("err 4"); return (KORE_RESULT_ERROR); } if (strlen(host[0]) != 4 || strncasecmp(host[0], "host", 4) || strlen(host[1]) < 4) { free(hbuf); + kore_log("err 5"); return (KORE_RESULT_ERROR); } @@ -313,11 +328,13 @@ http_header_recv(struct netbuf *nb) if (host[0] == NULL) { free(hbuf); + kore_log("err 6"); return (KORE_RESULT_ERROR); } if (!http_request_new(c, NULL, host[1], request[0], request[1], &req)) { free(hbuf); + kore_log("err 7"); return (KORE_RESULT_ERROR); } @@ -339,6 +356,34 @@ http_header_recv(struct netbuf *nb) } free(hbuf); + + if (req->method == HTTP_METHOD_POST) { + if (!http_request_header_get(req, "content-length", &p)) { + kore_log("POST but no content-length"); + TAILQ_REMOVE(&http_requests, req, list); + http_request_free(req); + return (KORE_RESULT_ERROR); + } + + clen = kore_strtonum(p, 0, UINT_MAX, &v); + if (v == KORE_RESULT_ERROR) { + free(p); + kore_log("content-length invalid: %s", p); + TAILQ_REMOVE(&http_requests, req, list); + http_request_free(req); + return (KORE_RESULT_ERROR); + } + + req->post_data = kore_buf_create(clen); + kore_buf_append(req->post_data, end_headers, + (nb->offset - len)); + + bytes_left = clen - (nb->offset - len); + kore_log("need %ld more bytes for POST", bytes_left); + net_recv_queue(c, bytes_left, 0, &nnb, http_post_data_recv); + nnb->extra = req; + } + return (KORE_RESULT_OK); } @@ -350,3 +395,15 @@ http_generic_404(struct http_request *req) return (http_response(req, 404, NULL, 0)); } + +static int +http_post_data_recv(struct netbuf *nb) +{ + struct http_request *req = (struct http_request *)nb->extra; + + kore_buf_append(req->post_data, nb->buf, nb->offset); + kore_log("%s", req->post_data->data); + req->flags |= HTTP_REQUEST_COMPLETE; + + return (KORE_RESULT_OK); +} diff --git a/src/spdy.c b/src/spdy.c @@ -489,9 +489,11 @@ spdy_data_frame_recv(struct netbuf *nb) data.length); if (data.flags & FLAG_FIN) { + kore_buf_append(req->post_data, (u_int8_t *)"\0", 1); + s->flags |= FLAG_FIN; req->flags |= HTTP_REQUEST_COMPLETE; - kore_log("POST request completed"); + kore_log("%s", req->post_data->data); } return (KORE_RESULT_OK);