diff --git a/source/core/http.c b/source/core/http.c index 4371d10..8f555e5 100644 --- a/source/core/http.c +++ b/source/core/http.c @@ -26,6 +26,35 @@ struct http_context_s { u32 bufferSize; }; +void http_resolve_redirect(char* oldUrl, const char* redirectTo, size_t size) { + if(size > 0) { + if(redirectTo[0] == '/') { + char* baseEnd = oldUrl; + + // Find the third slash to find the end of the URL's base; e.g. https://www.example.com/ + u32 slashCount = 0; + while(*baseEnd != '\0' && (baseEnd = strchr(baseEnd + 1, '/')) != NULL) { + slashCount++; + if(slashCount == 3) { + break; + } + } + + // If there are less than 3 slashes, assume the base URL ends at the end of the string; e.g. https://www.example.com + if(slashCount != 3) { + baseEnd = oldUrl + strlen(oldUrl); + } + + size_t baseLen = baseEnd - oldUrl; + if(baseLen < size) { + string_copy(baseEnd, redirectTo, size - baseLen); + } + } else { + string_copy(oldUrl, redirectTo, size); + } + } +} + Result http_open(http_context* context, const char* url, bool userAgent) { return http_open_ranged(context, url, userAgent, 0, 0); } @@ -64,9 +93,12 @@ Result http_open_ranged(http_context* context, const char* url, bool userAgent, if(response == 301 || response == 302 || response == 303) { redirectCount++; - memset(currUrl, '\0', sizeof(currUrl)); - if(R_SUCCEEDED(res = httpcGetResponseHeader(&ctx->httpc, "Location", currUrl, sizeof(currUrl)))) { + char redirectTo[1024]; + memset(redirectTo, '\0', sizeof(redirectTo)); + if(R_SUCCEEDED(res = httpcGetResponseHeader(&ctx->httpc, "Location", redirectTo, sizeof(redirectTo)))) { httpcCloseContext(&ctx->httpc); + + http_resolve_redirect(currUrl, redirectTo, sizeof(currUrl)); } } else { resolved = true;