From d419fb3f25d58f4e15c7ee872794db8abb26b5c2 Mon Sep 17 00:00:00 2001 From: Purple Tentacle Date: Sun, 18 Jan 2026 09:15:31 +0100 Subject: [PATCH 1/2] Fix: Do not fail on socket 0. Only negative numbers indicate an error. 0 is a normal socket, and usually just the first socket to be created. Fixes: https://github.com/starnight/MicroHttpServer/issues/9 --- FreeRTOS/lib/server.c | 2 +- c-version/lib/server.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/FreeRTOS/lib/server.c b/FreeRTOS/lib/server.c index 48fa22d..6bd5c9c 100644 --- a/FreeRTOS/lib/server.c +++ b/FreeRTOS/lib/server.c @@ -42,7 +42,7 @@ void HTTPServerInit(HTTPServer *srv, uint16_t port) { /* Have a server socket. */ srv->sock = socket(AF_INET, SOCK_STREAM, 0); - if(srv->sock <= 0) exit(1); + if(srv->sock < 0) exit(1); /* Set server address. */ memset(&srv_addr, 0, sizeof(srv_addr)); srv_addr.sin_family = AF_INET; diff --git a/c-version/lib/server.c b/c-version/lib/server.c index 48fa22d..6bd5c9c 100644 --- a/c-version/lib/server.c +++ b/c-version/lib/server.c @@ -42,7 +42,7 @@ void HTTPServerInit(HTTPServer *srv, uint16_t port) { /* Have a server socket. */ srv->sock = socket(AF_INET, SOCK_STREAM, 0); - if(srv->sock <= 0) exit(1); + if(srv->sock < 0) exit(1); /* Set server address. */ memset(&srv_addr, 0, sizeof(srv_addr)); srv_addr.sin_family = AF_INET; From f1e8833c538ff4520fbc552ae02fc4c59b3004dc Mon Sep 17 00:00:00 2001 From: Purple Tentacle Date: Sun, 18 Jan 2026 09:26:58 +0100 Subject: [PATCH 2/2] Improvement: Avoid "exit" in the libraries. Using "exit" in a library isn't too great, depending on the application. In an embedded environment, where the application may have other functions, it's better to just return an error. Removes the use of "exit". Adds a return status to HTTPServerInit. Also adds protective checks in HTTPServerRun and HTTPServerClose, if these were called, despite HTTPServerInit failing (so socket was invalid). See: https://github.com/starnight/MicroHttpServer/issues/9 --- FreeRTOS/lib/server.c | 15 ++++++++++++--- FreeRTOS/lib/server.h | 2 +- FreeRTOS/src/main.c | 19 ++++++++++++------- c-version/lib/server.c | 15 ++++++++++++--- c-version/lib/server.h | 2 +- c-version/main.c | 3 ++- 6 files changed, 40 insertions(+), 16 deletions(-) diff --git a/FreeRTOS/lib/server.c b/FreeRTOS/lib/server.c index 6bd5c9c..2e3c150 100644 --- a/FreeRTOS/lib/server.c +++ b/FreeRTOS/lib/server.c @@ -36,13 +36,14 @@ HTTPReq http_req[MAX_HTTP_CLIENT]; uint8_t req_buf[MAX_HTTP_CLIENT][MAX_HEADER_SIZE + MAX_BODY_SIZE]; uint8_t res_buf[MAX_HTTP_CLIENT][MAX_HEADER_SIZE + MAX_BODY_SIZE]; -void HTTPServerInit(HTTPServer *srv, uint16_t port) { +int HTTPServerInit(HTTPServer *srv, uint16_t port) { struct sockaddr_in srv_addr; unsigned int i; /* Have a server socket. */ srv->sock = socket(AF_INET, SOCK_STREAM, 0); - if(srv->sock < 0) exit(1); + if(srv->sock < 0) + return -1; /* Set server address. */ memset(&srv_addr, 0, sizeof(srv_addr)); srv_addr.sin_family = AF_INET; @@ -52,7 +53,8 @@ void HTTPServerInit(HTTPServer *srv, uint16_t port) { setsockopt(srv->sock, SOL_SOCKET, SO_REUSEADDR, &(int){1}, sizeof(int)); /* Bind the server socket with the server address. */ if(bind(srv->sock, (struct sockaddr*) &srv_addr, sizeof(srv_addr)) == -1) { - exit(1); + HTTPServerClose(srv); + return -1; } /* Set the server socket non-blocking. */ fcntl(srv->sock, F_SETFL, O_NONBLOCK); @@ -75,6 +77,7 @@ void HTTPServerInit(HTTPServer *srv, uint16_t port) { http_req[i].clisock = -1; http_req[i].work_state = NOTWORK_SOCKET; } + return 0; } void _HTTPServerAccept(HTTPServer *srv) { @@ -385,6 +388,9 @@ void HTTPServerRun(HTTPServer *srv, HTTPREQ_CALLBACK callback) { struct timeval timeout = {0, 0}; uint16_t i; + if (srv->sock < 0) + return; + /* Copy master socket queue to readable, writeable socket queue. */ readable = srv->_read_sock_pool; writeable = srv->_write_sock_pool; @@ -426,8 +432,11 @@ void HTTPServerRun(HTTPServer *srv, HTTPREQ_CALLBACK callback) { } void HTTPServerClose(HTTPServer *srv) { + if (srv->sock < 0) + return; shutdown(srv->sock, SHUT_RDWR); close((srv)->sock); + srv->sock = -1; } #ifdef MICRO_HTTP_SERVER_EXAMPLE diff --git a/FreeRTOS/lib/server.h b/FreeRTOS/lib/server.h index 7c6c4a3..d1d80d7 100644 --- a/FreeRTOS/lib/server.h +++ b/FreeRTOS/lib/server.h @@ -78,7 +78,7 @@ typedef struct _HTTPResMessage { typedef void (*HTTPREQ_CALLBACK)(HTTPReqMessage *, HTTPResMessage *); -void HTTPServerInit(HTTPServer *, uint16_t); +int HTTPServerInit(HTTPServer *, uint16_t); void HTTPServerRun(HTTPServer *, HTTPREQ_CALLBACK); #define HTTPServerRunLoop(srv, callback) { \ while(1) { \ diff --git a/FreeRTOS/src/main.c b/FreeRTOS/src/main.c index 7bdff5b..33b63cb 100644 --- a/FreeRTOS/src/main.c +++ b/FreeRTOS/src/main.c @@ -47,14 +47,19 @@ void MicroHTTPServer_task() { AddRoute(HTTP_POST, "/fib", Fib); AddRoute(HTTP_POST, "/led", LED); USART_Printf(USART2, "Going to start Micro HTTP Server.\r\n"); - HTTPServerInit(&srv, MHS_PORT); - USART_Printf(USART2, "Micro HTTP Server started and listening.\r\n"); - while(1) { - HTTPServerRun(&srv, Dispatch); - /* Reschedule after each HTTP server run turn. */ - vTaskDelay(10); + if (HTTPServerInit(&srv, MHS_PORT) < 0) { + USART_Printf(USART2, "Micro HTTP Server initialzation failed.\r\n"); + } + else + { + USART_Printf(USART2, "Micro HTTP Server started and listening.\r\n"); + while(1) { + HTTPServerRun(&srv, Dispatch); + /* Reschedule after each HTTP server run turn. */ + vTaskDelay(10); + } + HTTPServerClose(&srv); } - HTTPServerClose(&srv); vTaskDelete(NULL); } diff --git a/c-version/lib/server.c b/c-version/lib/server.c index 6bd5c9c..2e3c150 100644 --- a/c-version/lib/server.c +++ b/c-version/lib/server.c @@ -36,13 +36,14 @@ HTTPReq http_req[MAX_HTTP_CLIENT]; uint8_t req_buf[MAX_HTTP_CLIENT][MAX_HEADER_SIZE + MAX_BODY_SIZE]; uint8_t res_buf[MAX_HTTP_CLIENT][MAX_HEADER_SIZE + MAX_BODY_SIZE]; -void HTTPServerInit(HTTPServer *srv, uint16_t port) { +int HTTPServerInit(HTTPServer *srv, uint16_t port) { struct sockaddr_in srv_addr; unsigned int i; /* Have a server socket. */ srv->sock = socket(AF_INET, SOCK_STREAM, 0); - if(srv->sock < 0) exit(1); + if(srv->sock < 0) + return -1; /* Set server address. */ memset(&srv_addr, 0, sizeof(srv_addr)); srv_addr.sin_family = AF_INET; @@ -52,7 +53,8 @@ void HTTPServerInit(HTTPServer *srv, uint16_t port) { setsockopt(srv->sock, SOL_SOCKET, SO_REUSEADDR, &(int){1}, sizeof(int)); /* Bind the server socket with the server address. */ if(bind(srv->sock, (struct sockaddr*) &srv_addr, sizeof(srv_addr)) == -1) { - exit(1); + HTTPServerClose(srv); + return -1; } /* Set the server socket non-blocking. */ fcntl(srv->sock, F_SETFL, O_NONBLOCK); @@ -75,6 +77,7 @@ void HTTPServerInit(HTTPServer *srv, uint16_t port) { http_req[i].clisock = -1; http_req[i].work_state = NOTWORK_SOCKET; } + return 0; } void _HTTPServerAccept(HTTPServer *srv) { @@ -385,6 +388,9 @@ void HTTPServerRun(HTTPServer *srv, HTTPREQ_CALLBACK callback) { struct timeval timeout = {0, 0}; uint16_t i; + if (srv->sock < 0) + return; + /* Copy master socket queue to readable, writeable socket queue. */ readable = srv->_read_sock_pool; writeable = srv->_write_sock_pool; @@ -426,8 +432,11 @@ void HTTPServerRun(HTTPServer *srv, HTTPREQ_CALLBACK callback) { } void HTTPServerClose(HTTPServer *srv) { + if (srv->sock < 0) + return; shutdown(srv->sock, SHUT_RDWR); close((srv)->sock); + srv->sock = -1; } #ifdef MICRO_HTTP_SERVER_EXAMPLE diff --git a/c-version/lib/server.h b/c-version/lib/server.h index 7c6c4a3..d1d80d7 100644 --- a/c-version/lib/server.h +++ b/c-version/lib/server.h @@ -78,7 +78,7 @@ typedef struct _HTTPResMessage { typedef void (*HTTPREQ_CALLBACK)(HTTPReqMessage *, HTTPResMessage *); -void HTTPServerInit(HTTPServer *, uint16_t); +int HTTPServerInit(HTTPServer *, uint16_t); void HTTPServerRun(HTTPServer *, HTTPREQ_CALLBACK); #define HTTPServerRunLoop(srv, callback) { \ while(1) { \ diff --git a/c-version/main.c b/c-version/main.c index 699911e..19cd711 100644 --- a/c-version/main.c +++ b/c-version/main.c @@ -21,7 +21,8 @@ int main(void) { AddRoute(HTTP_GET, "/", HelloPage); AddRoute(HTTP_POST, "/fib", Fib); /* Initial the HTTP server and make it listening on MHS_PORT. */ - HTTPServerInit(&srv, MHS_PORT); + if (HTTPServerInit(&srv, MHS_PORT) < 0) + return -1; /* Run the HTTP server forever. */ /* Run the dispatch callback if there is a new request */ HTTPServerRunLoop(&srv, Dispatch);