From a20504642d083172f297543f9788b128e9c2e0bc Mon Sep 17 00:00:00 2001 From: Nayeem Rahman Date: Mon, 12 Apr 2021 15:24:45 +0100 Subject: fix(runtime/js/http): Correctly parse user response headers (#10076) --- cli/tests/unit/http_test.ts | 3 ++- runtime/js/40_http.js | 31 ++++++++++++------------------- 2 files changed, 14 insertions(+), 20 deletions(-) diff --git a/cli/tests/unit/http_test.ts b/cli/tests/unit/http_test.ts index 94c7ac887..f7ea3a75a 100644 --- a/cli/tests/unit/http_test.ts +++ b/cli/tests/unit/http_test.ts @@ -13,7 +13,7 @@ unitTest({ perms: { net: true } }, async function httpServerBasic() { const httpConn = Deno.serveHttp(conn); for await (const { request, respondWith } of httpConn) { assertEquals(await request.text(), ""); - respondWith(new Response("Hello World")); + respondWith(new Response("Hello World", { headers: { "foo": "bar" } })); } break; } @@ -24,6 +24,7 @@ unitTest({ perms: { net: true } }, async function httpServerBasic() { }); const text = await resp.text(); assertEquals(text, "Hello World"); + assertEquals(resp.headers.get("foo"), "bar"); await promise; }); diff --git a/runtime/js/40_http.js b/runtime/js/40_http.js index dd6c99a2d..d9dff7b52 100644 --- a/runtime/js/40_http.js +++ b/runtime/js/40_http.js @@ -9,15 +9,6 @@ const core = window.Deno.core; const { ReadableStream } = window.__bootstrap.streams; - function flatEntries(obj) { - const entries = []; - for (const key in obj) { - entries.push(key); - entries.push(obj[key]); - } - return entries; - } - function serveHttp(conn) { const rid = Deno.core.jsonOpSync("op_http_start", conn.rid); return new HttpConn(rid); @@ -104,12 +95,14 @@ ); } - function respond(responseSenderRid, resp, zeroCopyBuf) { - return Deno.core.jsonOpSync("op_http_response", [ - responseSenderRid, - resp.status ?? 200, - flatEntries(resp.headers ?? {}), - ], zeroCopyBuf); + /** IMPORTANT: Equivalent to `Array.from(headers).flat()` but more performant. + * Please preserve. */ + function flattenHeaders(headers) { + const array = []; + for (const pair of headers) { + array.push(pair[0], pair[1]); + } + return array; } function createRespondWith(responseSenderRid, connRid) { @@ -136,11 +129,11 @@ zeroCopyBuf = null; } - const responseBodyRid = respond( + const responseBodyRid = Deno.core.jsonOpSync("op_http_response", [ responseSenderRid, - resp, - zeroCopyBuf, - ); + resp.status ?? 200, + flattenHeaders(resp.headers), + ], zeroCopyBuf); // If `respond` returns a responseBodyRid, we should stream the body // to that resource. -- cgit v1.2.3