Skip to content

Use local server for test_fetch_redirect. NFC #24638

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 11 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions test/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -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}')

Expand All @@ -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
Expand Down
79 changes: 62 additions & 17 deletions test/fetch/test_fetch_redirect.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,46 +9,91 @@
#include <stdlib.h>
#include <emscripten/fetch.h>

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) {
printf("Fetch readyState %d responseUrl %s\n", fetch->readyState, fetch->responseUrl ? fetch->responseUrl : "is null");
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;
}