diff options
author | Felipe Baltor <fbaltor@gmail.com> | 2023-07-30 10:13:28 -0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-07-30 09:13:28 -0400 |
commit | 3cb260ed15a26785272bb09427504a565010963d (patch) | |
tree | cc29322017d235d3d56c75240eab1ce9f1f8be76 /cli/tests/unit/serve_test.ts | |
parent | cfdef0c38038e42a4ac40f6e962c5e40a0c5cbe6 (diff) |
fix(Deno.serve): accessing .url on cloned request throws (#19869)
This PR fixes #19818. The problem was that the new InnerRequest class does not initialize the fields urlList and urlListProcessed that are used during a request clone. The solution aims to be straightforward by simply initializing the missing properties during the clone process. I also implemented a "cache" to the url getter of the new InnerRequest, avoiding the cost of calling op_http_get_request_method_and_url.
Diffstat (limited to 'cli/tests/unit/serve_test.ts')
-rw-r--r-- | cli/tests/unit/serve_test.ts | 96 |
1 files changed, 96 insertions, 0 deletions
diff --git a/cli/tests/unit/serve_test.ts b/cli/tests/unit/serve_test.ts index fd7cc869a..abb2562b1 100644 --- a/cli/tests/unit/serve_test.ts +++ b/cli/tests/unit/serve_test.ts @@ -2789,6 +2789,7 @@ Deno.test( // https://github.com/denoland/deno/issues/15858 Deno.test( + "Clone should work", { permissions: { net: true } }, async function httpServerCanCloneRequest() { const ac = new AbortController(); @@ -2799,6 +2800,20 @@ Deno.test( const cloned = req.clone(); assertEquals(req.headers, cloned.headers); + assertEquals(cloned.url, req.url); + assertEquals(cloned.cache, req.cache); + assertEquals(cloned.destination, req.destination); + assertEquals(cloned.headers, req.headers); + assertEquals(cloned.integrity, req.integrity); + assertEquals(cloned.isHistoryNavigation, req.isHistoryNavigation); + assertEquals(cloned.isReloadNavigation, req.isReloadNavigation); + assertEquals(cloned.keepalive, req.keepalive); + assertEquals(cloned.method, req.method); + assertEquals(cloned.mode, req.mode); + assertEquals(cloned.redirect, req.redirect); + assertEquals(cloned.referrer, req.referrer); + assertEquals(cloned.referrerPolicy, req.referrerPolicy); + // both requests can read body await req.text(); await cloned.json(); @@ -2826,6 +2841,87 @@ Deno.test( }, ); +// https://fetch.spec.whatwg.org/#dom-request-clone +Deno.test( + "Throw if disturbed", + { permissions: { net: true } }, + async function shouldThrowIfBodyIsUnusableDisturbed() { + const ac = new AbortController(); + const listeningPromise = deferred(); + + const server = Deno.serve({ + handler: async (req) => { + await req.text(); + + try { + req.clone(); + } catch (error) { + assert(error instanceof TypeError); + assert( + error.message.endsWith("Body is unusable."), + ); + + ac.abort(); + await server.finished; + } + + return new Response("ok"); + }, + signal: ac.signal, + onListen: ({ port }: { port: number }) => listeningPromise.resolve(port), + }); + + try { + const port = await listeningPromise; + await fetch(`http://localhost:${port}/`, { + headers: { connection: "close" }, + method: "POST", + body: '{"bar":true}', + }); + } catch (e) { + assert(e instanceof TypeError); + } finally { + ac.abort(); + await server.finished; + } + }, +); + +// TODO(fbaltor): As it is this test should throw and fail +// https://fetch.spec.whatwg.org/#dom-request-clone +Deno.test({ + name: "Throw if locked", + ignore: true, + permissions: { net: true }, + fn: async function shouldThrowIfBodyIsUnusableLocked() { + const ac = new AbortController(); + const listeningPromise = deferred(); + + const server = Deno.serve({ + handler: (req) => { + const _reader = req.body?.getReader(); + + req.clone(); + + return new Response("ok"); + }, + signal: ac.signal, + onListen: ({ port }: { port: number }) => listeningPromise.resolve(port), + }); + + const port = await listeningPromise; + const resp = await fetch(`http://localhost:${port}/`, { + headers: { connection: "close" }, + method: "POST", + body: '{"bar":true}', + }); + + ac.abort(); + await resp.body?.cancel(); + await server.finished; + }, +}); + // Checks large streaming response // https://github.com/denoland/deno/issues/16567 Deno.test( |