the net qeueuing functions don't need to return status codes, simplifies a lot of other code that revolves around those.

prepare for POST support
This commit is contained in:
Joris Vink 2013-05-02 14:47:02 +02:00
parent 07f2f83def
commit 60ed3e0fd2
6 changed files with 63 additions and 55 deletions

View File

@ -27,12 +27,19 @@ struct http_header {
TAILQ_ENTRY(http_header) list; TAILQ_ENTRY(http_header) list;
}; };
#define HTTP_METHOD_GET 0
#define HTTP_METHOD_POST 1
#define HTTP_REQUEST_COMPLETE 0x01
struct http_request { struct http_request {
u_int8_t method;
u_int8_t flags;
char *host; char *host;
char *method;
char *path; char *path;
struct connection *owner; struct connection *owner;
struct spdy_stream *stream; struct spdy_stream *stream;
struct netbuf *post_data;
TAILQ_HEAD(, http_header) req_headers; TAILQ_HEAD(, http_header) req_headers;
TAILQ_HEAD(, http_header) resp_headers; TAILQ_HEAD(, http_header) resp_headers;

View File

@ -28,6 +28,10 @@
#define NETBUF_RECV 0 #define NETBUF_RECV 0
#define NETBUF_SEND 1 #define NETBUF_SEND 1
#define NETBUF_CALL_CB_ALWAYS 0x01
#define NETBUF_FORCE_REMOVE 0x02
#define NETBUF_RETAIN 0x04
struct netbuf { struct netbuf {
u_int8_t *buf; u_int8_t *buf;
u_int32_t offset; u_int32_t offset;
@ -58,9 +62,6 @@ struct listener {
#define CONN_READ_POSSIBLE 0x01 #define CONN_READ_POSSIBLE 0x01
#define CONN_WRITE_POSSIBLE 0x02 #define CONN_WRITE_POSSIBLE 0x02
#define NETBUF_CALL_CB_ALWAYS 0x01
#define NETBUF_FORCE_REMOVE 0x02
struct connection { struct connection {
int fd; int fd;
int state; int state;
@ -136,11 +137,11 @@ int net_recv(struct connection *);
int net_send(struct connection *); int net_send(struct connection *);
int net_send_flush(struct connection *); int net_send_flush(struct connection *);
int net_recv_flush(struct connection *); int net_recv_flush(struct connection *);
int net_recv_queue(struct connection *, size_t, int, void net_recv_queue(struct connection *, size_t, int,
struct netbuf **, int (*cb)(struct netbuf *)); struct netbuf **, int (*cb)(struct netbuf *));
int net_recv_expand(struct connection *c, struct netbuf *, size_t, int net_recv_expand(struct connection *c, struct netbuf *, size_t,
int (*cb)(struct netbuf *)); int (*cb)(struct netbuf *));
int net_send_queue(struct connection *, u_int8_t *, size_t, int, void net_send_queue(struct connection *, u_int8_t *, size_t, int,
struct netbuf **, int (*cb)(struct netbuf *)); struct netbuf **, int (*cb)(struct netbuf *));
struct kore_buf *kore_buf_create(u_int32_t); struct kore_buf *kore_buf_create(u_int32_t);
@ -153,7 +154,7 @@ int spdy_stream_get_header(struct spdy_header_block *,
char *, char **); char *, char **);
int spdy_frame_recv(struct netbuf *); int spdy_frame_recv(struct netbuf *);
int spdy_frame_send(struct connection *, u_int16_t, void spdy_frame_send(struct connection *, u_int16_t,
u_int8_t, u_int32_t, u_int32_t); u_int8_t, u_int32_t, u_int32_t);
void spdy_header_block_add(struct spdy_header_block *, void spdy_header_block_add(struct spdy_header_block *,
char *, char *); char *, char *);

View File

@ -58,13 +58,26 @@ http_request_new(struct connection *c, struct spdy_stream *s, char *host,
host, method, path); host, method, path);
req = (struct http_request *)kore_malloc(sizeof(*req)); req = (struct http_request *)kore_malloc(sizeof(*req));
req->flags = 0;
req->owner = c; req->owner = c;
req->stream = s; req->stream = s;
req->post_data = NULL;
req->host = kore_strdup(host); req->host = kore_strdup(host);
req->path = kore_strdup(path); req->path = kore_strdup(path);
req->method = kore_strdup(method);
TAILQ_INIT(&(req->resp_headers)); TAILQ_INIT(&(req->resp_headers));
TAILQ_INIT(&(req->req_headers)); TAILQ_INIT(&(req->req_headers));
if (!strcasecmp(method, "get")) {
req->method = HTTP_METHOD_GET;
req->flags |= HTTP_REQUEST_COMPLETE;
} else if (!strcasecmp(method, "post")) {
req->method = HTTP_METHOD_POST;
} else {
kore_log("invalid method specified in request: %s", method);
http_request_free(req);
return (KORE_RESULT_ERROR);
}
TAILQ_INSERT_TAIL(&http_requests, req, list); TAILQ_INSERT_TAIL(&http_requests, req, list);
if (out != NULL) if (out != NULL)
@ -109,7 +122,6 @@ http_request_free(struct http_request *req)
free(hdr); free(hdr);
} }
free(req->method);
free(req->path); free(req->path);
free(req->host); free(req->host);
free(req); free(req);
@ -140,27 +152,19 @@ http_response(struct http_request *req, int status, u_int8_t *d, u_int32_t len)
if (htext == NULL) if (htext == NULL)
return (KORE_RESULT_ERROR); return (KORE_RESULT_ERROR);
if (!spdy_frame_send(req->owner, SPDY_CTRL_FRAME_SYN_REPLY, spdy_frame_send(req->owner, SPDY_CTRL_FRAME_SYN_REPLY,
0, hlen, req->stream->stream_id)) 0, hlen, req->stream->stream_id);
return (KORE_RESULT_ERROR); net_send_queue(req->owner, htext, hlen, 0, NULL, NULL);
if (!net_send_queue(req->owner, htext, hlen, 0, NULL, NULL)) {
free(htext);
return (KORE_RESULT_ERROR);
}
free(htext); free(htext);
if (len > 0) { if (len > 0) {
if (!spdy_frame_send(req->owner, SPDY_DATA_FRAME, spdy_frame_send(req->owner, SPDY_DATA_FRAME,
0, len, req->stream->stream_id)) 0, len, req->stream->stream_id);
return (KORE_RESULT_ERROR); net_send_queue(req->owner, d, len, 0, NULL, NULL);
if (!net_send_queue(req->owner, d, len, 0, NULL, NULL))
return (KORE_RESULT_ERROR);
} }
if (!spdy_frame_send(req->owner, SPDY_DATA_FRAME, spdy_frame_send(req->owner, SPDY_DATA_FRAME,
FLAG_FIN, 0, req->stream->stream_id)) FLAG_FIN, 0, req->stream->stream_id);
return (KORE_RESULT_ERROR);
} else { } else {
buf = kore_buf_create(KORE_BUF_INITIAL); buf = kore_buf_create(KORE_BUF_INITIAL);
@ -181,14 +185,10 @@ http_response(struct http_request *req, int status, u_int8_t *d, u_int32_t len)
kore_buf_append(buf, (u_int8_t *)"\r\n", 2); kore_buf_append(buf, (u_int8_t *)"\r\n", 2);
htext = kore_buf_release(buf, &hlen); htext = kore_buf_release(buf, &hlen);
if (!net_send_queue(req->owner, htext, hlen, 0, NULL, NULL)) { net_send_queue(req->owner, htext, hlen, 0, NULL, NULL);
free(htext);
return (KORE_RESULT_ERROR);
}
free(htext); free(htext);
if (!net_send_queue(req->owner, d, len, 0, NULL, NULL))
return (KORE_RESULT_ERROR); net_send_queue(req->owner, d, len, 0, NULL, NULL);
} }
return (KORE_RESULT_OK); return (KORE_RESULT_OK);
@ -222,7 +222,7 @@ void
http_process(void) http_process(void)
{ {
struct http_request *req, *next; struct http_request *req, *next;
int r, (*handler)(struct http_request *); int r, (*hdlr)(struct http_request *);
if (TAILQ_EMPTY(&http_requests)) if (TAILQ_EMPTY(&http_requests))
return; return;
@ -230,12 +230,14 @@ http_process(void)
kore_log("http_process()"); kore_log("http_process()");
for (req = TAILQ_FIRST(&http_requests); req != NULL; req = next) { for (req = TAILQ_FIRST(&http_requests); req != NULL; req = next) {
next = TAILQ_NEXT(req, list); next = TAILQ_NEXT(req, list);
if (!(req->flags & HTTP_REQUEST_COMPLETE))
continue;
handler = kore_module_handler_find(req->host, req->path); hdlr = kore_module_handler_find(req->host, req->path);
if (handler == NULL) if (hdlr == NULL)
r = http_generic_404(req); r = http_generic_404(req);
else else
r = handler(req); r = hdlr(req);
if (r != KORE_RESULT_ERROR) if (r != KORE_RESULT_ERROR)
net_send_flush(req->owner); net_send_flush(req->owner);

View File

@ -341,16 +341,14 @@ kore_connection_handle(struct connection *c, int flags)
if (!memcmp(data, "spdy/3", 6)) if (!memcmp(data, "spdy/3", 6))
kore_log("using SPDY/3"); kore_log("using SPDY/3");
c->proto = CONN_PROTO_SPDY; c->proto = CONN_PROTO_SPDY;
if (!net_recv_queue(c, SPDY_FRAME_SIZE, 0, net_recv_queue(c, SPDY_FRAME_SIZE, 0,
NULL, spdy_frame_recv)) NULL, spdy_frame_recv);
return (KORE_RESULT_ERROR);
} else { } else {
kore_log("using HTTP/1.1"); kore_log("using HTTP/1.1");
c->proto = CONN_PROTO_HTTP; c->proto = CONN_PROTO_HTTP;
if (!net_recv_queue(c, HTTP_HEADER_MAX_LEN, net_recv_queue(c, HTTP_HEADER_MAX_LEN,
NETBUF_CALL_CB_ALWAYS, NULL, NETBUF_CALL_CB_ALWAYS, NULL,
http_header_recv)) http_header_recv);
return (KORE_RESULT_ERROR);
} }
c->state = CONN_STATE_ESTABLISHED; c->state = CONN_STATE_ESTABLISHED;

View File

@ -37,7 +37,7 @@
#include "spdy.h" #include "spdy.h"
#include "kore.h" #include "kore.h"
int void
net_send_queue(struct connection *c, u_int8_t *data, size_t len, int flags, net_send_queue(struct connection *c, u_int8_t *data, size_t len, int flags,
struct netbuf **out, int (*cb)(struct netbuf *)) struct netbuf **out, int (*cb)(struct netbuf *))
{ {
@ -63,11 +63,9 @@ net_send_queue(struct connection *c, u_int8_t *data, size_t len, int flags,
TAILQ_INSERT_TAIL(&(c->send_queue), nb, list); TAILQ_INSERT_TAIL(&(c->send_queue), nb, list);
if (out != NULL) if (out != NULL)
*out = nb; *out = nb;
return (KORE_RESULT_OK);
} }
int void
net_recv_queue(struct connection *c, size_t len, int flags, net_recv_queue(struct connection *c, size_t len, int flags,
struct netbuf **out, int (*cb)(struct netbuf *)) struct netbuf **out, int (*cb)(struct netbuf *))
{ {
@ -87,8 +85,6 @@ net_recv_queue(struct connection *c, size_t len, int flags,
TAILQ_INSERT_TAIL(&(c->recv_queue), nb, list); TAILQ_INSERT_TAIL(&(c->recv_queue), nb, list);
if (out != NULL) if (out != NULL)
*out = nb; *out = nb;
return (KORE_RESULT_OK);
} }
int int
@ -217,8 +213,11 @@ net_recv(struct connection *c)
if (nb->offset == nb->len || if (nb->offset == nb->len ||
(nb->flags & NETBUF_FORCE_REMOVE)) { (nb->flags & NETBUF_FORCE_REMOVE)) {
TAILQ_REMOVE(&(c->recv_queue), nb, list); TAILQ_REMOVE(&(c->recv_queue), nb, list);
free(nb->buf);
free(nb); if (!(nb->flags & NETBUF_RETAIN)) {
free(nb->buf);
free(nb);
}
} }
} else { } else {
r = KORE_RESULT_OK; r = KORE_RESULT_OK;

View File

@ -105,14 +105,14 @@ spdy_frame_recv(struct netbuf *nb)
} }
if (r == KORE_RESULT_OK) { if (r == KORE_RESULT_OK) {
r = net_recv_queue(c, SPDY_FRAME_SIZE, net_recv_queue(c, SPDY_FRAME_SIZE,
0, NULL, spdy_frame_recv); 0, NULL, spdy_frame_recv);
} }
return (r); return (r);
} }
int void
spdy_frame_send(struct connection *c, u_int16_t type, u_int8_t flags, spdy_frame_send(struct connection *c, u_int16_t type, u_int8_t flags,
u_int32_t len, u_int32_t stream_id) u_int32_t len, u_int32_t stream_id)
{ {
@ -149,7 +149,7 @@ spdy_frame_send(struct connection *c, u_int16_t type, u_int8_t flags,
break; break;
} }
return (net_send_queue(c, nb, length, 0, NULL, NULL)); net_send_queue(c, nb, length, 0, NULL, NULL);
} }
struct spdy_stream * struct spdy_stream *
@ -414,7 +414,8 @@ spdy_ctrl_frame_ping(struct netbuf *nb)
return (KORE_RESULT_ERROR); return (KORE_RESULT_ERROR);
} }
return (spdy_frame_send(c, SPDY_CTRL_FRAME_PING, 0, 4, id)); spdy_frame_send(c, SPDY_CTRL_FRAME_PING, 0, 4, id);
return (KORE_RESULT_OK);
} }
static int static int