@@ -114,6 +114,7 @@ static esp_err_t cb_url(http_parser *parser,
114114 parser_data_t * parser_data = (parser_data_t * ) parser -> data ;
115115 httpd_req_t * req = parser_data -> req ;
116116 struct httpd_req_aux * raux = req -> aux ;
117+
117118 if (parser_data -> status == PARSING_IDLE ) {
118119 ESP_LOGD (TAG , LOG_FMT ("message begin" ));
119120
@@ -131,9 +132,9 @@ static esp_err_t cb_url(http_parser *parser,
131132 ESP_LOGD (TAG , LOG_FMT ("processing url = %.*s" ), (int )length , at );
132133
133134 /* Update length of URL string */
134- if ((parser_data -> last .length += length ) > raux -> uri_buf_size_limit ) {
135+ if ((parser_data -> last .length += length ) > raux -> max_uri_len ) {
135136 ESP_LOGW (TAG , LOG_FMT ("URI length (%" NEWLIB_NANO_COMPAT_FORMAT ") greater than supported (%d)" ),
136- NEWLIB_NANO_COMPAT_CAST (parser_data -> last .length ), raux -> uri_buf_size_limit );
137+ NEWLIB_NANO_COMPAT_CAST (parser_data -> last .length ), raux -> max_uri_len );
137138 parser_data -> error = HTTPD_414_URI_TOO_LONG ;
138139 parser_data -> status = PARSING_FAILED ;
139140 return ESP_FAIL ;
@@ -216,7 +217,8 @@ static esp_err_t cb_header_field(http_parser *parser, const char *at, size_t len
216217 parser_data -> last .at = ra -> scratch ;
217218 parser_data -> last .length = 0 ;
218219 parser_data -> status = PARSING_HDR_FIELD ;
219- ra -> scratch_size_limit = ra -> hdr_buf_size_limit ;
220+ ra -> scratch_size_limit = ra -> max_req_hdr_len ;
221+
220222 /* Stop parsing for now and give control to process */
221223 if (pause_parsing (parser , at ) != ESP_OK ) {
222224 parser_data -> error = HTTPD_500_INTERNAL_SERVER_ERROR ;
@@ -233,7 +235,7 @@ static esp_err_t cb_header_field(http_parser *parser, const char *at, size_t len
233235 parser_data -> last .at = at ;
234236 parser_data -> last .length = 0 ;
235237 parser_data -> status = PARSING_HDR_FIELD ;
236- ra -> scratch_size_limit = ra -> hdr_buf_size_limit ;
238+ ra -> scratch_size_limit = ra -> max_req_hdr_len ;
237239
238240 /* Increment header count */
239241 ra -> req_hdrs_count ++ ;
@@ -415,6 +417,7 @@ static esp_err_t cb_headers_complete(http_parser *parser)
415417static esp_err_t cb_on_body (http_parser * parser , const char * at , size_t length )
416418{
417419 parser_data_t * parser_data = (parser_data_t * ) parser -> data ;
420+
418421 /* Check previous status */
419422 if (parser_data -> status != PARSING_BODY ) {
420423 ESP_LOGE (TAG , LOG_FMT ("unexpected state transition" ));
@@ -446,6 +449,7 @@ static esp_err_t cb_on_body(http_parser *parser, const char *at, size_t length)
446449static esp_err_t cb_no_body (http_parser * parser )
447450{
448451 parser_data_t * parser_data = (parser_data_t * ) parser -> data ;
452+
449453 /* Check previous status */
450454 if (parser_data -> status == PARSING_URL ) {
451455 ESP_LOGD (TAG , LOG_FMT ("no headers" ));
@@ -480,26 +484,32 @@ static esp_err_t cb_no_body(http_parser *parser)
480484 return ESP_OK ;
481485}
482486
483- static int read_block (httpd_req_t * req , size_t offset , size_t length )
487+ static int read_block (httpd_req_t * req , http_parser * parser , size_t offset , size_t length )
484488{
485489 struct httpd_req_aux * raux = req -> aux ;
490+ parser_data_t * parser_data = (parser_data_t * ) parser -> data ;
486491
487492 /* Limits the read to scratch buffer size */
488493 ssize_t buf_len = MIN (length , (raux -> scratch_size_limit - offset ));
489494 if (buf_len <= 0 ) {
490495 return 0 ;
491496 }
492- if (raux -> scratch == NULL && buf_len < raux -> scratch_size_limit ) {
493- raux -> scratch = (char * ) malloc (buf_len );
494- }
495- else if (raux -> scratch != NULL && buf_len < raux -> scratch_size_limit ) {
496- raux -> scratch = (char * ) realloc (raux -> scratch , raux -> scratch_cur_size + buf_len );
497- }
497+ /* Calculate the offset of the current position from the start of the buffer,
498+ * as after reallocating the buffer, the base address of the buffer may change.
499+ */
500+ size_t at_offset = parser_data -> last .at - raux -> scratch ;
501+ /* Allocate the buffer according to offset and buf_len. Offset is
502+ from where the reading will start and buf_len is till what length
503+ the buffer will be read.
504+ */
505+ raux -> scratch = (char * ) realloc (raux -> scratch , offset + buf_len );
498506 if (raux -> scratch == NULL ) {
507+ ESP_LOGE (TAG , "Unable to allocate the scratch buffer" );
499508 return 0 ;
500509 }
501- raux -> scratch_cur_size += buf_len ;
502- ESP_LOGD (TAG , "scratch size = %d" , raux -> scratch_cur_size );
510+ parser_data -> last .at = raux -> scratch + at_offset ;
511+ raux -> scratch_cur_size = offset + buf_len ;
512+ ESP_LOGD (TAG , "scratch buf qsize = %d" , raux -> scratch_cur_size );
503513 /* Receive data into buffer. If data is pending (from unrecv) then return
504514 * immediately after receiving pending data, as pending data may just complete
505515 * this request packet. */
@@ -537,7 +547,7 @@ static int parse_block(http_parser *parser, size_t offset, size_t length)
537547 httpd_req_t * req = data -> req ;
538548 struct httpd_req_aux * raux = req -> aux ;
539549 size_t nparsed = 0 ;
540- data -> last . at = raux -> scratch ;
550+
541551 if (!length ) {
542552 /* Parsing is still happening but nothing to
543553 * parse means no more space left on buffer,
@@ -643,7 +653,7 @@ static esp_err_t httpd_parse_req(struct httpd_data *hd)
643653 offset = 0 ;
644654 do {
645655 /* Read block into scratch buffer */
646- if ((blk_len = read_block (r , offset , PARSER_BLOCK_SIZE )) < 0 ) {
656+ if ((blk_len = read_block (r , & parser , offset , PARSER_BLOCK_SIZE )) < 0 ) {
647657 if (blk_len == HTTPD_SOCK_ERR_TIMEOUT ) {
648658 /* Retry read in case of non-fatal timeout error.
649659 * read_block() ensures that the timeout error is
@@ -660,6 +670,7 @@ static esp_err_t httpd_parse_req(struct httpd_data *hd)
660670 /* This is used by the callbacks to track
661671 * data usage of the buffer */
662672 parser_data .raw_datalen = blk_len + offset ;
673+
663674 /* Parse data block from buffer */
664675 if ((offset = parse_block (& parser , offset , blk_len )) < 0 ) {
665676 /* HTTP error occurred.
@@ -697,9 +708,9 @@ static void init_req_aux(struct httpd_req_aux *ra, httpd_config_t *config)
697708 ra -> resp_hdrs_count = 0 ;
698709 ra -> scratch = NULL ;
699710 ra -> scratch_cur_size = 0 ;
700- ra -> hdr_buf_size_limit = config -> hdr_buf_size_limit ;
701- ra -> uri_buf_size_limit = config -> uri_buf_size_limit ;
702- ra -> scratch_size_limit = ra -> uri_buf_size_limit ;
711+ ra -> max_req_hdr_len = ( config -> max_req_hdr_len > 0 ) ? config -> max_req_hdr_len : CONFIG_HTTPD_MAX_REQ_HDR_LEN ;
712+ ra -> max_uri_len = ( config -> max_uri_len > 0 ) ? config -> max_uri_len : CONFIG_HTTPD_MAX_URI_LEN ;
713+ ra -> scratch_size_limit = ra -> max_uri_len ;
703714#if CONFIG_HTTPD_WS_SUPPORT
704715 ra -> ws_handshake_detect = false;
705716#endif
@@ -732,8 +743,8 @@ static void httpd_req_cleanup(httpd_req_t *r)
732743 ra -> sd = NULL ;
733744 free (ra -> scratch );
734745 ra -> scratch = NULL ;
735- ra -> scratch_cur_size = 0 ;
736746 ra -> scratch_size_limit = 0 ;
747+ ra -> scratch_cur_size = 0 ;
737748 r -> handle = NULL ;
738749 r -> aux = NULL ;
739750 r -> user_ctx = NULL ;
0 commit comments