diff --git a/test/common.py b/test/common.py index cfa517a24ea72..dd1f88b640ab8 100644 --- a/test/common.py +++ b/test/common.py @@ -2148,6 +2148,20 @@ def do_POST(self): create_file(filename, post_data, binary=True) self.send_response(200) self.end_headers() + elif urlinfo.path.startswith('/status/'): + code_str = urlinfo.path[len('/status/'):] + code = int(code_str) + if code in (301, 302, 303, 307, 308): + self.send_response(code) + self.send_header('Location', '/status/200') + self.end_headers() + elif code == 200: + self.send_response(200) + self.send_header('Content-type', 'text/plain') + self.end_headers() + self.wfile.write(b'OK') + else: + self.send_error(400, f'Not implemented for {code}') else: print(f'do_POST: unexpected POST: {urlinfo}') @@ -2160,6 +2174,21 @@ def do_GET(self): self.send_header('Content-type', 'text/html') self.end_headers() self.wfile.write(read_binary(test_file('browser_harness.html'))) + elif info.path.startswith('/status/'): + code_str = info.path[len('/status/'):] + code = int(code_str) + if code in (301, 302, 303, 307, 308): + # Redirect to /status/200 + self.send_response(code) + self.send_header('Location', '/status/200') + self.end_headers() + elif code == 200: + self.send_response(200) + self.send_header('Content-type', 'text/plain') + self.end_headers() + self.wfile.write(b'OK') + else: + self.send_error(400, f'Not implemented for {code}') elif 'report_' in self.path: # the test is reporting its result. first change dir away from the # test dir, as it will be deleted now that the test is finishing, and diff --git a/test/fetch/test_fetch_redirect.c b/test/fetch/test_fetch_redirect.c index 39475dd487194..2b96f1e9063e8 100644 --- a/test/fetch/test_fetch_redirect.c +++ b/test/fetch/test_fetch_redirect.c @@ -9,27 +9,51 @@ #include #include -int fetchSync() { +#define SERVER "http://localhost:8888" + +// 301: Moved Permanently - https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/301 +// 302: Found (Previously "Moved Temporarily") - https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/302 +// 303: See Other - https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/303 +// 307: Temporary Redirect - https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/307 +// 308: Permanent Redirect - https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/308 +const int redirect_codes[] = {301, 302, 303, 307, 308}; +const int num_codes = sizeof(redirect_codes) / sizeof(redirect_codes[0]); + +void check_fetch_result(emscripten_fetch_t *fetch, int expected_status, const char *expected_url) { + printf("Fetch finished with status %d\n", fetch->status); + assert(fetch->status == expected_status); + printf("Downloaded %llu bytes\n", fetch->numBytes); + assert(strcmp(fetch->responseUrl, expected_url) == 0); +} + +void fetchSyncTest(int code, const char *method) { + char url[128]; + snprintf(url, sizeof(url), SERVER "/status/%d", code); emscripten_fetch_attr_t attr; emscripten_fetch_attr_init(&attr); - strcpy(attr.requestMethod, "GET"); + strcpy(attr.requestMethod, method); attr.attributes = EMSCRIPTEN_FETCH_LOAD_TO_MEMORY | EMSCRIPTEN_FETCH_SYNCHRONOUS | EMSCRIPTEN_FETCH_REPLACE; - emscripten_fetch_t *fetch = emscripten_fetch(&attr, "https://httpbin.org/status/307"); + emscripten_fetch_t *fetch = emscripten_fetch(&attr, url); assert(fetch); - printf("Fetch sync finished with status %d\n", fetch->status); - assert(fetch->status == 200); - printf("Downloaded %llu bytes", fetch->numBytes); - assert(strcmp(fetch->responseUrl, "https://httpbin.org/get") == 0); - exit(0); + check_fetch_result(fetch, 200, SERVER "/status/200"); + emscripten_fetch_close(fetch); } +void onsuccess(emscripten_fetch_t *fetch); +void onreadystatechange(emscripten_fetch_t *fetch); + +// State for async test +static int async_code_idx = 0; +static int async_method_idx = 0; +const char *methods[] = {"GET", "POST"}; +const int num_methods = 2; + +void start_next_async_fetch(); + void onsuccess(emscripten_fetch_t *fetch) { - printf("Fetch async finished with status %d\n", fetch->status); - assert(fetch->status == 200); - printf("Downloaded %llu bytes", fetch->numBytes); - assert(strcmp(fetch->responseUrl, "https://httpbin.org/get") == 0); + check_fetch_result(fetch, 200, SERVER "/status/200"); emscripten_fetch_close(fetch); - fetchSync(); + start_next_async_fetch(); } void onreadystatechange(emscripten_fetch_t *fetch) { @@ -37,18 +61,39 @@ void onreadystatechange(emscripten_fetch_t *fetch) { if (fetch->readyState < 2) { assert(NULL == fetch->responseUrl); } else { - assert(0 == strcmp(fetch->responseUrl, "https://httpbin.org/get")); + assert(0 == strcmp(fetch->responseUrl, SERVER "/status/200")); } } -int main() { +void start_next_async_fetch() { + if (async_code_idx >= num_codes) { + async_code_idx = 0; + async_method_idx++; + if (async_method_idx >= num_methods) { + // All async tests done, now run sync tests + for (int m = 0; m < num_methods; ++m) { + for (int i = 0; i < num_codes; ++i) { + fetchSyncTest(redirect_codes[i], methods[m]); + } + } + exit(0); + } + } + int code = redirect_codes[async_code_idx++]; + const char *method = methods[async_method_idx]; + char url[128]; + snprintf(url, sizeof(url), SERVER "/status/%d", code); emscripten_fetch_attr_t attr; emscripten_fetch_attr_init(&attr); - strcpy(attr.requestMethod, "GET"); + strcpy(attr.requestMethod, method); attr.attributes = EMSCRIPTEN_FETCH_LOAD_TO_MEMORY; attr.onsuccess = onsuccess; attr.onreadystatechange = onreadystatechange; - emscripten_fetch_t *fetch = emscripten_fetch(&attr, "https://httpbin.org/status/307"); + emscripten_fetch_t *fetch = emscripten_fetch(&attr, url); assert(fetch); +} + +int main() { + start_next_async_fetch(); return 99; }