diff --git a/src/Client/AsyncDownloader.c b/src/Client/AsyncDownloader.c index 9ed9c54bb..506a69c36 100644 --- a/src/Client/AsyncDownloader.c +++ b/src/Client/AsyncDownloader.c @@ -218,21 +218,22 @@ void AsyncDownloader_ProcessRequest(AsyncRequest* request) { Stopwatch_Start(&stopwatch); result = Platform_HttpMakeRequest(request, &handle); elapsedMS = Stopwatch_ElapsedMicroseconds(&stopwatch) / 1000; - Platform_Log2("HTTP get request %i in %i ms", &result, &elapsedMS); - if (!ErrorHandler_Check(result)) return; + Platform_Log2("HTTP get request: ret code %i, in %i ms", &result, &elapsedMS); + if (!ErrorHandler_Check(result)) return; void* data = NULL; UInt32 size = 0; Stopwatch_Start(&stopwatch); result = Platform_HttpGetRequestData(request, handle, &data, &size); elapsedMS = Stopwatch_ElapsedMicroseconds(&stopwatch) / 1000; - Platform_Log2("HTTP get data %i in %i ms", &result, &elapsedMS); + UInt32 status = request->StatusCode; + Platform_Log3("HTTP get data: ret code %i (http %i), in %i ms", &result, &status, &elapsedMS); Platform_HttpFreeRequest(handle); - if (!ErrorHandler_Check(result)) return; + if (!ErrorHandler_Check(result) || request->StatusCode != 200) return; UInt64 addr = (UInt64)data; - Platform_Log2("OK I got the DATA! %x of %i", &addr, &size); + Platform_Log2("OK I got the DATA! %i bytes at %x", &size, &addr); Stream memStream; switch (request->RequestType) { diff --git a/src/Client/AsyncDownloader.h b/src/Client/AsyncDownloader.h index 7c71edf39..2cda79370 100644 --- a/src/Client/AsyncDownloader.h +++ b/src/Client/AsyncDownloader.h @@ -18,7 +18,7 @@ typedef struct AsyncRequest_ { DateTime TimeAdded; DateTime TimeDownloaded; - UInt16 ResponseCode; + UInt16 StatusCode; union { struct { void* Ptr; UInt32 Size; } ResultData; diff --git a/src/Client/Deflate.c b/src/Client/Deflate.c index 3e607f1ce..68202ed38 100644 --- a/src/Client/Deflate.c +++ b/src/Client/Deflate.c @@ -170,11 +170,11 @@ enum INFLATE_STATE_ { /* Goes to the next state, after having read data of a block. */ #define Inflate_NextBlockState(state) (state->LastBlock ? INFLATE_STATE_DONE : INFLATE_STATE_HEADER) /* Goes to the next state, after having finished reading a compressed entry. */ -/* The maximum amount of bytes that can be output is 258. */ -/* The most input bytes required for huffman codes and extra data is 16 + 5 + 16 + 13 bits. Add 3 extra bytes to account for putting data into the bit buffer. */ -#define INFLATE_FASTINF_OUT 258 -#define INFLATE_FASTINF_IN 10 #define Inflate_NextCompressState(state) ((state->AvailIn >= INFLATE_FASTINF_IN && state->AvailOut >= INFLATE_FASTINF_OUT) ? INFLATE_STATE_FASTCOMPRESSED : INFLATE_STATE_COMPRESSED_LIT) +/* The maximum amount of bytes that can be output is 258. */ +#define INFLATE_FASTINF_OUT 258 +/* The most input bytes required for huffman codes and extra data is 16 + 5 + 16 + 13 bits. Add 3 extra bytes to account for putting data into the bit buffer. */ +#define INFLATE_FASTINF_IN 10 UInt32 Huffman_ReverseBits(UInt32 n, UInt8 bits) { n = ((n & 0xAAAA) >> 1) | ((n & 0x5555) << 1); diff --git a/src/Client/WinPlatform.c b/src/Client/WinPlatform.c index b4c8a31a4..a33fb306d 100644 --- a/src/Client/WinPlatform.c +++ b/src/Client/WinPlatform.c @@ -609,19 +609,39 @@ ReturnCode Platform_HttpMakeRequest(AsyncRequest* request, void** handle) { return *handle == NULL ? GetLastError() : 0; } +/* TODO: May need to rethink this API design a bit - probably want to split parse headers function out */ +/* TODO: Test last modified and etag even work */ +#define Http_Query(flags, result) HttpQueryInfoA(handle, flags, result, &bufferLen, NULL) ReturnCode Platform_HttpGetRequestData(AsyncRequest* request, void* handle, void** data, UInt32* size) { - DWORD bufferLen = sizeof(DWORD); - BOOL success = HttpQueryInfoA(handle, HTTP_QUERY_CONTENT_LENGTH | HTTP_QUERY_FLAG_NUMBER, size, &bufferLen, 0); - if (!success) return GetLastError(); - if (*size == 0) return 1; + DWORD bufferLen; + UInt32 status; + bufferLen = sizeof(DWORD); + if (!Http_Query(HTTP_QUERY_STATUS_CODE | HTTP_QUERY_FLAG_NUMBER, &status)) return GetLastError(); + request->StatusCode = status; + + bufferLen = sizeof(DWORD); + if (!Http_Query(HTTP_QUERY_CONTENT_LENGTH | HTTP_QUERY_FLAG_NUMBER, size)) return GetLastError(); + + SYSTEMTIME lastModified; + bufferLen = sizeof(SYSTEMTIME); + if (Http_Query(HTTP_QUERY_LAST_MODIFIED | HTTP_QUERY_FLAG_SYSTEMTIME, &lastModified)) { + Platform_FromSysTime(&request->LastModified, &lastModified); + } + + String etag = String_InitAndClearArray(request->Etag); + bufferLen = etag.capacity; + Http_Query(HTTP_QUERY_ETAG, etag.buffer, &bufferLen); + + if (*size == 0) return 1; *data = Platform_MemAlloc(*size, 1); if (*data == NULL) ErrorHandler_Fail("Failed to allocate memory for http get data"); + UInt8* buffer = *data; UInt32 left = *size, read; while (left > 0) { - success = InternetReadFile(handle, buffer, left, &read); + bool success = InternetReadFile(handle, buffer, left, &read); if (!success) { Platform_MemFree(data); return GetLastError(); } if (read == 0) break;