From fc37b081399bdaaab15e350d3d13e7e6317952c2 Mon Sep 17 00:00:00 2001 From: Sergey Lyubka <valenok@gmail.com> Date: Tue, 14 Jan 2014 13:16:58 +0000 Subject: [PATCH] URI handler status code drives streaming behavior --- examples/file.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++ mongoose.c | 31 +++++++++++++++++++++---------- 2 files changed, 68 insertions(+), 10 deletions(-) create mode 100644 examples/file.c diff --git a/examples/file.c b/examples/file.c new file mode 100644 index 000000000..7e571d412 --- /dev/null +++ b/examples/file.c @@ -0,0 +1,47 @@ +#include <stdio.h> +#include <string.h> +#include "mongoose.h" + + +static int index_html(struct mg_connection *conn) { + FILE *fp = (FILE *) conn->connection_param; + char buf[200]; + size_t n = 0; + + if (fp == NULL) { + fp = fopen("../mongoose.c", "r"); + conn->connection_param = (void *) fp; + } + + if (fp != NULL) { + n = fread(buf, 1, sizeof(buf), fp); + mg_send_data(conn, buf, n); + + if (n < sizeof(buf) || conn->wsbits != 0) { + fclose(fp); + conn->connection_param = NULL; + } + } + + return n < sizeof(buf) ? 1 : 0; +} + +int main(void) { + struct mg_server *server; + + // Create and configure the server + server = mg_create_server(NULL); + mg_set_option(server, "listening_port", "8080"); + mg_add_uri_handler(server, "/", index_html); + + // Serve request. Hit Ctrl-C to terminate the program + printf("Starting on port %s\n", mg_get_option(server, "listening_port")); + for (;;) { + mg_poll_server(server, 1000); + } + + // Cleanup, and free server instance + mg_destroy_server(&server); + + return 0; +} diff --git a/mongoose.c b/mongoose.c index f8de146f1..d262a1d04 100644 --- a/mongoose.c +++ b/mongoose.c @@ -1896,6 +1896,19 @@ static void ping_idle_websocket_connection(struct connection *conn, time_t t) { #define ping_idle_websocket_connection(conn, t) #endif // !NO_WEBSOCKET +static void write_terminating_chunk(struct connection *conn) { + mg_write(&conn->mg_conn, "0\r\n\r\n", 5); +} + +static void call_uri_handler(struct connection *conn) { + if (conn->endpoint.uh->handler(&conn->mg_conn)) { + if (conn->flags & CONN_HEADERS_SENT) { + write_terminating_chunk(conn); + } + close_local_endpoint(conn); + } +} + static void write_to_client(struct connection *conn) { struct iobuf *io = &conn->remote_iobuf; int n = conn->ssl == NULL ? send(conn->client_sock, io->buf, io->len, 0) : @@ -1915,6 +1928,12 @@ static void write_to_client(struct connection *conn) { io->len -= n; conn->num_bytes_sent += n; } + + if (conn->endpoint_type == EP_USER) { + conn->mg_conn.wsbits = conn->flags & CONN_CLOSE ? 1 : 0; + call_uri_handler(conn); + } + if (io->len == 0 && conn->flags & CONN_SPOOL_DONE) { conn->flags |= CONN_CLOSE; } @@ -2163,10 +2182,6 @@ static void open_file_endpoint(struct connection *conn, const char *path, #endif // NO_FILESYSTEM -static void write_terminating_chunk(struct connection *conn) { - mg_write(&conn->mg_conn, "0\r\n\r\n", 5); -} - static void call_uri_handler_if_data_is_buffered(struct connection *conn) { struct iobuf *loc = &conn->local_iobuf; struct mg_connection *c = &conn->mg_conn; @@ -2177,12 +2192,8 @@ static void call_uri_handler_if_data_is_buffered(struct connection *conn) { do { } while (deliver_websocket_frame(conn)); } else #endif - if (loc->len >= c->content_len) { - conn->endpoint.uh->handler(c); - if (conn->flags & CONN_HEADERS_SENT) { - write_terminating_chunk(conn); - } - close_local_endpoint(conn); + if (loc->len >= c->content_len) { + call_uri_handler(conn); } } -- GitLab