Skip to content

Commit 8481b79

Browse files
committed
fix: web server stack
1 parent 52c7db0 commit 8481b79

File tree

4 files changed

+72
-65
lines changed

4 files changed

+72
-65
lines changed

library.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
"maintainer": true
1515
}
1616
],
17-
"version": "14.0.1",
17+
"version": "14.0.2",
1818
"frameworks": ["espidf", "arduino"],
1919
"platforms": "espressif32"
2020
}

src/rbwebserver.c

Lines changed: 65 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,11 @@
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

5456
static 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;
5759
static 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

6669
void 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

289292
static 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-
383387
static 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

605608
exit:
606-
if(stopping_task)
609+
if (stopping_task)
607610
xTaskNotify(stopping_task, 0, eNoAction);
608611
vTaskDelete(NULL);
609612
}
610613

611614
TaskHandle_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
}

src/rbwebserver.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ TaskHandle_t rb_web_start(int port);
1717
/**
1818
* \brief Start serving files without mounting the spiffs.
1919
*/
20-
TaskHandle_t rb_web_start_no_spiffs(int port, const char *working_directory_path);
20+
TaskHandle_t rb_web_start_no_spiffs(int port, const char* working_directory_path);
2121

2222
/**
2323
* \brief Stop http server. Pass in the task handle returned by rb_web_start.
@@ -32,27 +32,27 @@ esp_err_t rb_web_add_file(const char* filename, const char* data, size_t len);
3232
/**
3333
* \brief Returns path to root of files served by the web server. Without trailing /.
3434
*/
35-
const char *rb_web_get_files_root(void);
35+
const char* rb_web_get_files_root(void);
3636

3737
/**
3838
* Set a callback to call whenever URL in directory /extra/ is accessed.
3939
*/
4040
void rb_web_set_extra_callback(void (*callback)(const char* request_path, int out_fd));
4141

4242
typedef struct {
43-
const uint8_t *data;
43+
const uint8_t* data;
4444
size_t size;
4545
uint8_t is_gzipped;
4646
} not_found_response_t;
4747

4848
/**
4949
* Set a callback to call whenever a 404 would have been returned.
5050
* Return zero-filled not_found_response_t to continue with 404, otherwise fill in the fields.
51-
*
51+
*
5252
*/
5353
void rb_web_set_not_found_callback(not_found_response_t (*callback)(const char* request_path));
5454

55-
55+
void rb_web_set_task_stack(uint16_t size);
5656

5757
#ifdef __cplusplus
5858
};

src/rbwebserver_internal.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
extern "C" {
88
#endif
99

10-
#define LISTENQ 8 /* second argument to listen() */
10+
#define LISTENQ 2 /* second argument to listen() */
1111
#define MAXLINE 256 /* max length of a line */
1212
#define RIO_BUFSIZE 256
1313
#define FILENAME_SIZE 64

0 commit comments

Comments
 (0)