1616#include "esp_spiffs.h"
1717#include "freertos/task.h"
1818
19+ #include "rbdns.h"
1920#include "rbwebserver.h"
2021#include "rbwebserver_internal.h"
21- #include "rbdns.h"
22+
23+ #include "mpaland-printf/printf.h"
2224
2325#define TAG "RbWebServer"
2426
@@ -53,29 +55,30 @@ static const mime_map meme_types[] = {
5355
5456static const char * default_mime_type = "text/plain" ;
5557
56- static void (* extra_path_callback )(const char * path , int out_fd ) = NULL ;
58+ static void (* extra_path_callback )(const char * path , int out_fd ) = NULL ;
5759static not_found_response_t (* not_found_callback )(const char * request_path ) = NULL ;
5860
59- static void * ws_protocol = NULL ;
60- static const char * working_directory = "/notset" ;
61+ static void * ws_protocol = NULL ;
62+ static const char * working_directory = "/notset" ;
63+ static uint16_t web_server_stack_size = 3584 ;
6164
62- void rb_web_set_extra_callback (void (* callback )(const char * path , int out_fd )) {
65+ void rb_web_set_extra_callback (void (* callback )(const char * path , int out_fd )) {
6366 extra_path_callback = callback ;
6467}
6568
6669void rb_web_set_not_found_callback (not_found_response_t (* callback )(const char * request_path )) {
6770 not_found_callback = callback ;
6871}
6972
70- void rb_web_set_wsprotocol (void * wsProtocolInstance ) {
71- if (ws_protocol != NULL && ws_protocol != wsProtocolInstance ) {
73+ void rb_web_set_wsprotocol (void * wsProtocolInstance ) {
74+ if (ws_protocol != NULL && ws_protocol != wsProtocolInstance ) {
7275 ESP_LOGE (TAG , "rb_web_set_wsprotocol was called twice with different instances!" );
7376 }
7477 ws_protocol = wsProtocolInstance ;
7578}
7679
77- void rb_web_clear_wsprotocol (void * wsProtocolInstance ) {
78- if (ws_protocol == wsProtocolInstance ) {
80+ void rb_web_clear_wsprotocol (void * wsProtocolInstance ) {
81+ if (ws_protocol == wsProtocolInstance ) {
7982 ws_protocol = NULL ;
8083 } else {
8184 ESP_LOGE (TAG , "rb_web_clear_wsprotocol was called twice with different instance than rb_web_set_wsprotocol!" );
@@ -122,7 +125,7 @@ static ssize_t rio_read(rio_t* rp, char* usrbuf, size_t n) {
122125 rp -> rio_cnt = recv (rp -> rio_fd , rp -> rio_buf ,
123126 sizeof (rp -> rio_buf ), MSG_DONTWAIT );
124127 if (rp -> rio_cnt < 0 ) {
125- if (errno == EAGAIN ) {
128+ if (errno == EAGAIN ) {
126129 vTaskDelay (pdMS_TO_TICKS (10 ));
127130 } else if (errno != EINTR ) /* interrupted by sig handler return */
128131 return -1 ;
@@ -255,40 +258,42 @@ static int prepare_gzip(http_request* req) {
255258 return open (req -> filename , O_RDONLY );
256259}
257260
258- static int is_local_host (const char * hostHeader ) {
261+ static int is_local_host (const char * hostHeader ) {
259262 const int hostHeaderLen = strlen (hostHeader ) - 2 ; // ignore \r\n
260- if (hostHeaderLen < 0 ) {
263+ if (hostHeaderLen < 0 ) {
261264 return true;
262265 }
263266
264- if (hostHeaderLen >= 7 && hostHeaderLen <= 15 ) {
267+ if (hostHeaderLen >= 7 && hostHeaderLen <= 15 ) {
265268 int dots = 0 ;
266269 bool is_ip = true;
267- for (int i = 0 ; i < hostHeaderLen ; ++ i ) {
270+ for (int i = 0 ; i < hostHeaderLen ; ++ i ) {
268271 char c = hostHeader [i ];
269- if (c == '.' ) {
272+ if (c == '.' ) {
270273 ++ dots ;
271- } else if (c < '0' || c > '9' ) {
274+ } else if (c < '0' || c > '9' ) {
272275 is_ip = false;
273276 break ;
274277 }
275278 }
276279
277- if (is_ip && dots == 3 ) {
280+ if (is_ip && dots == 3 ) {
278281 return true;
279282 }
280283 }
281284
282- const char * localHostname = rb_dn_get_local_hostname ();
283- if (strlen (localHostname ) == hostHeaderLen && memcmp (localHostname , hostHeader , hostHeaderLen ) == 0 ) {
285+ const char * localHostname = rb_dn_get_local_hostname ();
286+ if (strlen (localHostname ) == hostHeaderLen && memcmp (localHostname , hostHeader , hostHeaderLen ) == 0 ) {
284287 return true;
285288 }
286289 return false;
287290}
288291
289292static void parse_request (int fd , http_request * req ) {
290293 rio_t rio ;
291- char buf [MAXLINE ], method [10 ], uri [MAXLINE ];
294+ char buf [MAXLINE ];
295+ char uri [128 ];
296+ char method [10 ];
292297
293298 uint8_t websocket_upgrade_headers = 0 ;
294299
@@ -300,7 +305,7 @@ static void parse_request(int fd, http_request* req) {
300305 rio_readinitb (& rio , fd );
301306 rio_readlineb (& rio , buf , MAXLINE );
302307
303- sscanf (buf , "%9s %255s " , method , uri ); /* version is not cared */
308+ sscanf (buf , "%9s %127s " , method , uri ); /* version is not cared */
304309 /* read all */
305310 while (buf [0 ] != '\n' && buf [1 ] != '\n' ) { /* \n || \r\n */
306311 rio_readlineb (& rio , buf , MAXLINE );
@@ -311,24 +316,24 @@ static void parse_request(int fd, http_request* req) {
311316 req -> end ++ ;
312317 } else if (strstr (buf , "Accept-Encoding: " ) == buf && strstr (buf + 17 , "gzip" )) {
313318 req -> servingGzip = 1 ;
314- } else if (strstr (buf , "Upgrade: websocket" ) == buf ) {
319+ } else if (strstr (buf , "Upgrade: websocket" ) == buf ) {
315320 ++ websocket_upgrade_headers ;
316- } else if (strstr (buf , "Connection: " ) == buf && strstr (buf + 12 , "Upgrade" )) {
321+ } else if (strstr (buf , "Connection: " ) == buf && strstr (buf + 12 , "Upgrade" )) {
317322 ++ websocket_upgrade_headers ;
318323 }
319324 // len(Sec-WebSocket-Key: ) + len(key) + \r\n
320- else if (strlen (buf ) == 19 + 24 + 2 && strstr (buf , "Sec-WebSocket-Key: " ) == buf ) {
325+ else if (strlen (buf ) == 19 + 24 + 2 && strstr (buf , "Sec-WebSocket-Key: " ) == buf ) {
321326 ++ websocket_upgrade_headers ;
322327 memcpy (req -> ws_key , buf + 19 , 24 );
323- } else if (strstr (buf , "Sec-WebSocket-Version: " ) == buf ) {
328+ } else if (strstr (buf , "Sec-WebSocket-Version: " ) == buf ) {
324329 sscanf (buf + 23 , "%ld" , & req -> ws_version );
325- } else if (strncmp (buf , "Host: " , 6 ) == 0 ) {
326- req -> non_local_hostname = !is_local_host (buf + 6 );
330+ } else if (strncmp (buf , "Host: " , 6 ) == 0 ) {
331+ req -> non_local_hostname = !is_local_host (buf + 6 );
327332 }
328333 }
329334
330335 // Zero out the version if not all headers were received
331- if (req -> ws_version != 0 && (websocket_upgrade_headers != 3 || strcmp (method , "GET" ) != 0 )) {
336+ if (req -> ws_version != 0 && (websocket_upgrade_headers != 3 || strcmp (method , "GET" ) != 0 )) {
332337 req -> ws_version = 0 ;
333338 }
334339
@@ -369,17 +374,16 @@ void client_error(int fd, int status, const char* msg, const char* longmsg) {
369374 writen (fd , buf , strlen (buf ));
370375}
371376
372- #define REDIRECT_RESPONSE \
373- "HTTP/1.1 302 Temporary Redirect\r\n"\
377+ #define REDIRECT_RESPONSE \
378+ "HTTP/1.1 302 Temporary Redirect\r\n" \
374379 "Location: http://"
375380
376- static void temporary_redirect (int fd , const char * location ) {
377- writen (fd , REDIRECT_RESPONSE , sizeof (REDIRECT_RESPONSE )- 1 );
381+ static void temporary_redirect (int fd , const char * location ) {
382+ writen (fd , REDIRECT_RESPONSE , sizeof (REDIRECT_RESPONSE ) - 1 );
378383 writen (fd , location , strlen (location ));
379384 writen (fd , "\r\n\r\n" , 4 );
380385}
381386
382-
383387static ssize_t sendfile (char * buf , const size_t bufsize , int out_fd , int in_fd , off_t * offset , size_t count ) {
384388 size_t chunk ;
385389 ssize_t res ;
@@ -453,16 +457,15 @@ static void serve_static(int out_fd, int in_fd, http_request* req,
453457 close (out_fd );
454458 break ;
455459 }
456-
457460}
458461
459- static int serve_not_found_cb (int out_fd , http_request * req ) {
460- if (!not_found_callback ) {
462+ static int serve_not_found_cb (int out_fd , http_request * req ) {
463+ if (!not_found_callback ) {
461464 return 0 ;
462465 }
463466
464467 not_found_response_t nfr = not_found_callback (req -> filename + strlen (working_directory ));
465- if (!nfr .data || !nfr .size ) {
468+ if (!nfr .data || !nfr .size ) {
466469 return 0 ;
467470 }
468471
@@ -478,22 +481,23 @@ static int serve_not_found_cb(int out_fd, http_request *req) {
478481 }
479482
480483 off_t pos = req -> offset ;
481- while (pos < req -> end ) {
484+ while (pos < req -> end ) {
482485 size_t chunk = req -> end - pos ;
483- if (chunk > 256 ) chunk = 256 ;
486+ if (chunk > 256 )
487+ chunk = 256 ;
484488 writen (out_fd , nfr .data + pos , chunk );
485489 pos += chunk ;
486490 }
487491
488492 return 1 ;
489493}
490494
491- static void process_serve_file (int fd , struct sockaddr_in * clientaddr , http_request * req ) {
495+ static void process_serve_file (int fd , struct sockaddr_in * clientaddr , http_request * req ) {
492496 struct stat sbuf ;
493497 int status = 200 ;
494498 int ffd = prepare_gzip (req );
495499 if (ffd <= 0 ) {
496- if (!serve_not_found_cb (fd , req )) {
500+ if (!serve_not_found_cb (fd , req )) {
497501 status = 404 ;
498502 client_error (fd , status , "Not found" , "File not found" );
499503 }
@@ -522,29 +526,28 @@ static int process(int fd, struct sockaddr_in* clientaddr) {
522526
523527 parse_request (fd , & req );
524528
525- char * extra_itr ;
529+ char * extra_itr ;
526530
527- if (req .non_local_hostname ) {
531+ if (req .non_local_hostname ) {
528532 temporary_redirect (fd , rb_dn_get_local_hostname ());
529533 return 0 ;
530- } else if (req .ws_version != 0 ) {
531- if (ws_protocol == NULL ) {
534+ } else if (req .ws_version != 0 ) {
535+ if (ws_protocol == NULL ) {
532536 client_error (fd , 400 , "WS not enabled" , "" );
533537 return 0 ;
534538 }
535539
536- if (rb_web_handle_websocket_switch_request (fd , & req ) == 0 ) {
540+ if (rb_web_handle_websocket_switch_request (fd , & req ) == 0 ) {
537541 return 1 ;
538542 }
539543 return 0 ;
540- } else if ((extra_itr = strstr (req .filename , EXTRA_DIRECTORY_SUFFIX )) != NULL &&
541- (extra_itr - req .filename ) == strlen (working_directory )) {
542- if (extra_path_callback == NULL ) {
544+ } else if ((extra_itr = strstr (req .filename , EXTRA_DIRECTORY_SUFFIX )) != NULL && (extra_itr - req .filename ) == strlen (working_directory )) {
545+ if (extra_path_callback == NULL ) {
543546 client_error (fd , 400 , "Error" , "No extra_path_callback specified." );
544547 return 0 ;
545548 }
546549
547- extra_path_callback (extra_itr + sizeof (EXTRA_DIRECTORY_SUFFIX )- 1 , fd );
550+ extra_path_callback (extra_itr + sizeof (EXTRA_DIRECTORY_SUFFIX ) - 1 , fd );
548551 close (fd );
549552 return 0 ;
550553 } else {
@@ -558,12 +561,12 @@ static void tiny_web_task(void* portPtr) {
558561
559562 struct sockaddr_in clientaddr ;
560563 int listenfd , connfd ;
561- socklen_t clientlen = sizeof clientaddr ;
564+ socklen_t clientlen = sizeof ( clientaddr ) ;
562565 TaskHandle_t stopping_task = NULL ;
563566
564567 listenfd = open_listenfd (port );
565568 if (listenfd > 0 ) {
566- ESP_LOGI (TAG , "Listening on port %d" , port );
569+ ESP_LOGD (TAG , "Listening on port %d %d " , port , listenfd );
567570 } else {
568571 ESP_LOGE (TAG , "failed to start: %s" , strerror (errno ));
569572 goto fail ;
@@ -585,7 +588,7 @@ static void tiny_web_task(void* portPtr) {
585588 timeout .tv_usec = 0 ;
586589 setsockopt (connfd , SOL_SOCKET , SO_SNDTIMEO , & timeout , sizeof (timeout ));
587590
588- if (process (connfd , & clientaddr ) <= 0 ) {
591+ if (process (connfd , & clientaddr ) <= 0 ) {
589592 close (connfd );
590593 } else {
591594 rb_web_ws_new_connection (ws_protocol , connfd );
@@ -603,13 +606,13 @@ static void tiny_web_task(void* portPtr) {
603606 xTaskNotifyWait (0 , 0xFFFFFFFF , (uint32_t * )& stopping_task , portMAX_DELAY );
604607
605608exit :
606- if (stopping_task )
609+ if (stopping_task )
607610 xTaskNotify (stopping_task , 0 , eNoAction );
608611 vTaskDelete (NULL );
609612}
610613
611614TaskHandle_t rb_web_start (int port ) {
612- if (!esp_spiffs_mounted (NULL )) {
615+ if (!esp_spiffs_mounted (NULL )) {
613616 esp_vfs_spiffs_conf_t conf = {
614617 .base_path = "/data" ,
615618 .partition_label = NULL ,
@@ -633,10 +636,14 @@ TaskHandle_t rb_web_start(int port) {
633636 return rb_web_start_no_spiffs (port , "/data" );
634637}
635638
636- TaskHandle_t rb_web_start_no_spiffs (int port , const char * working_directory_path ) {
639+ void rb_web_set_task_stack (uint16_t size ) {
640+ web_server_stack_size = size ;
641+ }
642+
643+ TaskHandle_t rb_web_start_no_spiffs (int port , const char * working_directory_path ) {
637644 TaskHandle_t task ;
638645 working_directory = working_directory_path ;
639- xTaskCreate (& tiny_web_task , "rbctrl_web" , 3072 , (void * )port , 2 , & task );
646+ xTaskCreate (& tiny_web_task , "rbctrl_web" , web_server_stack_size , (void * )port , 2 , & task );
640647 return task ;
641648}
642649
@@ -669,6 +676,6 @@ esp_err_t rb_web_add_file(const char* filename, const char* data, size_t len) {
669676 return res ;
670677}
671678
672- const char * rb_web_get_files_root (void ) {
679+ const char * rb_web_get_files_root (void ) {
673680 return working_directory ;
674681}
0 commit comments