implemented handle of unlimited size of dynamic variable expand;
fixed problem appeared when dynamic variable split into two chunk of data
This commit is contained in:
parent
7a46c36156
commit
0f386c35d0
113
src/HTTPServer.c
113
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_set_hdr(req, "Location", filename);
|
||||||
httpd_resp_send(req, NULL, 0); // Response body can be empty
|
httpd_resp_send(req, NULL, 0); // Response body can be empty
|
||||||
#if HTTP_SERVER_DEBUG_LEVEL > 0
|
#if HTTP_SERVER_DEBUG_LEVEL > 0
|
||||||
ESP_LOGI(TAG, "Redirect request from POST");
|
ESP_LOGI(TAG, "Redirect request from POST");
|
||||||
#endif
|
#endif
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -251,9 +251,8 @@ static esp_err_t GETHandler(httpd_req_t *req)
|
||||||
espfs_file_t *file;
|
espfs_file_t *file;
|
||||||
struct espfs_stat_t stat;
|
struct espfs_stat_t stat;
|
||||||
bool isDynamicVars = false;
|
bool isDynamicVars = false;
|
||||||
uint32_t fileSize; //length of file in bytes
|
uint32_t bufSize; //size of ram buffer for chunk of data, read from file
|
||||||
uint32_t bufSize;
|
uint32_t readBytes; //number of bytes, read from file. used for information only
|
||||||
uint32_t readBytes; //number of bytes, already read from file
|
|
||||||
|
|
||||||
const char *filename = get_path_from_uri(filepath,
|
const char *filename = get_path_from_uri(filepath,
|
||||||
((struct file_server_data*) req->user_ctx)->base_path,
|
((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 */
|
/* Retrieve the pointer to scratch buffer for temporary storage */
|
||||||
char *chunk = ((struct file_server_data*) req->user_ctx)->scratch;
|
char *chunk = ((struct file_server_data*) req->user_ctx)->scratch;
|
||||||
|
|
||||||
fileSize = stat.size;
|
bufSize = MIN(stat.size, SCRATCH_BUFSIZE - MAX_DYNVAR_LENGTH);
|
||||||
bufSize = MIN(fileSize, SCRATCH_BUFSIZE - MAX_DYNVAR_LENGTH); //
|
|
||||||
readBytes = 0;
|
readBytes = 0;
|
||||||
//allocate buffer for file data
|
//allocate buffer for file data
|
||||||
char *buf = (char*) malloc(bufSize);
|
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"))
|
if (IS_FILE_EXT(filename, ".html") || IS_FILE_EXT(filename, ".json"))
|
||||||
isDynamicVars = true;
|
isDynamicVars = true;
|
||||||
|
|
||||||
bool transfComplete = false;
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
int pt = 0;
|
int pt = 0;
|
||||||
int prcdBytes = 0;
|
int preparedBytes = 0;
|
||||||
while (pt < bufSize && prcdBytes < (SCRATCH_BUFSIZE))
|
while (pt < bufSize)
|
||||||
{
|
{
|
||||||
if (buf[pt] == '~' && isDynamicVars) //open tag
|
if (buf[pt] == '~' && isDynamicVars) //open tag
|
||||||
{
|
{
|
||||||
|
|
@ -353,9 +350,7 @@ static esp_err_t GETHandler(httpd_req_t *req)
|
||||||
if (buf[++pt] != '~')
|
if (buf[++pt] != '~')
|
||||||
DynVarName[k++] = buf[pt]; //continue extract variable name from buf
|
DynVarName[k++] = buf[pt]; //continue extract variable name from buf
|
||||||
else
|
else
|
||||||
{
|
|
||||||
break; //found close tag
|
break; //found close tag
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else //need read more characters directly from file
|
else //need read more characters directly from file
|
||||||
{
|
{
|
||||||
|
|
@ -367,68 +362,80 @@ static esp_err_t GETHandler(httpd_req_t *req)
|
||||||
else
|
else
|
||||||
break; //found close tag
|
break; //found close tag
|
||||||
}
|
}
|
||||||
else // end of file
|
else
|
||||||
{
|
//unexpected end of file
|
||||||
break; //error end of file
|
goto file_send_error;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (buf[pt] == '~' || ch == '~') //close tag, got valid dynamic variable name
|
if (buf[pt] == '~' || ch == '~') //close tag, got valid dynamic variable name
|
||||||
{
|
{
|
||||||
DynVarName[k] = 0x00;
|
DynVarName[k] = 0x00;
|
||||||
prcdBytes += HTTPPrint(req, &chunk[prcdBytes], DynVarName);
|
preparedBytes += HTTPPrint(req, &chunk[preparedBytes], DynVarName);
|
||||||
pt++;
|
|
||||||
}
|
|
||||||
else //not found close tag, exit by overflow max variable size or file end
|
|
||||||
{
|
|
||||||
|
|
||||||
|
//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
|
else
|
||||||
chunk[prcdBytes++] = buf[pt++]; //ordinary character
|
chunk[preparedBytes++] = buf[pt++]; //write to chunk ordinary character
|
||||||
}
|
|
||||||
if (prcdBytes != 0)
|
//check if scratch buffer is full and need send chunk
|
||||||
{
|
if (preparedBytes >= (SCRATCH_BUFSIZE - MAX_DYNVAR_LENGTH))
|
||||||
/* 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)
|
|
||||||
{
|
{
|
||||||
ESP_LOGE(TAG, "File sending failed!");
|
#if HTTP_SERVER_DEBUG_LEVEL > 0
|
||||||
/* Abort sending file */
|
ESP_LOGI(TAG, "Write to HTTPserv resp %d", preparedBytes);
|
||||||
httpd_resp_sendstr_chunk(req, NULL);
|
#endif
|
||||||
/* Respond with 500 Internal Server Error */
|
if (httpd_resp_send_chunk(req, chunk, preparedBytes) != ESP_OK)
|
||||||
httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR,
|
goto file_send_error;
|
||||||
"Failed to send file");
|
preparedBytes = 0;
|
||||||
free(buf);
|
|
||||||
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 (!transfComplete);
|
|
||||||
|
|
||||||
/* Close file after sending complete */
|
//data in buffer is finished and not void, need send chunk
|
||||||
espfs_fclose(file);
|
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
|
#if HTTP_SERVER_DEBUG_LEVEL > 0
|
||||||
ESP_LOGI(TAG, "File sending complete, read from file %d", readBytes);
|
ESP_LOGI(TAG, "File sending complete, read from file %d", readBytes);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Respond with an empty chunk to signal HTTP response completion */
|
/* Respond with an empty chunk to signal HTTP response completion */
|
||||||
httpd_resp_send_chunk(req, NULL, 0);
|
httpd_resp_send_chunk(req, NULL, 0);
|
||||||
free(buf);
|
free(buf);
|
||||||
|
espfs_fclose(file);
|
||||||
return ESP_OK;
|
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)
|
static httpd_handle_t start_webserver(void)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user