commit 4ed4f76e44a39cb4cbd7803364f9d9f9c8cb4e4d
parent f61bbe8ff42863af238573cd63d73b3ad16a9a30
Author: Joris Vink <joris@coders.se>
Date: Thu, 2 May 2013 17:14:07 +0200
allow POST to work with spdy, all POST data is stored in the httpreq->post_data field. (as a kore_buf)
Diffstat:
2 files changed, 60 insertions(+), 3 deletions(-)
diff --git a/includes/http.h b/includes/http.h
@@ -39,7 +39,7 @@ struct http_request {
char *path;
struct connection *owner;
struct spdy_stream *stream;
- struct netbuf *post_data;
+ struct kore_buf *post_data;
TAILQ_HEAD(, http_header) req_headers;
TAILQ_HEAD(, http_header) resp_headers;
diff --git a/src/spdy.c b/src/spdy.c
@@ -41,6 +41,7 @@ static int spdy_ctrl_frame_syn_stream(struct netbuf *);
static int spdy_ctrl_frame_settings(struct netbuf *);
static int spdy_ctrl_frame_ping(struct netbuf *);
static int spdy_ctrl_frame_window(struct netbuf *);
+static int spdy_data_frame_recv(struct netbuf *);
static int spdy_zlib_inflate(struct connection *, u_int8_t *,
size_t, u_int8_t **, u_int32_t *);
@@ -50,7 +51,9 @@ static int spdy_zlib_deflate(struct connection *, u_int8_t *,
int
spdy_frame_recv(struct netbuf *nb)
{
+ struct spdy_stream *s;
struct spdy_ctrl_frame ctrl;
+ struct spdy_data_frame data;
int (*cb)(struct netbuf *), r;
struct connection *c = (struct connection *)nb->owner;
@@ -100,8 +103,20 @@ spdy_frame_recv(struct netbuf *nb)
r = KORE_RESULT_OK;
}
} else {
- r = KORE_RESULT_ERROR;
- kore_log("received data frame, can't handle that yet.");
+ data.stream_id = net_read32(nb->buf) & ~(1 << 31);
+ if ((s = spdy_stream_lookup(c, data.stream_id)) == NULL) {
+ kore_log("received data frame for non existing stream");
+ r = KORE_RESULT_ERROR;
+ } else if (s->flags & FLAG_FIN) {
+ kore_log("received data frame but FLAG_FIN was set");
+ r = KORE_RESULT_ERROR;
+ } else {
+ data.flags = *(u_int8_t *)(nb->buf + 4);
+ data.length = net_read32(nb->buf + 4) & 0xffffff;
+
+ r = net_recv_expand(c, nb, data.length,
+ spdy_data_frame_recv);
+ }
}
if (r == KORE_RESULT_OK) {
@@ -373,8 +388,12 @@ spdy_ctrl_frame_syn_stream(struct netbuf *nb)
GET_HEADER(":path", &path);
GET_HEADER(":method", &method);
GET_HEADER(":host", &host);
+
if (!http_request_new(c, s, host, method, path,
(struct http_request **)&(s->httpreq))) {
+ free(path);
+ free(method);
+ free(host);
free(s->hblock->header_block);
free(s->hblock);
free(s);
@@ -432,6 +451,44 @@ spdy_ctrl_frame_window(struct netbuf *nb)
}
static int
+spdy_data_frame_recv(struct netbuf *nb)
+{
+ struct spdy_stream *s;
+ struct http_request *req;
+ struct spdy_data_frame data;
+ struct connection *c = (struct connection *)nb->owner;
+
+ data.stream_id = net_read32(nb->buf) & ~(1 << 31);
+ data.flags = *(u_int8_t *)(nb->buf + 4);
+ data.length = net_read32(nb->buf + 4) & 0xffffff;
+ kore_log("SPDY_SESSION_DATA: %d:%d:%d", data.stream_id,
+ data.flags, data.length);
+
+ if ((s = spdy_stream_lookup(c, data.stream_id)) == NULL) {
+ kore_log("session data for incorrect stream");
+ return (KORE_RESULT_OK);
+ }
+
+ req = (struct http_request *)s->httpreq;
+ if (req->method != HTTP_METHOD_POST) {
+ kore_log("data frame for non post received");
+ return (KORE_RESULT_ERROR);
+ }
+
+ if (req->post_data == NULL)
+ req->post_data = kore_buf_create(data.length);
+ kore_buf_append(req->post_data, (nb->buf + SPDY_FRAME_SIZE),
+ data.length);
+
+ if (data.flags & FLAG_FIN) {
+ req->flags |= HTTP_REQUEST_COMPLETE;
+ kore_log("POST request completed");
+ }
+
+ return (KORE_RESULT_OK);
+}
+
+static int
spdy_zlib_inflate(struct connection *c, u_int8_t *src, size_t len,
u_int8_t **dst, u_int32_t *olen)
{