From 6d45ec59dcb202e54c5532514a08891df2368f07 Mon Sep 17 00:00:00 2001 From: Chewing_Bever Date: Thu, 25 May 2023 09:26:53 +0200 Subject: [PATCH] refactor: make code a bit cleaner n stuff --- src/event_loop/event_loop_conn.c | 163 +++++++++++++-------------- src/event_loop/event_loop_consts.c | 11 ++ src/event_loop/event_loop_internal.h | 5 + 3 files changed, 93 insertions(+), 86 deletions(-) create mode 100644 src/event_loop/event_loop_consts.c diff --git a/src/event_loop/event_loop_conn.c b/src/event_loop/event_loop_conn.c index bdc5160..0cca6aa 100644 --- a/src/event_loop/event_loop_conn.c +++ b/src/event_loop/event_loop_conn.c @@ -14,47 +14,46 @@ #include "event_loop_internal.h" -const char http_200_ok[] = "HTTP/1.1 200 OK\nContent-Length: 5\n\nhello"; +void event_loop_conn_io_res(event_loop_conn *conn) { + while (1) { + ssize_t res = 0; + size_t remain = conn->wbuf_size - conn->wbuf_sent; -bool event_loop_conn_io_res(event_loop_conn *conn) { - ssize_t res = 0; - size_t remain = conn->wbuf_size - conn->wbuf_sent; + do { + res = write(conn->fd, &conn->wbuf[conn->wbuf_sent], remain); + } while (res < 0 && errno == EINTR); - do { - res = write(conn->fd, &conn->wbuf[conn->wbuf_sent], remain); - } while (res < 0 && errno == EINTR); + // EAGAIN doesn't mean there was an error, but rather that there's no more + // data right now, but there might be more later, aka "try again later" + if (res < 0 && errno == EAGAIN) { + return; + } - // EAGAIN doesn't mean there was an error, but rather that there's no more - // data right now, but there might be more later, aka "try again later" - if (res < 0 && errno == EAGAIN) { - return false; + // If it's not EGAIN, there was an error writing so we simply end the + // request + if (res < 0) { + conn->state = event_loop_conn_state_end; + return; + } + + conn->wbuf_sent += (size_t)res; + + // After writing a response, we switch back to request mode to process a + // next request + if (conn->wbuf_sent == conn->wbuf_size) { + conn->state = conn->close_after_write ? event_loop_conn_state_end + : event_loop_conn_state_req; + /* c->wbuf_sent = 0; */ + /* c->wbuf_size = 0; */ + + return; + } } - - // If it's not EGAIN, there was an error writing so we simply end the request - if (res < 0) { - conn->state = event_loop_conn_state_end; - return false; - } - - conn->wbuf_sent += (size_t)res; - - // After writing a response, we switch back to request mode to process a next - // request - if (conn->wbuf_sent == conn->wbuf_size) { - conn->state = conn->close_after_write ? event_loop_conn_state_end - : event_loop_conn_state_req; - /* c->wbuf_sent = 0; */ - /* c->wbuf_size = 0; */ - - return false; - } - - // still got some data in wbuf, could try to write again - return true; } -bool try_one_request(event_loop_conn *conn) { - // We definitely can't do anything with zero bytes. +bool event_loop_handle_request(event_loop_conn *conn) { + // Prevents the request handler function from looping indefinitely without + // ever consuming new data if (conn->rbuf_size == 0) { return false; } @@ -117,76 +116,68 @@ bool try_one_request(event_loop_conn *conn) { * * Returns whether the function should be retried immediately or not. */ -bool event_loop_conn_io_req(event_loop_conn *conn) { - ssize_t res; - size_t cap = EVENT_LOOP_BUFFER_SIZE - conn->rbuf_size; +void event_loop_conn_io_req(event_loop_conn *conn) { + while (1) { + ssize_t res; + size_t cap = EVENT_LOOP_BUFFER_SIZE - conn->rbuf_size; - // Try to read at most cap bytes from the file descriptor - do { - res = read(conn->fd, &conn->rbuf[conn->rbuf_size], cap); - } while (res < 0 && errno == EINTR); + // Try to read at most cap bytes from the file descriptor + do { + res = read(conn->fd, &conn->rbuf[conn->rbuf_size], cap); + } while (res < 0 && errno == EINTR); - // EGAIN means we try again later - if (res < 0 && errno == EAGAIN) { - return false; - } + // EGAIN means we try again later + if (res < 0 && errno == EAGAIN) { + return; + } - // Any other negative error message means the read errored out - if (res < 0) { - conn->state = event_loop_conn_state_end; + // Any other negative error message means the read errored out + if (res < 0) { + conn->state = event_loop_conn_state_end; - return false; - } + return; + } - // Output of 0 and no error means we've reached the end of the input. We run - // try_one_request one more time and close the connection if this doesn't - // change the result. - if (res == 0) { - conn->state = event_loop_conn_state_end; + // Output of 0 and no error means we've reached the end of the input. We run + // try_one_request one more time and close the connection if this doesn't + // change the result. + if (res == 0) { + conn->state = event_loop_conn_state_end; - return false; - } + return; + } - // We switch to processing mode if we've reached the end of the data stream, - // or if the read buffer is filled - /* if (res == 0 || c->rbuf_size == MAX_MSG_SIZE) { */ - /* c->state = STATE_PROCESS; */ - /* return false; */ - /* } */ + // We switch to processing mode if we've reached the end of the data stream, + // or if the read buffer is filled + /* if (res == 0 || c->rbuf_size == MAX_MSG_SIZE) { */ + /* c->state = STATE_PROCESS; */ + /* return false; */ + /* } */ - conn->rbuf_size += (size_t)res; + conn->rbuf_size += (size_t)res; - /* assert(conn->rbuf_size <= sizeof(conn->rbuf)); */ + /* assert(conn->rbuf_size <= sizeof(conn->rbuf)); */ - // Try to process requests one by one. - // Try to process requests one by one. - // Why is there a loop? Please read the explanation of "pipelining". - while (try_one_request(conn)) { - }; + // Try to process requests one by one. + // Try to process requests one by one. + // Why is there a loop? Please read the explanation of "pipelining". + while (event_loop_handle_request(conn)) { + }; - // We can keep reading as long as we're in request mode - return conn->state == event_loop_conn_state_req; - /* while (try_one_request(conn)) {} */ - /* return (conn->state == STATE_REQ); */ -} - -void conn_state_res(event_loop_conn *conn) { - while (event_loop_conn_io_res(conn)) { - } -} - -void conn_state_req(event_loop_conn *conn) { - while (event_loop_conn_io_req(conn)) { + // We can keep reading as long as we're in request mode + if (conn->state != event_loop_conn_state_req) { + return; + }; } } void event_loop_conn_io(event_loop_conn *conn) { switch (conn->state) { case event_loop_conn_state_req: - conn_state_req(conn); + event_loop_conn_io_req(conn); break; case event_loop_conn_state_res: - conn_state_res(conn); + event_loop_conn_io_res(conn); break; case event_loop_conn_state_end: printf("we shouldn't be here\n"); diff --git a/src/event_loop/event_loop_consts.c b/src/event_loop/event_loop_consts.c new file mode 100644 index 0000000..87419e7 --- /dev/null +++ b/src/event_loop/event_loop_consts.c @@ -0,0 +1,11 @@ +#include + +const char http_404[] = "HTTP/1.1 404 Not Found\n" + "Connection: close\n" + "Content-Length: 0\n\n"; +const size_t http_404_len = sizeof(http_404) - 1; + +const char http_500[] = "HTTP/1.1 500 Internal Server Error\n" + "Connection: close\n" + "Content-Length: 0\n\n"; +const size_t http_500_len = sizeof(http_500) - 1; diff --git a/src/event_loop/event_loop_internal.h b/src/event_loop/event_loop_internal.h index ef10191..34c22b3 100644 --- a/src/event_loop/event_loop_internal.h +++ b/src/event_loop/event_loop_internal.h @@ -53,4 +53,9 @@ int event_loop_accept(event_loop *loop, int fd); void event_loop_conn_io(event_loop_conn *conn); +extern const char http_404[]; +extern const size_t http_404_len; +extern const char http_500[]; +extern const size_t http_500_len; + #endif