Support reply data defered

Signed-off-by: Jianhui Zhao <zhaojh329@gmail.com>
main
Jianhui Zhao 2020-09-08 22:37:36 +08:00
parent 17f7ccf2c9
commit 9410e7eca9
4 changed files with 26 additions and 9 deletions

View File

@ -49,6 +49,7 @@ static void on_request(struct uh_connection *conn)
conn->chunk_printf(conn, "User-Agent: %.*s\n", ua.len, ua.p); conn->chunk_printf(conn, "User-Agent: %.*s\n", ua.len, ua.p);
conn->chunk_printf(conn, "Body: %.*s\n", body.len, body.p); conn->chunk_printf(conn, "Body: %.*s\n", body.len, body.p);
conn->chunk_end(conn); conn->chunk_end(conn);
conn->done(conn);
} else { } else {
conn->serve_file(conn, docroot, index_page); conn->serve_file(conn, docroot, index_page);
} }

View File

@ -36,6 +36,14 @@
#include "file.h" #include "file.h"
#include "ssl.h" #include "ssl.h"
static void conn_done(struct uh_connection *conn)
{
buffer_pull(&conn->rb, NULL, buffer_length(&conn->rb));
if (!http_should_keep_alive(&conn->parser))
conn->flags |= CONN_F_SEND_AND_CLOSE;
ev_io_start(conn->srv->loop, &conn->iow);
}
static void conn_send(struct uh_connection *conn, const void *data, ssize_t len) static void conn_send(struct uh_connection *conn, const void *data, ssize_t len)
{ {
@ -142,6 +150,8 @@ static void conn_error(struct uh_connection *conn, int code, const char *reason)
conn_send(conn, reason, strlen(reason)); conn_send(conn, reason, strlen(reason));
conn->flags |= CONN_F_SEND_AND_CLOSE; conn->flags |= CONN_F_SEND_AND_CLOSE;
conn_done(conn);
} }
static void conn_redirect(struct uh_connection *conn, int code, const char *location, ...) static void conn_redirect(struct uh_connection *conn, int code, const char *location, ...)
@ -161,6 +171,8 @@ static void conn_redirect(struct uh_connection *conn, int code, const char *loca
conn_printf(conn, "Content-Length: 0\r\n"); conn_printf(conn, "Content-Length: 0\r\n");
conn_send(conn, "\r\n", 2); conn_send(conn, "\r\n", 2);
conn_done(conn);
} }
static enum http_method conn_get_method(struct uh_connection *conn) static enum http_method conn_get_method(struct uh_connection *conn)
@ -245,10 +257,14 @@ static int on_message_begin_cb(struct http_parser *parser)
struct uh_connection *conn = (struct uh_connection *)parser->data; struct uh_connection *conn = (struct uh_connection *)parser->data;
struct uh_request *req = &conn->req; struct uh_request *req = &conn->req;
memset(req, 0, sizeof(struct uh_request));
req->last_was_header_value = true; req->last_was_header_value = true;
http_parser_url_init(&conn->url_parser); http_parser_url_init(&conn->url_parser);
ev_timer_start(conn->srv->loop, &conn->timer);
return 0; return 0;
} }
@ -331,23 +347,20 @@ static bool run_plugins(struct uh_connection *conn)
static int on_message_complete_cb(struct http_parser *parser) static int on_message_complete_cb(struct http_parser *parser)
{ {
struct uh_connection *conn = (struct uh_connection *)parser->data; struct uh_connection *conn = (struct uh_connection *)parser->data;
struct uh_server *srv = conn->srv;
struct uh_request *req = &conn->req; struct uh_request *req = &conn->req;
ev_timer_stop(srv->loop, &conn->timer);
http_parser_parse_url(O2D(conn, req->url.offset), req->url.length, false, &conn->url_parser); http_parser_parse_url(O2D(conn, req->url.offset), req->url.length, false, &conn->url_parser);
if (!run_plugins(conn)) { if (!run_plugins(conn)) {
if (conn->srv->on_request) if (srv->on_request)
conn->srv->on_request(conn); srv->on_request(conn);
else else
conn_error(conn, HTTP_STATUS_NOT_FOUND, NULL); conn_error(conn, HTTP_STATUS_NOT_FOUND, NULL);
} }
buffer_pull(&conn->rb, NULL, buffer_length(&conn->rb));
memset(req, 0, sizeof(struct uh_request));
ev_io_start(conn->srv->loop, &conn->iow);
return 0; return 0;
} }
@ -447,7 +460,7 @@ static void conn_write_cb(struct ev_loop *loop, struct ev_io *w, int revents)
conn->file.fd = -1; conn->file.fd = -1;
} }
if ((conn->flags & CONN_F_SEND_AND_CLOSE) || !http_should_keep_alive(&conn->parser)) if (conn->flags & CONN_F_SEND_AND_CLOSE)
conn_free(conn); conn_free(conn);
else else
ev_io_stop(loop, w); ev_io_stop(loop, w);
@ -577,6 +590,7 @@ struct uh_connection *uh_new_connection(struct uh_server *srv, int sock, struct
conn->parser.data = conn; conn->parser.data = conn;
conn->free = conn_free; conn->free = conn_free;
conn->done = conn_done;
conn->send = conn_send; conn->send = conn_send;
conn->send_file = conn_send_file; conn->send_file = conn_send_file;
conn->printf = conn_printf; conn->printf = conn_printf;

View File

@ -95,6 +95,7 @@ struct uh_connection {
struct uh_connection *prev; struct uh_connection *prev;
struct uh_connection *next; struct uh_connection *next;
void (*free)(struct uh_connection *conn); void (*free)(struct uh_connection *conn);
void (*done)(struct uh_connection *conn); /* Must be called at last, if not call 'error', 'redirect' and 'serve_file' */
void (*send)(struct uh_connection *conn, const void *data, ssize_t len); void (*send)(struct uh_connection *conn, const void *data, ssize_t len);
void (*send_file)(struct uh_connection *conn, const char *path); void (*send_file)(struct uh_connection *conn, const char *path);
void (*printf)(struct uh_connection *conn, const char *format, ...); void (*printf)(struct uh_connection *conn, const char *format, ...);

View File

@ -229,4 +229,5 @@ void serve_file(struct uh_connection *conn, const char *docroot, const char *ind
return; return;
conn->send_file(conn, fullpath); conn->send_file(conn, fullpath);
conn->done(conn);
} }