From a55b194638bcaace38917703b7d9233fb1989d44 Mon Sep 17 00:00:00 2001 From: Marcos Casagrande Date: Sun, 2 Oct 2022 01:21:48 +0200 Subject: [PATCH] fix(ext/cache): acquire reader lock before async op (#16126) --- cli/tests/unit/cache_api_test.ts | 22 ++++++++++++++++++++++ ext/cache/01_cache.js | 7 ++++--- 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/cli/tests/unit/cache_api_test.ts b/cli/tests/unit/cache_api_test.ts index 4d7c6511bc..8b84bfc6d3 100644 --- a/cli/tests/unit/cache_api_test.ts +++ b/cli/tests/unit/cache_api_test.ts @@ -94,3 +94,25 @@ Deno.test(async function cacheApi() { assert(await caches.delete(cacheName)); assertFalse(await caches.has(cacheName)); }); + +Deno.test(async function cachePutReaderLock() { + const cacheName = "cache-v1"; + const cache = await caches.open(cacheName); + + const response = new Response("consumed"); + + const promise = cache.put( + new Request("https://example.com/"), + response, + ); + + assertRejects( + async () => { + await response.arrayBuffer(); + }, + TypeError, + "Body already consumed.", + ); + + await promise; +}); diff --git a/ext/cache/01_cache.js b/ext/cache/01_cache.js index b08de3675d..c2843cedb5 100644 --- a/ext/cache/01_cache.js +++ b/ext/cache/01_cache.js @@ -119,8 +119,10 @@ // Step 8. if (innerResponse.body !== null && innerResponse.body.unusable()) { - throw new TypeError("Response body must not already used"); + throw new TypeError("Response body is already used"); } + // acquire lock before async op + const reader = innerResponse.body?.stream.getReader(); // Remove fragment from request URL before put. reqUrl.hash = ""; @@ -138,8 +140,7 @@ responseStatusText: innerResponse.statusMessage, }, ); - if (innerResponse.body) { - const reader = innerResponse.body.stream.getReader(); + if (reader) { while (true) { const { value, done } = await reader.read(); if (done) {