diff --git a/src/Http_Worker.c b/src/Http_Worker.c index d74509228..d9f70c269 100644 --- a/src/Http_Worker.c +++ b/src/Http_Worker.c @@ -1,131 +1,36 @@ #include "Core.h" -#ifndef CC_BUILD_WEB + +#if defined CC_BUILD_WEB +/* Implemented in web http backend without C worker thread(s) */ +#elif !defined CC_BUILD_NETWORKING +#include "Http.h" +#include "Game.h" + +void HttpRequest_Free(struct HttpRequest* request) { } + +cc_bool Http_GetResult(int reqID, struct HttpRequest* item) { + return false; +} + +int Http_AsyncGetSkin(const cc_string* skinName, cc_uint8 flags) { + return -1; +} + +int Http_CheckProgress(int reqID) { + return -1; +} + +void Http_LogError(const char* action, const struct HttpRequest* item) { +} + +static void Http_NullInit(void) { } + +struct IGameComponent Http_Component = { + Http_NullInit +}; +#else #include "_HttpBase.h" -/* Ensures data buffer has enough space left to append amount bytes */ -static cc_bool Http_BufferExpand(struct HttpRequest* req, cc_uint32 amount) { - cc_uint32 newSize = req->size + amount; - cc_uint8* ptr; - if (newSize <= req->_capacity) return true; - - if (!req->_capacity) { - /* Allocate initial storage */ - req->_capacity = req->contentLength ? req->contentLength : 1; - req->_capacity = max(req->_capacity, newSize); - - ptr = (cc_uint8*)Mem_TryAlloc(req->_capacity, 1); - } else { - /* Reallocate if capacity reached */ - req->_capacity = newSize; - ptr = (cc_uint8*)Mem_TryRealloc(req->data, newSize, 1); - } - - if (!ptr) return false; - req->data = ptr; - return true; -} - -/* Increases size and updates current progress */ -static void Http_BufferExpanded(struct HttpRequest* req, cc_uint32 read) { - req->size += read; - if (req->contentLength) req->progress = (int)(100.0f * req->size / req->contentLength); -} - - -/*########################################################################################################################* -*---------------------------------------------------Common backend code---------------------------------------------------* -*#########################################################################################################################*/ -static void Http_ParseCookie(struct HttpRequest* req, const cc_string* value) { - cc_string name, data; - int dataEnd; - String_UNSAFE_Separate(value, '=', &name, &data); - /* Cookie is: __cfduid=xyz; expires=abc; path=/; domain=.classicube.net; HttpOnly */ - /* However only the __cfduid=xyz part of the cookie should be stored */ - dataEnd = String_IndexOf(&data, ';'); - if (dataEnd >= 0) data.length = dataEnd; - - EntryList_Set(req->cookies, &name, &data, '='); -} - -static void Http_ParseContentLength(struct HttpRequest* req, const cc_string* value) { - int contentLen = 0; - Convert_ParseInt(value, &contentLen); - - if (contentLen <= 0) return; - req->contentLength = contentLen; -} - -/* Parses a HTTP header */ -static void Http_ParseHeader(struct HttpRequest* req, const cc_string* line) { - static const cc_string httpVersion = String_FromConst("HTTP"); - cc_string name, value, parts[3]; - int numParts; - - /* HTTP[version] [status code] [status reason] */ - if (String_CaselessStarts(line, &httpVersion)) { - numParts = String_UNSAFE_Split(line, ' ', parts, 3); - if (numParts >= 2) Convert_ParseInt(&parts[1], &req->statusCode); - } - /* For all other headers: name: value */ - if (!String_UNSAFE_Separate(line, ':', &name, &value)) return; - - if (String_CaselessEqualsConst(&name, "ETag")) { - String_CopyToRawArray(req->etag, &value); - } else if (String_CaselessEqualsConst(&name, "Content-Length")) { - Http_ParseContentLength(req, &value); - } else if (String_CaselessEqualsConst(&name, "X-Dropbox-Content-Length")) { - /* dropbox stopped returning Content-Length header since switching to chunked transfer */ - /* https://www.dropboxforum.com/t5/Discuss-Dropbox-Developer-API/Dropbox-media-can-t-be-access-by-azure-blob/td-p/575458 */ - Http_ParseContentLength(req, &value); - } else if (String_CaselessEqualsConst(&name, "Last-Modified")) { - String_CopyToRawArray(req->lastModified, &value); - } else if (req->cookies && String_CaselessEqualsConst(&name, "Set-Cookie")) { - Http_ParseCookie(req, &value); - } -} - -/* Adds a http header to the request headers. */ -static void Http_AddHeader(struct HttpRequest* req, const char* key, const cc_string* value); - -/* Adds all the appropriate headers for a request. */ -static void Http_SetRequestHeaders(struct HttpRequest* req) { - static const cc_string contentType = String_FromConst("application/x-www-form-urlencoded"); - cc_string str, cookies; char cookiesBuffer[1024]; - int i; - - if (req->lastModified[0]) { - str = String_FromRawArray(req->lastModified); - Http_AddHeader(req, "If-Modified-Since", &str); - } - if (req->etag[0]) { - str = String_FromRawArray(req->etag); - Http_AddHeader(req, "If-None-Match", &str); - } - - if (req->data) Http_AddHeader(req, "Content-Type", &contentType); - if (!req->cookies || !req->cookies->count) return; - - String_InitArray(cookies, cookiesBuffer); - for (i = 0; i < req->cookies->count; i++) { - if (i) String_AppendConst(&cookies, "; "); - str = StringsBuffer_UNSAFE_Get(req->cookies, i); - String_AppendString(&cookies, &str); - } - Http_AddHeader(req, "Cookie", &cookies); -} - -/* TODO: Rewrite to use a local variable instead */ -static cc_string* Http_GetUserAgent_UNSAFE(void) { - static char userAgentBuffer[STRING_SIZE]; - static cc_string userAgent; - - String_InitArray(userAgent, userAgentBuffer); - String_AppendConst(&userAgent, GAME_APP_NAME); - String_AppendConst(&userAgent, Platform_AppNameSuffix); - return &userAgent; -} - - #if CC_NET_BACKEND == CC_NET_BACKEND_BUILTIN #include "Errors.h" #include "PackedCol.h" @@ -737,24 +642,6 @@ static cc_result HttpBackend_Do(struct HttpRequest* req, cc_string* urlStr) { static cc_bool HttpBackend_DescribeError(cc_result res, cc_string* dst) { return SSLBackend_DescribeError(res, dst); } -#elif !defined CC_BUILD_NETWORKING -/*########################################################################################################################* -*------------------------------------------------------Null backend-------------------------------------------------------* -*#########################################################################################################################*/ -#include "Errors.h" - -static cc_bool HttpBackend_DescribeError(cc_result res, cc_string* dst) { - return false; -} - -static void HttpBackend_Init(void) { } - -static void Http_AddHeader(struct HttpRequest* req, const char* key, const cc_string* value) { } - -static cc_result HttpBackend_Do(struct HttpRequest* req, cc_string* url) { - req->progress = 100; - return ERR_NOT_SUPPORTED; -} #endif diff --git a/src/TexturePack.c b/src/TexturePack.c index 4e5c02e72..4b9d0d4f4 100644 --- a/src/TexturePack.c +++ b/src/TexturePack.c @@ -578,6 +578,7 @@ static cc_result ExtractFrom(struct Stream* stream, const cc_string* path) { } #if defined CC_BUILD_PS1 || defined CC_BUILD_SATURN +/* Load hardcoded texture pack */ #include "../misc/ps1/classicubezip.h" static cc_result ExtractFromFile(const cc_string* path) { @@ -586,6 +587,11 @@ static cc_result ExtractFromFile(const cc_string* path) { return ExtractFrom(&stream, path); } +#elif !defined CC_BUILD_FILESYSTEM +/* E.g. GBA/32X don't support textures at all */ +static cc_result ExtractFromFile(const cc_string* path) { + return ERR_NOT_SUPPORTED; +} #else static cc_result ExtractFromFile(const cc_string* path) { struct Stream stream; diff --git a/src/_HttpBase.h b/src/_HttpBase.h index 3ac646c98..af32751cf 100644 --- a/src/_HttpBase.h +++ b/src/_HttpBase.h @@ -23,14 +23,11 @@ void HttpRequest_Free(struct HttpRequest* request) { } #define HttpRequest_Copy(dst, src) Mem_Copy(dst, src, sizeof(struct HttpRequest)) + /*########################################################################################################################* *----------------------------------------------------Http requests list---------------------------------------------------* *#########################################################################################################################*/ -#ifdef CC_BUILD_NETWORKING - #define HTTP_DEF_ELEMS 10 -#else - #define HTTP_DEF_ELEMS 1 /* TODO better unused code removal */ -#endif +#define HTTP_DEF_ELEMS 10 struct RequestList { int count, capacity; @@ -111,6 +108,133 @@ static void RequestList_Free(struct RequestList* list) { } +/*########################################################################################################################* +*---------------------------------------------------Common buffer code----------------------------------------------------* +*#########################################################################################################################*/ +/* Ensures data buffer has enough space left to append amount bytes */ +static cc_bool Http_BufferExpand(struct HttpRequest* req, cc_uint32 amount) { + cc_uint32 newSize = req->size + amount; + cc_uint8* ptr; + if (newSize <= req->_capacity) return true; + + if (!req->_capacity) { + /* Allocate initial storage */ + req->_capacity = req->contentLength ? req->contentLength : 1; + req->_capacity = max(req->_capacity, newSize); + + ptr = (cc_uint8*)Mem_TryAlloc(req->_capacity, 1); + } else { + /* Reallocate if capacity reached */ + req->_capacity = newSize; + ptr = (cc_uint8*)Mem_TryRealloc(req->data, newSize, 1); + } + + if (!ptr) return false; + req->data = ptr; + return true; +} + +/* Increases size and updates current progress */ +static void Http_BufferExpanded(struct HttpRequest* req, cc_uint32 read) { + req->size += read; + if (req->contentLength) req->progress = (int)(100.0f * req->size / req->contentLength); +} + + +/*########################################################################################################################* +*---------------------------------------------------Common header code----------------------------------------------------* +*#########################################################################################################################*/ +static void Http_ParseCookie(struct HttpRequest* req, const cc_string* value) { + cc_string name, data; + int dataEnd; + String_UNSAFE_Separate(value, '=', &name, &data); + /* Cookie is: __cfduid=xyz; expires=abc; path=/; domain=.classicube.net; HttpOnly */ + /* However only the __cfduid=xyz part of the cookie should be stored */ + dataEnd = String_IndexOf(&data, ';'); + if (dataEnd >= 0) data.length = dataEnd; + + EntryList_Set(req->cookies, &name, &data, '='); +} + +static void Http_ParseContentLength(struct HttpRequest* req, const cc_string* value) { + int contentLen = 0; + Convert_ParseInt(value, &contentLen); + + if (contentLen <= 0) return; + req->contentLength = contentLen; +} + +/* Parses a HTTP header */ +static void Http_ParseHeader(struct HttpRequest* req, const cc_string* line) { + static const cc_string httpVersion = String_FromConst("HTTP"); + cc_string name, value, parts[3]; + int numParts; + + /* HTTP[version] [status code] [status reason] */ + if (String_CaselessStarts(line, &httpVersion)) { + numParts = String_UNSAFE_Split(line, ' ', parts, 3); + if (numParts >= 2) Convert_ParseInt(&parts[1], &req->statusCode); + } + /* For all other headers: name: value */ + if (!String_UNSAFE_Separate(line, ':', &name, &value)) return; + + if (String_CaselessEqualsConst(&name, "ETag")) { + String_CopyToRawArray(req->etag, &value); + } else if (String_CaselessEqualsConst(&name, "Content-Length")) { + Http_ParseContentLength(req, &value); + } else if (String_CaselessEqualsConst(&name, "X-Dropbox-Content-Length")) { + /* dropbox stopped returning Content-Length header since switching to chunked transfer */ + /* https://www.dropboxforum.com/t5/Discuss-Dropbox-Developer-API/Dropbox-media-can-t-be-access-by-azure-blob/td-p/575458 */ + Http_ParseContentLength(req, &value); + } else if (String_CaselessEqualsConst(&name, "Last-Modified")) { + String_CopyToRawArray(req->lastModified, &value); + } else if (req->cookies && String_CaselessEqualsConst(&name, "Set-Cookie")) { + Http_ParseCookie(req, &value); + } +} + +/* Adds a http header to the request headers. */ +static void Http_AddHeader(struct HttpRequest* req, const char* key, const cc_string* value); + +/* Adds all the appropriate headers for a request. */ +static void Http_SetRequestHeaders(struct HttpRequest* req) { + static const cc_string contentType = String_FromConst("application/x-www-form-urlencoded"); + cc_string str, cookies; char cookiesBuffer[1024]; + int i; + + if (req->lastModified[0]) { + str = String_FromRawArray(req->lastModified); + Http_AddHeader(req, "If-Modified-Since", &str); + } + if (req->etag[0]) { + str = String_FromRawArray(req->etag); + Http_AddHeader(req, "If-None-Match", &str); + } + + if (req->data) Http_AddHeader(req, "Content-Type", &contentType); + if (!req->cookies || !req->cookies->count) return; + + String_InitArray(cookies, cookiesBuffer); + for (i = 0; i < req->cookies->count; i++) { + if (i) String_AppendConst(&cookies, "; "); + str = StringsBuffer_UNSAFE_Get(req->cookies, i); + String_AppendString(&cookies, &str); + } + Http_AddHeader(req, "Cookie", &cookies); +} + +/* TODO: Rewrite to use a local variable instead */ +static cc_string* Http_GetUserAgent_UNSAFE(void) { + static char userAgentBuffer[STRING_SIZE]; + static cc_string userAgent; + + String_InitArray(userAgent, userAgentBuffer); + String_AppendConst(&userAgent, GAME_APP_NAME); + String_AppendConst(&userAgent, Platform_AppNameSuffix); + return &userAgent; +} + + /*########################################################################################################################* *--------------------------------------------------Common downloader code-------------------------------------------------* *#########################################################################################################################*/ diff --git a/third_party/bearssl/config.h b/third_party/bearssl/config.h index b12d3dca9..09791b8ba 100644 --- a/third_party/bearssl/config.h +++ b/third_party/bearssl/config.h @@ -32,18 +32,6 @@ * non-zero integer (normally 1). If the macro is not defined, then * autodetection applies. */ - -/* The x86 intrinsics seem to be incomplete compared to what aes_x86ni expects when compiling with NXDK */ -#ifdef NXDK - #define BR_AES_X86NI 0 - #define BR_ENABLE_INTRINSICS 0 - #define BR_SSE2 0 -#endif - -/* intrin.h doesn't exist in older TinyC */ -#if defined __TINYC__ -#define BR_INT128 0 -#endif /* * When BR_64 is enabled, 64-bit integer types are assumed to be diff --git a/third_party/bearssl/inner.h b/third_party/bearssl/inner.h index b9a80eb49..57ccd0600 100644 --- a/third_party/bearssl/inner.h +++ b/third_party/bearssl/inner.h @@ -35,6 +35,30 @@ #include "config.h" #include "bearssl.h" +/* ==== BEG ClassiCube specific ==== */ +static size_t br_strlen(const char* a) { + int i = 0; + while (*a++) i++; + return i; +} + +#define br_memcpy memcpy +#define br_memset memset +#define br_memmove memmove + +/* The x86 intrinsics seem to be incomplete compared to what aes_x86ni expects when compiling with NXDK */ +#ifdef NXDK + #define BR_AES_X86NI 0 + #define BR_ENABLE_INTRINSICS 0 + #define BR_SSE2 0 +#endif + +/* intrin.h doesn't exist in older TinyC */ +#if defined __TINYC__ + #define BR_INT128 0 +#endif +/* ==== END ClassiCube specific ==== */ + /* * On MSVC, disable the warning about applying unary minus on an * unsigned type: it is standard, we do it all the time, and for diff --git a/third_party/bearssl/ssl_client.c b/third_party/bearssl/ssl_client.c index 28c404b83..7975bcace 100644 --- a/third_party/bearssl/ssl_client.c +++ b/third_party/bearssl/ssl_client.c @@ -64,7 +64,7 @@ br_ssl_client_reset(br_ssl_client_context *cc, if (server_name == NULL) { cc->eng.server_name[0] = 0; } else { - n = strlen(server_name) + 1; + n = br_strlen(server_name) + 1; if (n > sizeof cc->eng.server_name) { br_ssl_engine_fail(&cc->eng, BR_ERR_BAD_PARAM); return 0; diff --git a/third_party/bearssl/ssl_hs_client.c b/third_party/bearssl/ssl_hs_client.c index 1a1cf4b31..8aeebe505 100644 --- a/third_party/bearssl/ssl_hs_client.c +++ b/third_party/bearssl/ssl_hs_client.c @@ -1246,7 +1246,7 @@ br_ssl_hs_client_run(void *t0ctx) /* copy-protocol-name */ size_t idx = T0_POP(); - size_t len = strlen(ENG->protocol_names[idx]); + size_t len = br_strlen(ENG->protocol_names[idx]); memcpy(ENG->pad, ENG->protocol_names[idx], len); T0_PUSH(len); @@ -1346,7 +1346,7 @@ br_ssl_hs_client_run(void *t0ctx) } len = 6; for (u = 0; u < ENG->protocol_names_num; u ++) { - len += 1 + strlen(ENG->protocol_names[u]); + len += 1 + br_strlen(ENG->protocol_names[u]); } T0_PUSH(len); @@ -1591,10 +1591,10 @@ br_ssl_hs_client_run(void *t0ctx) } break; case 63: { - /* strlen */ + /* br_strlen */ void *str = (unsigned char *)ENG + (size_t)T0_POP(); - T0_PUSH((uint32_t)strlen(str)); + T0_PUSH((uint32_t)br_strlen(str)); } break; @@ -1766,7 +1766,7 @@ br_ssl_hs_client_run(void *t0ctx) const char *name; name = ENG->protocol_names[u]; - if (len == strlen(name) && memcmp(ENG->pad, name, len) == 0) { + if (len == br_strlen(name) && memcmp(ENG->pad, name, len) == 0) { T0_PUSH(u); T0_RET(); } diff --git a/third_party/bearssl/x509_minimal.c b/third_party/bearssl/x509_minimal.c index b3079deca..9611a8e77 100644 --- a/third_party/bearssl/x509_minimal.c +++ b/third_party/bearssl/x509_minimal.c @@ -1440,7 +1440,7 @@ br_x509_minimal_run(void *t0ctx) T0_PUSH(0); T0_RET(); } - n1 = strlen(CTX->server_name); + n1 = br_strlen(CTX->server_name); n2 = CTX->pad[0]; if (n1 == n2 && eqnocase(&CTX->pad[1], CTX->server_name, n1)) { T0_PUSHi(-1);