@@ -112,7 +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-
115+ httpd_req_t * req = parser_data -> req ;
116+ struct httpd_req_aux * raux = req -> aux ;
116117 if (parser_data -> status == PARSING_IDLE ) {
117118 ESP_LOGD (TAG , LOG_FMT ("message begin" ));
118119
@@ -130,9 +131,9 @@ static esp_err_t cb_url(http_parser *parser,
130131 ESP_LOGD (TAG , LOG_FMT ("processing url = %.*s" ), (int )length , at );
131132
132133 /* Update length of URL string */
133- if ((parser_data -> last .length += length ) > HTTPD_MAX_URI_LEN ) {
134+ if ((parser_data -> last .length += length ) > raux -> uri_buf_size_limit ) {
134135 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 );
136+ NEWLIB_NANO_COMPAT_CAST (parser_data -> last .length ), raux -> uri_buf_size_limit );
136137 parser_data -> error = HTTPD_414_URI_TOO_LONG ;
137138 parser_data -> status = PARSING_FAILED ;
138139 return ESP_FAIL ;
@@ -215,7 +216,7 @@ static esp_err_t cb_header_field(http_parser *parser, const char *at, size_t len
215216 parser_data -> last .at = ra -> scratch ;
216217 parser_data -> last .length = 0 ;
217218 parser_data -> status = PARSING_HDR_FIELD ;
218-
219+ ra -> scratch_size_limit = ra -> hdr_buf_size_limit ;
219220 /* Stop parsing for now and give control to process */
220221 if (pause_parsing (parser , at ) != ESP_OK ) {
221222 parser_data -> error = HTTPD_500_INTERNAL_SERVER_ERROR ;
@@ -232,6 +233,7 @@ static esp_err_t cb_header_field(http_parser *parser, const char *at, size_t len
232233 parser_data -> last .at = at ;
233234 parser_data -> last .length = 0 ;
234235 parser_data -> status = PARSING_HDR_FIELD ;
236+ ra -> scratch_size_limit = ra -> hdr_buf_size_limit ;
235237
236238 /* Increment header count */
237239 ra -> req_hdrs_count ++ ;
@@ -413,7 +415,6 @@ static esp_err_t cb_headers_complete(http_parser *parser)
413415static esp_err_t cb_on_body (http_parser * parser , const char * at , size_t length )
414416{
415417 parser_data_t * parser_data = (parser_data_t * ) parser -> data ;
416-
417418 /* Check previous status */
418419 if (parser_data -> status != PARSING_BODY ) {
419420 ESP_LOGE (TAG , LOG_FMT ("unexpected state transition" ));
@@ -445,7 +446,6 @@ static esp_err_t cb_on_body(http_parser *parser, const char *at, size_t length)
445446static esp_err_t cb_no_body (http_parser * parser )
446447{
447448 parser_data_t * parser_data = (parser_data_t * ) parser -> data ;
448-
449449 /* Check previous status */
450450 if (parser_data -> status == PARSING_URL ) {
451451 ESP_LOGD (TAG , LOG_FMT ("no headers" ));
@@ -485,11 +485,21 @@ static int read_block(httpd_req_t *req, size_t offset, size_t length)
485485 struct httpd_req_aux * raux = req -> aux ;
486486
487487 /* Limits the read to scratch buffer size */
488- ssize_t buf_len = MIN (length , (sizeof ( raux -> scratch ) - offset ));
488+ ssize_t buf_len = MIN (length , (raux -> scratch_size_limit - offset ));
489489 if (buf_len <= 0 ) {
490490 return 0 ;
491491 }
492-
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+ }
498+ if (raux -> scratch == NULL ) {
499+ return 0 ;
500+ }
501+ raux -> scratch_cur_size += buf_len ;
502+ ESP_LOGD (TAG , "scratch size = %d" , raux -> scratch_cur_size );
493503 /* Receive data into buffer. If data is pending (from unrecv) then return
494504 * immediately after receiving pending data, as pending data may just complete
495505 * this request packet. */
@@ -527,19 +537,20 @@ static int parse_block(http_parser *parser, size_t offset, size_t length)
527537 httpd_req_t * req = data -> req ;
528538 struct httpd_req_aux * raux = req -> aux ;
529539 size_t nparsed = 0 ;
530-
540+ data -> last . at = raux -> scratch ;
531541 if (!length ) {
532542 /* Parsing is still happening but nothing to
533543 * parse means no more space left on buffer,
534544 * therefore it can be inferred that the
535545 * request URI/header must be too long */
536- ESP_LOGW (TAG , LOG_FMT ("request URI/header too long" ));
537546 switch (data -> status ) {
538547 case PARSING_URL :
548+ ESP_LOGW (TAG , LOG_FMT ("request URI too long" ));
539549 data -> error = HTTPD_414_URI_TOO_LONG ;
540550 break ;
541551 case PARSING_HDR_FIELD :
542552 case PARSING_HDR_VALUE :
553+ ESP_LOGW (TAG , LOG_FMT ("request header too long" ));
543554 data -> error = HTTPD_431_REQ_HDR_FIELDS_TOO_LARGE ;
544555 break ;
545556 default :
@@ -649,7 +660,6 @@ static esp_err_t httpd_parse_req(struct httpd_data *hd)
649660 /* This is used by the callbacks to track
650661 * data usage of the buffer */
651662 parser_data .raw_datalen = blk_len + offset ;
652-
653663 /* Parse data block from buffer */
654664 if ((offset = parse_block (& parser , offset , blk_len )) < 0 ) {
655665 /* HTTP error occurred.
@@ -679,13 +689,17 @@ static void init_req(httpd_req_t *r, httpd_config_t *config)
679689static void init_req_aux (struct httpd_req_aux * ra , httpd_config_t * config )
680690{
681691 ra -> sd = 0 ;
682- memset (ra -> scratch , 0 , sizeof (ra -> scratch ));
683692 ra -> remaining_len = 0 ;
684693 ra -> status = 0 ;
685694 ra -> content_type = 0 ;
686695 ra -> first_chunk_sent = 0 ;
687696 ra -> req_hdrs_count = 0 ;
688697 ra -> resp_hdrs_count = 0 ;
698+ ra -> scratch = NULL ;
699+ 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 ;
689703#if CONFIG_HTTPD_WS_SUPPORT
690704 ra -> ws_handshake_detect = false;
691705#endif
@@ -716,6 +730,10 @@ static void httpd_req_cleanup(httpd_req_t *r)
716730
717731 /* Clear out the request and request_aux structures */
718732 ra -> sd = NULL ;
733+ free (ra -> scratch );
734+ ra -> scratch = NULL ;
735+ ra -> scratch_cur_size = 0 ;
736+ ra -> scratch_size_limit = 0 ;
719737 r -> handle = NULL ;
720738 r -> aux = NULL ;
721739 r -> user_ctx = NULL ;
0 commit comments