From dde568f62008b90054d2a65949c995923b150511 Mon Sep 17 00:00:00 2001 From: Bogdan Date: Fri, 28 Oct 2022 09:33:12 +0200 Subject: [PATCH 1/6] prepare rework http server --- include/HTTPServer.h | 1 + src/HTTPServer.c | 56 +++++++++++++++++++++++++++++++++----------- 2 files changed, 43 insertions(+), 14 deletions(-) diff --git a/include/HTTPServer.h b/include/HTTPServer.h index cf1857f..b538c32 100644 --- a/include/HTTPServer.h +++ b/include/HTTPServer.h @@ -43,6 +43,7 @@ #include "esp_eth.h" #include "mbedtls/base64.h" +#define MAX_DYNVAR_NAME_LENGTH 32 #define MAX_DYNVAR_LENGTH 256 #define MAX_INCFILE_LENGTH 1024 diff --git a/src/HTTPServer.c b/src/HTTPServer.c index e7dae60..618c87a 100644 --- a/src/HTTPServer.c +++ b/src/HTTPServer.c @@ -252,6 +252,8 @@ static esp_err_t GETHandler(httpd_req_t *req) espfs_file_t *file; struct espfs_stat_t stat; bool isDynamicVars = false; + uint32_t fileSize; //length of file in bytes + uint32_t readBytes; //number of bytes, already read from file const char *filename = get_path_from_uri(filepath, ((struct file_server_data*) req->user_ctx)->base_path, @@ -305,43 +307,69 @@ static esp_err_t GETHandler(httpd_req_t *req) set_content_type_from_file(req, filename); /* Retrieve the pointer to scratch buffer for temporary storage */ char *chunk = ((struct file_server_data*) req->user_ctx)->scratch; - uint32_t readBytes, fileSize; + fileSize = stat.size; - char *buf = (char*) malloc(fileSize); - if (buf) - { - readBytes = espfs_fread(file, buf, fileSize); - } - else + readBytes = 0; + //char *buf = (char*) malloc(fileSize); + //allocate buffer for file data + char *buf = (char*) malloc(MIN(fileSize, SCRATCH_BUFSIZE) + MAX_DYNVAR_LENGTH); + if (!buf) { ESP_LOGE(TAG, "Failed to allocate memory"); /* Respond with 500 Internal Server Error */ - httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, - "Out of memory"); + httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "Out of memory"); espfs_fclose(file); return ESP_FAIL; } - + //read first portion of data from file + readBytes = espfs_fread(file, buf, MIN(fileSize, SCRATCH_BUFSIZE)); + //check if file is compressed by GZIP and add correspondent header if (memmem(buf, 3, GZIP_SIGN, 3)) { httpd_resp_set_hdr(req, "Content-Encoding", "gzip"); httpd_resp_set_hdr(req, "Cache-Control", "max-age=600"); } + //check if the file can contains dynamic variables if (IS_FILE_EXT(filename, ".html") || IS_FILE_EXT(filename, ".json")) isDynamicVars = true; + char *ptr = buf; + do + { + while (ptr < fileSize && readBytes < (SCRATCH_BUFSIZE - MAX_DYNVAR_LENGTH)) + { + if (buf[pt] == '~' && isDynamicVars) + { + int k = 0; + char DynVarName[MAX_DYNVAR_NAME_LENGTH]; + while (pt < fileSize && k < MAX_DYNVAR_NAME_LENGTH && (buf[++pt] != '~')) + DynVarName[k++] = buf[pt]; + if (buf[pt] == '~') + { //got valid dynamic variable name + DynVarName[k] = 0x00; + readBytes += HTTPPrint(req, &chunk[readBytes], DynVarName); + pt++; + } + } + else + chunk[readBytes++] = buf[pt++]; + } + + } + while (1); + int pt = 0; do { readBytes = 0; - while (pt < fileSize && readBytes < (SCRATCH_BUFSIZE - 64)) + while (pt < fileSize && readBytes < (SCRATCH_BUFSIZE - MAX_DYNVAR_LENGTH)) { if (buf[pt] == '~' && isDynamicVars) { int k = 0; - char DynVarName[16]; - while (pt < fileSize && k < 16 && (buf[++pt] != '~')) + char DynVarName[MAX_DYNVAR_NAME_LENGTH]; + while (pt < fileSize && k < MAX_DYNVAR_NAME_LENGTH && (buf[++pt] != '~')) DynVarName[k++] = buf[pt]; if (buf[pt] == '~') { //got valid dynamic variable name @@ -375,7 +403,7 @@ static esp_err_t GETHandler(httpd_req_t *req) } /* Keep looping till the whole file is sent */ } - while (readBytes != 0); + while (readBytes != fileSize); /* Close file after sending complete */ espfs_fclose(file); #if HTTP_SERVER_DEBUG_LEVEL > 0 From 7a46c36156d55c67e2727e70f3089abdc6b7680e Mon Sep 17 00:00:00 2001 From: Bogdan Pilyugin Date: Fri, 28 Oct 2022 15:59:35 +0200 Subject: [PATCH 2/6] http new transport testing and debug --- include/HTTPServer.h | 2 +- src/HTTPPrintSystem.c | 6 +++ src/HTTPServer.c | 110 ++++++++++++++++++++++++------------------ 3 files changed, 70 insertions(+), 48 deletions(-) diff --git a/include/HTTPServer.h b/include/HTTPServer.h index b538c32..c411ea8 100644 --- a/include/HTTPServer.h +++ b/include/HTTPServer.h @@ -47,7 +47,7 @@ #define MAX_DYNVAR_LENGTH 256 #define MAX_INCFILE_LENGTH 1024 -#define HTTP_SERVER_DEBUG_LEVEL 0 +#define HTTP_SERVER_DEBUG_LEVEL 1 typedef enum { diff --git a/src/HTTPPrintSystem.c b/src/HTTPPrintSystem.c index 557c085..378b92e 100644 --- a/src/HTTPPrintSystem.c +++ b/src/HTTPPrintSystem.c @@ -584,6 +584,11 @@ static void HTTPPrint_ifc_mq2(char *VarData, void *arg) #endif } +static void HTTPPrint_testvariable(char *VarData, void *arg) +{ +static int counter = 0; +snprintf(VarData, MAX_DYNVAR_LENGTH, "[%d]", counter++); +} //Default string if not found handler static void HTTPPrint_DEF(char *VarData, void *arg) @@ -703,6 +708,7 @@ dyn_var_handler_t HANDLERS_ARRAY[] = { { "ifc_gprs", sizeof("ifc_gprs") - 1, &HTTPPrint_ifc_gprs }, { "ifc_mq2", sizeof("ifc_mq2") - 1, &HTTPPrint_ifc_mq2 }, + { "testvariable", sizeof("testvariable") - 1, &HTTPPrint_testvariable}, }; diff --git a/src/HTTPServer.c b/src/HTTPServer.c index 618c87a..a03b0a8 100644 --- a/src/HTTPServer.c +++ b/src/HTTPServer.c @@ -34,10 +34,9 @@ static esp_err_t CheckAuth(httpd_req_t *req); /* Max size of an individual file. Make sure this * value is same as that set in upload_script.html */ -#define MAX_FILE_SIZE (200*1024) // 200 KB -#define MAX_FILE_SIZE_STR "200KB" + /* Scratch buffer size */ -#define SCRATCH_BUFSIZE 8192 +#define SCRATCH_BUFSIZE 4096 #define AUTH_DATA_MAX_LENGTH 16 struct file_server_data @@ -253,6 +252,7 @@ static esp_err_t GETHandler(httpd_req_t *req) struct espfs_stat_t stat; bool isDynamicVars = false; uint32_t fileSize; //length of file in bytes + uint32_t bufSize; uint32_t readBytes; //number of bytes, already read from file const char *filename = get_path_from_uri(filepath, @@ -309,10 +309,10 @@ static esp_err_t GETHandler(httpd_req_t *req) char *chunk = ((struct file_server_data*) req->user_ctx)->scratch; fileSize = stat.size; + bufSize = MIN(fileSize, SCRATCH_BUFSIZE - MAX_DYNVAR_LENGTH); // readBytes = 0; - //char *buf = (char*) malloc(fileSize); //allocate buffer for file data - char *buf = (char*) malloc(MIN(fileSize, SCRATCH_BUFSIZE) + MAX_DYNVAR_LENGTH); + char *buf = (char*) malloc(bufSize); if (!buf) { ESP_LOGE(TAG, "Failed to allocate memory"); @@ -322,7 +322,7 @@ static esp_err_t GETHandler(httpd_req_t *req) return ESP_FAIL; } //read first portion of data from file - readBytes = espfs_fread(file, buf, MIN(fileSize, SCRATCH_BUFSIZE)); + readBytes = espfs_fread(file, buf, bufSize); //check if file is compressed by GZIP and add correspondent header if (memmem(buf, 3, GZIP_SIGN, 3)) { @@ -334,60 +334,68 @@ static esp_err_t GETHandler(httpd_req_t *req) if (IS_FILE_EXT(filename, ".html") || IS_FILE_EXT(filename, ".json")) isDynamicVars = true; - char *ptr = buf; + bool transfComplete = false; do { - while (ptr < fileSize && readBytes < (SCRATCH_BUFSIZE - MAX_DYNVAR_LENGTH)) + int pt = 0; + int prcdBytes = 0; + while (pt < bufSize && prcdBytes < (SCRATCH_BUFSIZE)) { - if (buf[pt] == '~' && isDynamicVars) + if (buf[pt] == '~' && isDynamicVars) //open tag { int k = 0; + char ch = 0x00; char DynVarName[MAX_DYNVAR_NAME_LENGTH]; - while (pt < fileSize && k < MAX_DYNVAR_NAME_LENGTH && (buf[++pt] != '~')) - DynVarName[k++] = buf[pt]; - if (buf[pt] == '~') - { //got valid dynamic variable name + while (k < MAX_DYNVAR_NAME_LENGTH) + { + if (pt < bufSize) + { + if (buf[++pt] != '~') + DynVarName[k++] = buf[pt]; //continue extract variable name from buf + else + { + break; //found close tag + } + } + else //need read more characters directly from file + { + if (espfs_fread(file, &ch, 1)) + { + readBytes++; + if (ch != '~') + DynVarName[k++] = ch; //continue extract variable name from file + else + break; //found close tag + } + else // end of file + { + break; //error end of file + } + } + } + + + if (buf[pt] == '~' || ch == '~') //close tag, got valid dynamic variable name + { DynVarName[k] = 0x00; - readBytes += HTTPPrint(req, &chunk[readBytes], DynVarName); + prcdBytes += HTTPPrint(req, &chunk[prcdBytes], DynVarName); pt++; } + else //not found close tag, exit by overflow max variable size or file end + { + + } } else - chunk[readBytes++] = buf[pt++]; + chunk[prcdBytes++] = buf[pt++]; //ordinary character } - - } - while (1); - - int pt = 0; - do - { - readBytes = 0; - while (pt < fileSize && readBytes < (SCRATCH_BUFSIZE - MAX_DYNVAR_LENGTH)) - { - if (buf[pt] == '~' && isDynamicVars) - { - int k = 0; - char DynVarName[MAX_DYNVAR_NAME_LENGTH]; - while (pt < fileSize && k < MAX_DYNVAR_NAME_LENGTH && (buf[++pt] != '~')) - DynVarName[k++] = buf[pt]; - if (buf[pt] == '~') - { //got valid dynamic variable name - DynVarName[k] = 0x00; - readBytes += HTTPPrint(req, &chunk[readBytes], DynVarName); - pt++; - } - } - else - chunk[readBytes++] = buf[pt++]; - } - if (readBytes != 0) + if (prcdBytes != 0) { /* Send the buffer contents as HTTP response chunk */ #if HTTP_SERVER_DEBUG_LEVEL > 0 - ESP_LOGI(TAG, "Write to HTTPserv resp %d", readBytes); + ESP_LOGI(TAG, "Write to HTTPserv resp %d", prcdBytes); #endif - if (httpd_resp_send_chunk(req, chunk, readBytes) != ESP_OK) + if (httpd_resp_send_chunk(req, chunk, prcdBytes) != ESP_OK) { ESP_LOGE(TAG, "File sending failed!"); /* Abort sending file */ @@ -399,15 +407,23 @@ static esp_err_t GETHandler(httpd_req_t *req) espfs_fclose(file); return ESP_FAIL; } - } /* Keep looping till the whole file is sent */ + int nextPortion; + if((nextPortion = espfs_fread(file, buf, bufSize))) + { + bufSize = nextPortion; + readBytes += nextPortion; + } + else + transfComplete = true; } - while (readBytes != fileSize); + while (!transfComplete); + /* Close file after sending complete */ espfs_fclose(file); #if HTTP_SERVER_DEBUG_LEVEL > 0 - ESP_LOGI(TAG, "File sending complete"); + ESP_LOGI(TAG, "File sending complete, read from file %d", readBytes); #endif /* Respond with an empty chunk to signal HTTP response completion */ httpd_resp_send_chunk(req, NULL, 0); From 0f386c35d09d83f19559bb53584d0fa0be4e73fd Mon Sep 17 00:00:00 2001 From: Bogdan Date: Sat, 29 Oct 2022 14:11:07 +0200 Subject: [PATCH 3/6] implemented handle of unlimited size of dynamic variable expand; fixed problem appeared when dynamic variable split into two chunk of data --- src/HTTPServer.c | 113 +++++++++++++++++++++++++---------------------- 1 file changed, 60 insertions(+), 53 deletions(-) diff --git a/src/HTTPServer.c b/src/HTTPServer.c index a03b0a8..af10650 100644 --- a/src/HTTPServer.c +++ b/src/HTTPServer.c @@ -220,8 +220,8 @@ static esp_err_t POSTHandler(httpd_req_t *req) httpd_resp_set_hdr(req, "Location", filename); httpd_resp_send(req, NULL, 0); // Response body can be empty #if HTTP_SERVER_DEBUG_LEVEL > 0 - ESP_LOGI(TAG, "Redirect request from POST"); - #endif + ESP_LOGI(TAG, "Redirect request from POST"); +#endif return ESP_OK; } @@ -251,9 +251,8 @@ static esp_err_t GETHandler(httpd_req_t *req) espfs_file_t *file; struct espfs_stat_t stat; bool isDynamicVars = false; - uint32_t fileSize; //length of file in bytes - uint32_t bufSize; - uint32_t readBytes; //number of bytes, already read from file + uint32_t bufSize; //size of ram buffer for chunk of data, read from file + uint32_t readBytes; //number of bytes, read from file. used for information only const char *filename = get_path_from_uri(filepath, ((struct file_server_data*) req->user_ctx)->base_path, @@ -308,8 +307,7 @@ static esp_err_t GETHandler(httpd_req_t *req) /* Retrieve the pointer to scratch buffer for temporary storage */ char *chunk = ((struct file_server_data*) req->user_ctx)->scratch; - fileSize = stat.size; - bufSize = MIN(fileSize, SCRATCH_BUFSIZE - MAX_DYNVAR_LENGTH); // + bufSize = MIN(stat.size, SCRATCH_BUFSIZE - MAX_DYNVAR_LENGTH); readBytes = 0; //allocate buffer for file data char *buf = (char*) malloc(bufSize); @@ -334,12 +332,11 @@ static esp_err_t GETHandler(httpd_req_t *req) if (IS_FILE_EXT(filename, ".html") || IS_FILE_EXT(filename, ".json")) isDynamicVars = true; - bool transfComplete = false; do { int pt = 0; - int prcdBytes = 0; - while (pt < bufSize && prcdBytes < (SCRATCH_BUFSIZE)) + int preparedBytes = 0; + while (pt < bufSize) { if (buf[pt] == '~' && isDynamicVars) //open tag { @@ -353,9 +350,7 @@ static esp_err_t GETHandler(httpd_req_t *req) if (buf[++pt] != '~') DynVarName[k++] = buf[pt]; //continue extract variable name from buf else - { break; //found close tag - } } else //need read more characters directly from file { @@ -367,68 +362,80 @@ static esp_err_t GETHandler(httpd_req_t *req) else break; //found close tag } - else // end of file - { - break; //error end of file - } + else + //unexpected end of file + goto file_send_error; + } } - if (buf[pt] == '~' || ch == '~') //close tag, got valid dynamic variable name { DynVarName[k] = 0x00; - prcdBytes += HTTPPrint(req, &chunk[prcdBytes], DynVarName); - pt++; - } - else //not found close tag, exit by overflow max variable size or file end - { + preparedBytes += HTTPPrint(req, &chunk[preparedBytes], DynVarName); + //skip close '~' in buf or directly in file + if (ch == '~') + espfs_fread(file, &ch, 1); + else + pt++; } + else + //not found close tag, exit by overflow max variable size or file end + goto file_send_error; + } else - chunk[prcdBytes++] = buf[pt++]; //ordinary character - } - if (prcdBytes != 0) - { - /* Send the buffer contents as HTTP response chunk */ -#if HTTP_SERVER_DEBUG_LEVEL > 0 - ESP_LOGI(TAG, "Write to HTTPserv resp %d", prcdBytes); -#endif - if (httpd_resp_send_chunk(req, chunk, prcdBytes) != ESP_OK) + chunk[preparedBytes++] = buf[pt++]; //write to chunk ordinary character + + //check if scratch buffer is full and need send chunk + if (preparedBytes >= (SCRATCH_BUFSIZE - MAX_DYNVAR_LENGTH)) { - ESP_LOGE(TAG, "File sending failed!"); - /* Abort sending file */ - httpd_resp_sendstr_chunk(req, NULL); - /* Respond with 500 Internal Server Error */ - httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, - "Failed to send file"); - free(buf); - espfs_fclose(file); - return ESP_FAIL; +#if HTTP_SERVER_DEBUG_LEVEL > 0 + ESP_LOGI(TAG, "Write to HTTPserv resp %d", preparedBytes); +#endif + if (httpd_resp_send_chunk(req, chunk, preparedBytes) != ESP_OK) + goto file_send_error; + preparedBytes = 0; } } - /* Keep looping till the whole file is sent */ - int nextPortion; - if((nextPortion = espfs_fread(file, buf, bufSize))) - { - bufSize = nextPortion; - readBytes += nextPortion; - } - else - transfComplete = true; - } - while (!transfComplete); - /* Close file after sending complete */ - espfs_fclose(file); + //data in buffer is finished and not void, need send chunk + if (preparedBytes) + { +#if HTTP_SERVER_DEBUG_LEVEL > 0 + ESP_LOGI(TAG, "Write to HTTPserv resp %d", preparedBytes); +#endif + if (httpd_resp_send_chunk(req, chunk, preparedBytes) != ESP_OK) + goto file_send_error; + } + + //try to read next part of data from file + bufSize = espfs_fread(file, buf, bufSize); + readBytes += bufSize; + } + while (bufSize > 0); + #if HTTP_SERVER_DEBUG_LEVEL > 0 ESP_LOGI(TAG, "File sending complete, read from file %d", readBytes); #endif + /* Respond with an empty chunk to signal HTTP response completion */ httpd_resp_send_chunk(req, NULL, 0); free(buf); + espfs_fclose(file); return ESP_OK; + +file_send_error: + ESP_LOGE(TAG, "File sending failed!"); + /* Abort sending file */ + httpd_resp_sendstr_chunk(req, NULL); + /* Respond with 500 Internal Server Error */ + httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, + "Failed to send file"); + free(buf); + espfs_fclose(file); + return ESP_FAIL; } static httpd_handle_t start_webserver(void) From 1b1454a1603934aefc8078936ada6f228ae6a14b Mon Sep 17 00:00:00 2001 From: Bogdan Date: Sat, 29 Oct 2022 17:40:31 +0200 Subject: [PATCH 4/6] created REST API entry point and user handler --- src/HTTPServer.c | 43 +++++++++++++++++++++++++++++++++---------- 1 file changed, 33 insertions(+), 10 deletions(-) diff --git a/src/HTTPServer.c b/src/HTTPServer.c index af10650..c06e3e4 100644 --- a/src/HTTPServer.c +++ b/src/HTTPServer.c @@ -51,6 +51,13 @@ struct file_server_data *server_data = NULL; httpd_handle_t server = NULL; static const char *TAG = "HTTPServer"; +//Pointer to external user defined rest api handler +static int (*HTTPUserRestAPI)(char *url, char *req, int len, char *resp) = NULL; +void regHTTPUserRestAPI(int (*api_handler)(char *url, char *req, int len, char *resp)) +{ + HTTPUserRestAPI = api_handler; +} + static esp_err_t CheckAuth(httpd_req_t *req) { unsigned char pass[18] = { 0 }; //max length of login:password decoded string @@ -168,6 +175,16 @@ static const char* get_path_from_uri(char *dest, const char *base_path, return dest + base_pathlen; } +static esp_err_t RestApiHandler(httpd_req_t *req) +{ +#if HTTP_SERVER_DEBUG_LEVEL > 0 + ESP_LOGI(TAG, "REST API handler"); +#endif + + httpd_resp_sendstr(req, "{\"apiver\":\"1.00\",\"result\":\"OK\"}"); // Response body can be empty + return ESP_OK; +} + static esp_err_t POSTHandler(httpd_req_t *req) { #if HTTP_SERVER_DEBUG_LEVEL > 0 @@ -209,6 +226,12 @@ static esp_err_t POSTHandler(httpd_req_t *req) ((struct file_server_data*) req->user_ctx)->base_path, req->uri, sizeof(filepath)); + + if (!memcmp(filename, "/api", 4)) + { + return RestApiHandler(req); + } + http_res = HTTPPostApp(req, filename, buf); if (http_res == HTTP_IO_DONE) @@ -279,7 +302,7 @@ static esp_err_t GETHandler(httpd_req_t *req) return ESP_OK; } - //check auth for all files except status.json +//check auth for all files except status.json if (strcmp(filename, "/status.json")) { if (CheckAuth(req) != ESP_OK) @@ -288,28 +311,28 @@ static esp_err_t GETHandler(httpd_req_t *req) } } - //open file +//open file file = espfs_fopen(fs, filepath); if (!file) { httpd_resp_send_err(req, HTTPD_404_NOT_FOUND, "File not found"); return ESP_FAIL; } - //get file info +//get file info espfs_stat(fs, filepath, &stat); #if HTTP_SERVER_DEBUG_LEVEL > 0 ESP_LOGI(TAG, "Sending file : %s (%d bytes)...", filename, stat.size); #endif - //OutputDisplay((char*) filepath); +//OutputDisplay((char*) filepath); set_content_type_from_file(req, filename); /* Retrieve the pointer to scratch buffer for temporary storage */ char *chunk = ((struct file_server_data*) req->user_ctx)->scratch; bufSize = MIN(stat.size, SCRATCH_BUFSIZE - MAX_DYNVAR_LENGTH); readBytes = 0; - //allocate buffer for file data +//allocate buffer for file data char *buf = (char*) malloc(bufSize); if (!buf) { @@ -319,16 +342,16 @@ static esp_err_t GETHandler(httpd_req_t *req) espfs_fclose(file); return ESP_FAIL; } - //read first portion of data from file +//read first portion of data from file readBytes = espfs_fread(file, buf, bufSize); - //check if file is compressed by GZIP and add correspondent header +//check if file is compressed by GZIP and add correspondent header if (memmem(buf, 3, GZIP_SIGN, 3)) { httpd_resp_set_hdr(req, "Content-Encoding", "gzip"); httpd_resp_set_hdr(req, "Cache-Control", "max-age=600"); } - //check if the file can contains dynamic variables +//check if the file can contains dynamic variables if (IS_FILE_EXT(filename, ".html") || IS_FILE_EXT(filename, ".json")) isDynamicVars = true; @@ -446,7 +469,7 @@ static httpd_handle_t start_webserver(void) config.uri_match_fn = httpd_uri_match_wildcard; config.max_open_sockets = 3; - // Start the httpd server +// Start the httpd server ESP_LOGI(TAG, "Starting server on port: '%d'", config.server_port); if (httpd_start(&server, &config) == ESP_OK) { @@ -475,7 +498,7 @@ static httpd_handle_t start_webserver(void) static void stop_webserver(httpd_handle_t server) { - // Stop the httpd server +// Stop the httpd server httpd_stop(server); } From 27835c9496179e33c955c8c0f79d6eed108df529 Mon Sep 17 00:00:00 2001 From: Bogdan Date: Sun, 30 Oct 2022 13:34:50 +0200 Subject: [PATCH 5/6] debug messages edited --- src/HTTPServer.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/HTTPServer.c b/src/HTTPServer.c index c06e3e4..52f5084 100644 --- a/src/HTTPServer.c +++ b/src/HTTPServer.c @@ -415,7 +415,7 @@ static esp_err_t GETHandler(httpd_req_t *req) if (preparedBytes >= (SCRATCH_BUFSIZE - MAX_DYNVAR_LENGTH)) { #if HTTP_SERVER_DEBUG_LEVEL > 0 - ESP_LOGI(TAG, "Write to HTTPserv resp %d", preparedBytes); + ESP_LOGI(TAG, "Call resp_send_chank because of chunk full. Send %d bytes", preparedBytes); #endif if (httpd_resp_send_chunk(req, chunk, preparedBytes) != ESP_OK) goto file_send_error; @@ -427,7 +427,7 @@ static esp_err_t GETHandler(httpd_req_t *req) if (preparedBytes) { #if HTTP_SERVER_DEBUG_LEVEL > 0 - ESP_LOGI(TAG, "Write to HTTPserv resp %d", preparedBytes); + ESP_LOGI(TAG, "Call resp_send_chank because of buf empty. Send %d bytes", preparedBytes); #endif if (httpd_resp_send_chunk(req, chunk, preparedBytes) != ESP_OK) goto file_send_error; From be93495134d9f4f1b4b424b9399476893b0b1e51 Mon Sep 17 00:00:00 2001 From: Bogdan Pilyugin Date: Mon, 31 Oct 2022 15:04:39 +0200 Subject: [PATCH 6/6] http server send file mechanism reworked with constant buffer size --- src/HTTPPrintSystem.c | 4 ++-- src/HTTPServer.c | 16 +++++----------- 2 files changed, 7 insertions(+), 13 deletions(-) diff --git a/src/HTTPPrintSystem.c b/src/HTTPPrintSystem.c index 378b92e..ae421da 100644 --- a/src/HTTPPrintSystem.c +++ b/src/HTTPPrintSystem.c @@ -586,8 +586,8 @@ static void HTTPPrint_ifc_mq2(char *VarData, void *arg) static void HTTPPrint_testvariable(char *VarData, void *arg) { -static int counter = 0; -snprintf(VarData, MAX_DYNVAR_LENGTH, "[%d]", counter++); +static int counter = 1; +snprintf(VarData, MAX_DYNVAR_LENGTH, "[Long extended dynamic variable number %d]", counter++); } //Default string if not found handler diff --git a/src/HTTPServer.c b/src/HTTPServer.c index 52f5084..9adf395 100644 --- a/src/HTTPServer.c +++ b/src/HTTPServer.c @@ -354,7 +354,6 @@ static esp_err_t GETHandler(httpd_req_t *req) //check if the file can contains dynamic variables if (IS_FILE_EXT(filename, ".html") || IS_FILE_EXT(filename, ".json")) isDynamicVars = true; - do { int pt = 0; @@ -366,12 +365,13 @@ static esp_err_t GETHandler(httpd_req_t *req) int k = 0; char ch = 0x00; char DynVarName[MAX_DYNVAR_NAME_LENGTH]; + pt++; //skip open tag while (k < MAX_DYNVAR_NAME_LENGTH) { if (pt < bufSize) { - if (buf[++pt] != '~') - DynVarName[k++] = buf[pt]; //continue extract variable name from buf + if (buf[pt] != '~') + DynVarName[k++] = buf[pt++]; //continue extract variable name from buf else break; //found close tag } @@ -388,25 +388,19 @@ static esp_err_t GETHandler(httpd_req_t *req) else //unexpected end of file goto file_send_error; - } } - if (buf[pt] == '~' || ch == '~') //close tag, got valid dynamic variable name { DynVarName[k] = 0x00; preparedBytes += HTTPPrint(req, &chunk[preparedBytes], DynVarName); - - //skip close '~' in buf or directly in file - if (ch == '~') - espfs_fread(file, &ch, 1); - else + //skip close '~' in buf but not directly in file! + if (ch != '~') pt++; } else //not found close tag, exit by overflow max variable size or file end goto file_send_error; - } else chunk[preparedBytes++] = buf[pt++]; //write to chunk ordinary character