From 93c82f1f9ee715d40ef01c4eff494227a2e3ec90 Mon Sep 17 00:00:00 2001 From: Gregor Hartmann Date: Sun, 10 May 2020 20:36:02 +0200 Subject: [PATCH] Fix binary and chunked HTTP downloads (#2985) Original sources by @anod221 --- app/http/httpclient.c | 15 +++++++++------ app/http/httpclient.h | 2 +- app/modules/http.c | 4 ++-- 3 files changed, 12 insertions(+), 9 deletions(-) diff --git a/app/http/httpclient.c b/app/http/httpclient.c index a73f7627..837add70 100644 --- a/app/http/httpclient.c +++ b/app/http/httpclient.c @@ -122,7 +122,7 @@ static int ICACHE_FLASH_ATTR http_chunked_decode( const char * chunked, char * d * */ - return(j); + return(decode_size); } @@ -306,6 +306,7 @@ static void ICACHE_FLASH_ATTR http_disconnect_callback( void * arg ) request_args_t * req = (request_args_t *) conn->reverse; int http_status = -1; char * body = ""; + int body_size = 0; // Turn off timeout timer os_timer_disarm( &(req->timeout_timer) ); @@ -411,15 +412,17 @@ static void ICACHE_FLASH_ATTR http_disconnect_callback( void * arg ) body = body + 4; } + body_size = req->buffer_size - (body - req->buffer); if ( strcasestr( req->buffer, "Transfer-Encoding: chunked" ) ) { - int body_size = req->buffer_size - (body - req->buffer); - char chunked_decode_buffer[body_size]; + char *chunked_decode_buffer = os_malloc(body_size); os_memset( chunked_decode_buffer, 0, body_size ); /* Chuncked data */ - http_chunked_decode( body, chunked_decode_buffer ); + body_size = http_chunked_decode( body, chunked_decode_buffer ); os_memcpy( body, chunked_decode_buffer, body_size ); + os_free( chunked_decode_buffer ); } + else --body_size; } } } @@ -432,7 +435,7 @@ static void ICACHE_FLASH_ATTR http_disconnect_callback( void * arg ) http_free_req( req ); - req_callback( body, http_status, &req_buffer ); + req_callback( body, http_status, &req_buffer, body_size ); if (req_buffer) { os_free(req_buffer); } @@ -498,7 +501,7 @@ static void ICACHE_FLASH_ATTR http_dns_callback( const char * hostname, ip_addr_ HTTPCLIENT_ERR( "DNS failed for %s", hostname ); if ( req->callback_handle != NULL ) { - req->callback_handle( "", -1, NULL ); + req->callback_handle( "", -1, NULL, 0 ); } http_free_req( req ); } diff --git a/app/http/httpclient.h b/app/http/httpclient.h index c69f7c36..179af9c5 100644 --- a/app/http/httpclient.h +++ b/app/http/httpclient.h @@ -53,7 +53,7 @@ static const char log_prefix[] = "HTTP client: "; * A successful request corresponds to an HTTP status code of 200 (OK). * More info at http://en.wikipedia.org/wiki/List_of_HTTP_status_codes */ -typedef void (* http_callback_t)(char * response_body, int http_status, char ** full_response_p); +typedef void (* http_callback_t)(char * response_body, int http_status, char ** full_response_p, int body_size); /* * Call this function to skip URL parsing if the arguments are already in separate variables. diff --git a/app/modules/http.c b/app/modules/http.c index e79a76b2..9bb24020 100644 --- a/app/modules/http.c +++ b/app/modules/http.c @@ -13,7 +13,7 @@ #include static int http_callback_registry = LUA_NOREF; -static void http_callback( char * response, int http_status, char ** full_response_p ) +static void http_callback( char * response, int http_status, char ** full_response_p, int body_size ) { const char *full_response = full_response_p ? *full_response_p : NULL; @@ -36,7 +36,7 @@ static void http_callback( char * response, int http_status, char ** full_respon lua_pushnumber(L, http_status); if ( http_status != HTTP_STATUS_GENERIC_ERROR && response) { - lua_pushstring(L, response); + lua_pushlstring(L, response, (size_t)body_size); lua_newtable(L); const char *p = full_response;