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;
};
#define HTTP_METHOD_GET 0
#define HTTP_METHOD_POST 1
#define HTTP_REQUEST_COMPLETE 0x01
struct http_request {
u_int8_t method;
u_int8_t flags;
char *host;
char *method;
char *path;
struct connection *owner;
struct spdy_stream *stream;
struct netbuf *post_data;
TAILQ_HEAD(, http_header) req_headers;
TAILQ_HEAD(, http_header) resp_headers;

View File

@ -28,6 +28,10 @@
#define NETBUF_RECV 0
#define NETBUF_SEND 1
#define NETBUF_CALL_CB_ALWAYS 0x01
#define NETBUF_FORCE_REMOVE 0x02
#define NETBUF_RETAIN 0x04
struct netbuf {
u_int8_t *buf;
u_int32_t offset;
@ -58,9 +62,6 @@ struct listener {
#define CONN_READ_POSSIBLE 0x01
#define CONN_WRITE_POSSIBLE 0x02
#define NETBUF_CALL_CB_ALWAYS 0x01
#define NETBUF_FORCE_REMOVE 0x02
struct connection {
int fd;
int state;
@ -136,11 +137,11 @@ int net_recv(struct connection *);
int net_send(struct connection *);
int net_send_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 *));
int net_recv_expand(struct connection *c, struct netbuf *, size_t,
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 kore_buf *kore_buf_create(u_int32_t);
@ -153,7 +154,7 @@ int spdy_stream_get_header(struct spdy_header_block *,
char *, char **);
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);
void spdy_header_block_add(struct spdy_header_block *,
char *, char *);

View File

@ -58,13 +58,26 @@ http_request_new(struct connection *c, struct spdy_stream *s, char *host,
host, method, path);
req = (struct http_request *)kore_malloc(sizeof(*req));
req->flags = 0;
req->owner = c;
req->stream = s;
req->post_data = NULL;
req->host = kore_strdup(host);
req->path = kore_strdup(path);
req->method = kore_strdup(method);
TAILQ_INIT(&(req->resp_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);
if (out != NULL)
@ -109,7 +122,6 @@ http_request_free(struct http_request *req)
free(hdr);
}
free(req->method);
free(req->path);
free(req->host);
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)
return (KORE_RESULT_ERROR);
if (!spdy_frame_send(req->owner, SPDY_CTRL_FRAME_SYN_REPLY,
0, hlen, req->stream->stream_id))
return (KORE_RESULT_ERROR);
if (!net_send_queue(req->owner, htext, hlen, 0, NULL, NULL)) {
free(htext);
return (KORE_RESULT_ERROR);
}
spdy_frame_send(req->owner, SPDY_CTRL_FRAME_SYN_REPLY,
0, hlen, req->stream->stream_id);
net_send_queue(req->owner, htext, hlen, 0, NULL, NULL);
free(htext);
if (len > 0) {
if (!spdy_frame_send(req->owner, SPDY_DATA_FRAME,
0, len, req->stream->stream_id))
return (KORE_RESULT_ERROR);
if (!net_send_queue(req->owner, d, len, 0, NULL, NULL))
return (KORE_RESULT_ERROR);
spdy_frame_send(req->owner, SPDY_DATA_FRAME,
0, len, req->stream->stream_id);
net_send_queue(req->owner, d, len, 0, NULL, NULL);
}
if (!spdy_frame_send(req->owner, SPDY_DATA_FRAME,
FLAG_FIN, 0, req->stream->stream_id))
return (KORE_RESULT_ERROR);
spdy_frame_send(req->owner, SPDY_DATA_FRAME,
FLAG_FIN, 0, req->stream->stream_id);
} else {
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);
htext = kore_buf_release(buf, &hlen);
if (!net_send_queue(req->owner, htext, hlen, 0, NULL, NULL)) {
free(htext);
return (KORE_RESULT_ERROR);
}
net_send_queue(req->owner, htext, hlen, 0, NULL, NULL);
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);
@ -222,7 +222,7 @@ void
http_process(void)
{
struct http_request *req, *next;
int r, (*handler)(struct http_request *);
int r, (*hdlr)(struct http_request *);
if (TAILQ_EMPTY(&http_requests))
return;
@ -230,12 +230,14 @@ http_process(void)
kore_log("http_process()");
for (req = TAILQ_FIRST(&http_requests); req != NULL; req = next) {
next = TAILQ_NEXT(req, list);
if (!(req->flags & HTTP_REQUEST_COMPLETE))
continue;
handler = kore_module_handler_find(req->host, req->path);
if (handler == NULL)
hdlr = kore_module_handler_find(req->host, req->path);
if (hdlr == NULL)
r = http_generic_404(req);
else
r = handler(req);
r = hdlr(req);
if (r != KORE_RESULT_ERROR)
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))
kore_log("using SPDY/3");
c->proto = CONN_PROTO_SPDY;
if (!net_recv_queue(c, SPDY_FRAME_SIZE, 0,
NULL, spdy_frame_recv))
return (KORE_RESULT_ERROR);
net_recv_queue(c, SPDY_FRAME_SIZE, 0,
NULL, spdy_frame_recv);
} else {
kore_log("using HTTP/1.1");
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,
http_header_recv))
return (KORE_RESULT_ERROR);
http_header_recv);
}
c->state = CONN_STATE_ESTABLISHED;

View File

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

View File

@ -105,14 +105,14 @@ spdy_frame_recv(struct netbuf *nb)
}
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);
}
return (r);
}
int
void
spdy_frame_send(struct connection *c, u_int16_t type, u_int8_t flags,
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;
}
return (net_send_queue(c, nb, length, 0, NULL, NULL));
net_send_queue(c, nb, length, 0, NULL, NULL);
}
struct spdy_stream *
@ -414,7 +414,8 @@ spdy_ctrl_frame_ping(struct netbuf *nb)
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