Unify http backends buffer init/expanding

This commit is contained in:
UnknownShadow200 2019-07-06 21:30:44 +10:00
parent 62bab79201
commit 4949e64663
2 changed files with 36 additions and 56 deletions

View File

@ -388,6 +388,31 @@ static void Http_DownloadAsync(struct HttpRequest* req) {
/*########################################################################################################################* /*########################################################################################################################*
*--------------------------------------------------Native implementation--------------------------------------------------* *--------------------------------------------------Native implementation--------------------------------------------------*
*#########################################################################################################################*/ *#########################################################################################################################*/
static uint32_t bufferSize;
/* Allocates initial data buffer to store response contents */
static void Http_BufferInit(struct HttpRequest* req) {
http_curProgress = 0;
bufferSize = req->ContentLength ? req->ContentLength : 1;
req->Data = (uint8_t*)Mem_Alloc(bufferSize, 1, "http get data");
req->Size = 0;
}
/* Ensures data buffer has enough space left to append amount bytes, reallocates if not */
static void Http_BufferEnsure(struct HttpRequest* req, uint32_t amount) {
uint32_t newSize = req->Size + amount;
if (newSize <= bufferSize) return;
bufferSize = newSize;
req->Data = (uint8_t*)Mem_Realloc(req->Data, newSize, 1, "http inc data");
}
/* Increases size and updates current progress */
static void Http_BufferExpanded(struct HttpRequest* req, uint32_t read) {
req->Size += read;
if (req->ContentLength) http_curProgress = (int)(100.0f * req->Size / req->ContentLength);
}
#if defined CC_BUILD_WININET #if defined CC_BUILD_WININET
static HINTERNET hInternet; static HINTERNET hInternet;
/* TODO: Test last modified and etag even work */ /* TODO: Test last modified and etag even work */
@ -540,37 +565,17 @@ static ReturnCode Http_ProcessHeaders(struct HttpRequest* req, HINTERNET handle)
/* Downloads the data/contents of a HTTP response */ /* Downloads the data/contents of a HTTP response */
static ReturnCode Http_DownloadData(struct HttpRequest* req, HINTERNET handle) { static ReturnCode Http_DownloadData(struct HttpRequest* req, HINTERNET handle) {
uint8_t* buffer;
uint32_t size, totalRead;
DWORD read, avail; DWORD read, avail;
BOOL success; Http_BufferInit(req);
http_curProgress = 0;
size = req->ContentLength ? req->ContentLength : 1;
buffer = (uint8_t*)Mem_Alloc(size, 1, "http get data");
totalRead = 0;
req->Data = buffer;
req->Size = 0;
for (;;) { for (;;) {
if (!InternetQueryDataAvailable(handle, &avail, 0, 0)) break; if (!InternetQueryDataAvailable(handle, &avail, 0, 0)) break;
if (!avail) break; if (!avail) break;
Http_BufferEnsure(req, avail);
/* expand if buffer is too small (some servers don't give content length) */ if (!InternetReadFile(handle, &req->Data[req->Size], avail, &read)) return GetLastError();
if (totalRead + avail > size) {
size = totalRead + avail;
buffer = (uint8_t*)Mem_Realloc(buffer, size, 1, "http inc data");
req->Data = buffer;
}
success = InternetReadFile(handle, &buffer[totalRead], avail, &read);
if (!success) return GetLastError();
if (!read) break; if (!read) break;
Http_BufferExpanded(req, read);
totalRead += read;
if (req->ContentLength) http_curProgress = (int)(100.0f * totalRead / size);
req->Size += read;
} }
http_curProgress = 100; http_curProgress = 100;
@ -622,12 +627,6 @@ static void Http_SysInit(void) {
if (!curl) Logger_Abort("Failed to init easy curl"); if (!curl) Logger_Abort("Failed to init easy curl");
} }
/* Updates progress of current download */
static int Http_UpdateProgress(void* ptr, double total, double received, double a, double b) {
if (total) http_curProgress = (int)(100 * received / total);
return 0;
}
static struct curl_slist* headers_list; static struct curl_slist* headers_list;
static void Http_AddHeader(const char* key, const String* value) { static void Http_AddHeader(const char* key, const String* value) {
String tmp; char tmpBuffer[1024]; String tmp; char tmpBuffer[1024];
@ -641,10 +640,7 @@ static void Http_AddHeader(const char* key, const String* value) {
/* Processes a HTTP header downloaded from the server */ /* Processes a HTTP header downloaded from the server */
static size_t Http_ProcessHeader(char *buffer, size_t size, size_t nitems, void* userdata) { static size_t Http_ProcessHeader(char *buffer, size_t size, size_t nitems, void* userdata) {
struct HttpRequest* req = (struct HttpRequest*)userdata; struct HttpRequest* req = (struct HttpRequest*)userdata;
String line; String line = String_Init(buffer, nitems, nitems);
if (size != 1) return size * nitems; /* non byte header */
line = String_Init(buffer, nitems, nitems);
/* line usually has \r\n at end */ /* line usually has \r\n at end */
if (line.length && line.buffer[line.length - 1] == '\n') line.length--; if (line.length && line.buffer[line.length - 1] == '\n') line.length--;
@ -654,27 +650,15 @@ static size_t Http_ProcessHeader(char *buffer, size_t size, size_t nitems, void*
return nitems; return nitems;
} }
static int curlBufferSize;
/* Processes a chunk of data downloaded from the web server */ /* Processes a chunk of data downloaded from the web server */
static size_t Http_ProcessData(char *buffer, size_t size, size_t nitems, void* userdata) { static size_t Http_ProcessData(char *buffer, size_t size, size_t nitems, void* userdata) {
struct HttpRequest* req = (struct HttpRequest*)userdata; struct HttpRequest* req = (struct HttpRequest*)userdata;
uint8_t* dst;
if (!curlBufferSize) { if (!bufferSize) Http_BufferInit(req);
curlBufferSize = req->ContentLength ? req->ContentLength : 1; Http_BufferEnsure(req, nitems);
req->Data = (uint8_t*)Mem_Alloc(curlBufferSize, 1, "http get data");
req->Size = 0;
}
/* expand buffer if needed */ Mem_Copy(&req->Data[req->Size], buffer, nitems);
if (req->Size + nitems > curlBufferSize) { Http_BufferExpanded(req, nitems);
curlBufferSize = req->Size + nitems;
req->Data = (uint8_t*)Mem_Realloc(req->Data, curlBufferSize, 1, "http inc data");
}
dst = (uint8_t*)req->Data + req->Size;
Mem_Copy(dst, buffer, nitems);
req->Size += nitems;
return nitems; return nitems;
} }
@ -683,9 +667,6 @@ static void Http_SetCurlOpts(struct HttpRequest* req) {
curl_easy_setopt(curl, CURLOPT_USERAGENT, GAME_APP_NAME); curl_easy_setopt(curl, CURLOPT_USERAGENT, GAME_APP_NAME);
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0L);
curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, Http_UpdateProgress);
curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, Http_ProcessHeader); curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, Http_ProcessHeader);
curl_easy_setopt(curl, CURLOPT_HEADERDATA, req); curl_easy_setopt(curl, CURLOPT_HEADERDATA, req);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, Http_ProcessData); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, Http_ProcessData);
@ -720,7 +701,7 @@ static ReturnCode Http_SysDo(struct HttpRequest* req) {
HttpRequest_Free(req); HttpRequest_Free(req);
} }
curlBufferSize = 0; bufferSize = 0;
http_curProgress = ASYNC_PROGRESS_FETCHING_DATA; http_curProgress = ASYNC_PROGRESS_FETCHING_DATA;
res = curl_easy_perform(curl); res = curl_easy_perform(curl);
http_curProgress = 100; http_curProgress = 100;

View File

@ -377,7 +377,7 @@ void Logger_Backtrace(String* trace, void* ctx) {
/*########################################################################################################################* /*########################################################################################################################*
*-------------------------------------------------------Info dumping------------------------------------------------------* *-----------------------------------------------------CPU registers-------------------------------------------------------*
*#########################################################################################################################*/ *#########################################################################################################################*/
/* Unfortunately, operating systems vary wildly in how they name and access registers for dumping */ /* Unfortunately, operating systems vary wildly in how they name and access registers for dumping */
/* So this is the simplest way to avoid duplicating code on each platform */ /* So this is the simplest way to avoid duplicating code on each platform */
@ -432,7 +432,6 @@ String_Format2(&str, "pc=%x nc=%x" _NL, REG_GET(pc,PC), REG_GET(npc,
#if defined CC_BUILD_WEB #if defined CC_BUILD_WEB
static void Logger_DumpRegisters(void* ctx) { } static void Logger_DumpRegisters(void* ctx) { }
static void Logger_DumpMisc(void* ctx) { }
#elif defined CC_BUILD_WIN #elif defined CC_BUILD_WIN
static void Logger_DumpRegisters(void* ctx) { static void Logger_DumpRegisters(void* ctx) {
String str; char strBuffer[512]; String str; char strBuffer[512];