@@ -112,6 +112,8 @@ static esp_err_t cb_url(http_parser *parser,
112112 const char * at , size_t length )
113113{
114114 parser_data_t * parser_data = (parser_data_t * ) parser -> data ;
115+ httpd_req_t * req = parser_data -> req ;
116+ struct httpd_req_aux * raux = req -> aux ;
115117
116118 if (parser_data -> status == PARSING_IDLE ) {
117119 ESP_LOGD (TAG , LOG_FMT ("message begin" ));
@@ -130,9 +132,9 @@ static esp_err_t cb_url(http_parser *parser,
130132 ESP_LOGD (TAG , LOG_FMT ("processing url = %.*s" ), (int )length , at );
131133
132134 /* Update length of URL string */
133- if ((parser_data -> last .length += length ) > HTTPD_MAX_URI_LEN ) {
135+ if ((parser_data -> last .length += length ) > raux -> max_uri_len ) {
134136 ESP_LOGW (TAG , LOG_FMT ("URI length (%" NEWLIB_NANO_COMPAT_FORMAT ") greater than supported (%d)" ),
135- NEWLIB_NANO_COMPAT_CAST (parser_data -> last .length ), HTTPD_MAX_URI_LEN );
137+ NEWLIB_NANO_COMPAT_CAST (parser_data -> last .length ), raux -> max_uri_len );
136138 parser_data -> error = HTTPD_414_URI_TOO_LONG ;
137139 parser_data -> status = PARSING_FAILED ;
138140 return ESP_FAIL ;
@@ -215,6 +217,7 @@ static esp_err_t cb_header_field(http_parser *parser, const char *at, size_t len
215217 parser_data -> last .at = ra -> scratch ;
216218 parser_data -> last .length = 0 ;
217219 parser_data -> status = PARSING_HDR_FIELD ;
220+ ra -> scratch_size_limit = ra -> max_req_hdr_len ;
218221
219222 /* Stop parsing for now and give control to process */
220223 if (pause_parsing (parser , at ) != ESP_OK ) {
@@ -232,6 +235,7 @@ static esp_err_t cb_header_field(http_parser *parser, const char *at, size_t len
232235 parser_data -> last .at = at ;
233236 parser_data -> last .length = 0 ;
234237 parser_data -> status = PARSING_HDR_FIELD ;
238+ ra -> scratch_size_limit = ra -> max_req_hdr_len ;
235239
236240 /* Increment header count */
237241 ra -> req_hdrs_count ++ ;
@@ -480,16 +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 */
488- ssize_t buf_len = MIN (length , (sizeof ( raux -> scratch ) - offset ));
493+ ssize_t buf_len = MIN (length , (raux -> scratch_size_limit - offset ));
489494 if (buf_len <= 0 ) {
490495 return 0 ;
491496 }
492-
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 );
506+ if (raux -> scratch == NULL ) {
507+ ESP_LOGE (TAG , "Unable to allocate the scratch buffer" );
508+ return 0 ;
509+ }
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 );
493513 /* Receive data into buffer. If data is pending (from unrecv) then return
494514 * immediately after receiving pending data, as pending data may just complete
495515 * this request packet. */
@@ -533,13 +553,14 @@ static int parse_block(http_parser *parser, size_t offset, size_t length)
533553 * parse means no more space left on buffer,
534554 * therefore it can be inferred that the
535555 * request URI/header must be too long */
536- ESP_LOGW (TAG , LOG_FMT ("request URI/header too long" ));
537556 switch (data -> status ) {
538557 case PARSING_URL :
558+ ESP_LOGW (TAG , LOG_FMT ("request URI too long" ));
539559 data -> error = HTTPD_414_URI_TOO_LONG ;
540560 break ;
541561 case PARSING_HDR_FIELD :
542562 case PARSING_HDR_VALUE :
563+ ESP_LOGW (TAG , LOG_FMT ("request header too long" ));
543564 data -> error = HTTPD_431_REQ_HDR_FIELDS_TOO_LARGE ;
544565 break ;
545566 default :
@@ -632,7 +653,7 @@ static esp_err_t httpd_parse_req(struct httpd_data *hd)
632653 offset = 0 ;
633654 do {
634655 /* Read block into scratch buffer */
635- if ((blk_len = read_block (r , offset , PARSER_BLOCK_SIZE )) < 0 ) {
656+ if ((blk_len = read_block (r , & parser , offset , PARSER_BLOCK_SIZE )) < 0 ) {
636657 if (blk_len == HTTPD_SOCK_ERR_TIMEOUT ) {
637658 /* Retry read in case of non-fatal timeout error.
638659 * read_block() ensures that the timeout error is
@@ -679,13 +700,17 @@ static void init_req(httpd_req_t *r, httpd_config_t *config)
679700static void init_req_aux (struct httpd_req_aux * ra , httpd_config_t * config )
680701{
681702 ra -> sd = 0 ;
682- memset (ra -> scratch , 0 , sizeof (ra -> scratch ));
683703 ra -> remaining_len = 0 ;
684704 ra -> status = 0 ;
685705 ra -> content_type = 0 ;
686706 ra -> first_chunk_sent = 0 ;
687707 ra -> req_hdrs_count = 0 ;
688708 ra -> resp_hdrs_count = 0 ;
709+ ra -> scratch = NULL ;
710+ ra -> scratch_cur_size = 0 ;
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 ;
689714#if CONFIG_HTTPD_WS_SUPPORT
690715 ra -> ws_handshake_detect = false;
691716#endif
@@ -716,6 +741,10 @@ static void httpd_req_cleanup(httpd_req_t *r)
716741
717742 /* Clear out the request and request_aux structures */
718743 ra -> sd = NULL ;
744+ free (ra -> scratch );
745+ ra -> scratch = NULL ;
746+ ra -> scratch_size_limit = 0 ;
747+ ra -> scratch_cur_size = 0 ;
719748 r -> handle = NULL ;
720749 r -> aux = NULL ;
721750 r -> user_ctx = NULL ;
0 commit comments