summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cli/js/web/fetch.ts6
-rw-r--r--cli/tests/unit/fetch_test.ts21
-rw-r--r--cli/tests/unit/url_test.ts13
-rw-r--r--test_util/src/lib.rs8
4 files changed, 43 insertions, 5 deletions
diff --git a/cli/js/web/fetch.ts b/cli/js/web/fetch.ts
index 543560c8d..d692b83e1 100644
--- a/cli/js/web/fetch.ts
+++ b/cli/js/web/fetch.ts
@@ -342,11 +342,7 @@ export async function fetch(
!redirectUrl.startsWith("http://") &&
!redirectUrl.startsWith("https://")
) {
- redirectUrl =
- url.split("//")[0] +
- "//" +
- url.split("//")[1].split("/")[0] +
- redirectUrl; // TODO: handle relative redirection more gracefully
+ redirectUrl = new URL(redirectUrl, url).href;
}
url = redirectUrl;
redirected = true;
diff --git a/cli/tests/unit/fetch_test.ts b/cli/tests/unit/fetch_test.ts
index 84f2c2822..c93cc0c85 100644
--- a/cli/tests/unit/fetch_test.ts
+++ b/cli/tests/unit/fetch_test.ts
@@ -339,6 +339,27 @@ unitTest(
{
perms: { net: true },
},
+ async function fetchWithRelativeRedirectionUrl(): Promise<void> {
+ const cases = [
+ ["end", "http://localhost:4550/a/b/end"],
+ ["/end", "http://localhost:4550/end"],
+ ];
+ for (const [loc, redUrl] of cases) {
+ const response = await fetch("http://localhost:4550/a/b/c", {
+ headers: new Headers([["x-location", loc]]),
+ });
+ assertEquals(response.url, redUrl);
+ assertEquals(response.redirected, true);
+ assertEquals(response.status, 404);
+ assertEquals(await response.text(), "");
+ }
+ }
+);
+
+unitTest(
+ {
+ perms: { net: true },
+ },
async function fetchWithInfRedirection(): Promise<void> {
const response = await fetch("http://localhost:4549/cli/tests"); // will redirect to the same place
assertEquals(response.status, 0); // network error
diff --git a/cli/tests/unit/url_test.ts b/cli/tests/unit/url_test.ts
index 177f605c1..3e7ac6214 100644
--- a/cli/tests/unit/url_test.ts
+++ b/cli/tests/unit/url_test.ts
@@ -240,6 +240,19 @@ unitTest(function urlBaseURL(): void {
);
const url = new URL("/foo/bar?baz=foo#qux", base);
assertEquals(url.href, "https://foo:bar@baz.qat:8000/foo/bar?baz=foo#qux");
+
+ assertEquals(
+ new URL("D", "https://foo.bar/path/a/b/c/d").href,
+ "https://foo.bar/path/a/b/c/D"
+ );
+
+ assertEquals(new URL("D", "https://foo.bar").href, "https://foo.bar/D");
+ assertEquals(new URL("D", "https://foo.bar/").href, "https://foo.bar/D");
+
+ assertEquals(
+ new URL("/d", "https://foo.bar/path/a/b/c/d").href,
+ "https://foo.bar/d"
+ );
});
unitTest(function urlBaseString(): void {
diff --git a/test_util/src/lib.rs b/test_util/src/lib.rs
index 73a1df043..10e803f5f 100644
--- a/test_util/src/lib.rs
+++ b/test_util/src/lib.rs
@@ -147,6 +147,14 @@ pub async fn run_all_servers() {
warp::redirect(u)
})
.or(
+ warp::path!("a" / "b" / "c")
+ .and(warp::header::<String>("x-location"))
+ .map(|token: String| {
+ let uri: Uri = token.parse().unwrap();
+ warp::redirect(uri)
+ }),
+ )
+ .or(
warp::any()
.and(warp::path::peek())
.and(warp::fs::dir(root_path()))