Skip to content

Commit

Permalink
fix(js-runtime): Response.error() & Response.redirect() WPT confo…
Browse files Browse the repository at this point in the history
…rmance (#429)

* fix(js-runtime): `Response.error()` & `Response.redirect()` WPT conformance

* chore: add changeset

* fix: current-results log
  • Loading branch information
QuiiBz committed Dec 28, 2022
1 parent 3006a60 commit 84290e6
Show file tree
Hide file tree
Showing 6 changed files with 61 additions and 28 deletions.
5 changes: 5 additions & 0 deletions .changeset/loud-clocks-tell.md
@@ -0,0 +1,5 @@
---
'@lagon/js-runtime': patch
---

Fix implementation of `Response.error()` & `Response.redirect()`
4 changes: 4 additions & 0 deletions packages/js-runtime/src/index.ts
Expand Up @@ -74,6 +74,10 @@ declare global {
interface Blob {
readonly buffer: Uint8Array;
}

interface Headers {
immutable: boolean;
}
}

export async function masterHandler(request: {
Expand Down
13 changes: 13 additions & 0 deletions packages/js-runtime/src/runtime/http/Headers.ts
@@ -1,6 +1,7 @@
(globalThis => {
globalThis.Headers = class {
private readonly h: Map<string, string[]> = new Map();
immutable = false;

constructor(init?: HeadersInit) {
if (init === null) {
Expand Down Expand Up @@ -49,11 +50,19 @@
}

append(name: string, value: string) {
if (this.immutable) {
throw new TypeError('Headers are immutable');
}

name = name.toLowerCase();
this.addValue(name, value);
}

delete(name: string) {
if (this.immutable) {
throw new TypeError('Headers are immutable');
}

name = name.toLowerCase();
this.h.delete(name);
}
Expand Down Expand Up @@ -81,6 +90,10 @@
}

set(name: string, value: string) {
if (this.immutable) {
throw new TypeError('Headers are immutable');
}

name = name.toLowerCase();
value = String(value);
this.h.set(name, [value]);
Expand Down
38 changes: 25 additions & 13 deletions packages/js-runtime/src/runtime/http/Response.ts
Expand Up @@ -3,6 +3,8 @@ import { RequestResponseBody } from './body';
(globalThis => {
// https://fetch.spec.whatwg.org/#null-body-status
const NULL_BODY_STATUS = [101, 103, 204, 205, 304];
// https://fetch.spec.whatwg.org/#redirect-status
const REDIRECT_STATUS = [301, 302, 303, 307, 308];

globalThis.Response = class extends RequestResponseBody {
ok: boolean;
Expand All @@ -25,8 +27,8 @@ import { RequestResponseBody } from './body';
this.ok = true;
}

this.status = init?.status || 200;
this.statusText = init?.statusText || '';
this.status = init?.status ?? 200;
this.statusText = init?.statusText ?? '';
// TODO: investigate
// @ts-expect-error ResponseInit doesn't have url
this.url = init?.url || '';
Expand All @@ -43,19 +45,29 @@ import { RequestResponseBody } from './body';
}

static error(): Response {
return {
...new Response(),
type: 'error',
};
const response = new Response(null, {
status: 0,
});
// @ts-expect-error we modify a read-only property
response.type = 'error';
response.headers.immutable = true;

return response;
}

static redirect(url: string | URL, status?: number): Response {
const response = {
...new Response(null, {
status,
}),
url: url.toString(),
};
static redirect(url: string | URL, status = 302): Response {
if (!REDIRECT_STATUS.includes(status)) {
throw new RangeError('Invalid status code');
}

const response = new Response(null, {
status,
headers: {
Location: new URL(url).toString(),
},
});
// @ts-expect-error we modify a read-only property
response.type = 'default';

return response;
}
Expand Down
1 change: 0 additions & 1 deletion packages/js-runtime/src/runtime/http/URL.ts
Expand Up @@ -82,7 +82,6 @@
}

get href(): string {
// TODO: username and password
const credentials = this.username + (this.password ? ':' + this.password : '');

let href =
Expand Down
28 changes: 14 additions & 14 deletions packages/wpt-runner/current-results.md
Expand Up @@ -473,8 +473,8 @@ TEST DONE 0 Can override Content-Type for Response with string body
TEST DONE 0 Can override Content-Type for Response with ReadableStream body
TEST DONE 1 Default Content-Type for Response with FormData body
Running ../../tools/wpt/fetch/api/response/response-static-error.any.js
TEST DONE 1 Check response returned by static method error()
TEST DONE 1 the 'guard' of the Headers instance should be immutable
TEST DONE 0 Check response returned by static method error()
TEST DONE 0 the 'guard' of the Headers instance should be immutable
Running ../../tools/wpt/fetch/api/response/response-static-json.any.js
TEST DONE 0 Throws TypeError when calling static json() with a status of 204
TEST DONE 0 Throws TypeError when calling static json() with a status of 205
Expand All @@ -490,17 +490,17 @@ TEST DONE 0 Check response returned by static json() with init {"headers":{"x-fo
TEST DONE 0 Check static json() encodes JSON objects correctly
TEST DONE 0 Check static json() propagates JSON serializer errors
Running ../../tools/wpt/fetch/api/response/response-static-redirect.any.js
TEST DONE 1 Check default redirect response
TEST DONE 1 Check response returned by static method redirect(), status = 301
TEST DONE 1 Check response returned by static method redirect(), status = 302
TEST DONE 1 Check response returned by static method redirect(), status = 303
TEST DONE 1 Check response returned by static method redirect(), status = 307
TEST DONE 1 Check response returned by static method redirect(), status = 308
TEST DONE 0 Check default redirect response
TEST DONE 0 Check response returned by static method redirect(), status = 301
TEST DONE 0 Check response returned by static method redirect(), status = 302
TEST DONE 0 Check response returned by static method redirect(), status = 303
TEST DONE 0 Check response returned by static method redirect(), status = 307
TEST DONE 0 Check response returned by static method redirect(), status = 308
TEST DONE 1 Check error returned when giving invalid url to redirect()
TEST DONE 1 Check error returned when giving invalid status to redirect(), status = 200
TEST DONE 1 Check error returned when giving invalid status to redirect(), status = 309
TEST DONE 1 Check error returned when giving invalid status to redirect(), status = 400
TEST DONE 1 Check error returned when giving invalid status to redirect(), status = 500
TEST DONE 0 Check error returned when giving invalid status to redirect(), status = 200
TEST DONE 0 Check error returned when giving invalid status to redirect(), status = 309
TEST DONE 0 Check error returned when giving invalid status to redirect(), status = 400
TEST DONE 0 Check error returned when giving invalid status to redirect(), status = 500
Running ../../tools/wpt/fetch/api/response/response-stream-bad-chunk.any.js
TEST DONE 1 ReadableStream with non-Uint8Array chunk passed to Response.arrayBuffer() causes TypeError
TEST DONE 1 ReadableStream with non-Uint8Array chunk passed to Response.blob() causes TypeError
Expand Down Expand Up @@ -1497,5 +1497,5 @@ TEST DONE 0 Blob.text() different charset param with non-ascii input
TEST DONE 1 Blob.text() invalid utf-8 input
TEST DONE 1 Blob.text() concurrent reads

1402 tests, 349 passed, 1047 failed
-> 24% conformance
1402 tests, 361 passed, 1035 failed
-> 25% conformance

1 comment on commit 84290e6

@vercel
Copy link

@vercel vercel bot commented on 84290e6 Dec 28, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Deployment failed with the following error:

Resource is limited - try again in 46 minutes (more than 100, code: "api-deployments-free-per-day").

Please sign in to comment.