summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cli/tests/unit/cache_api_test.ts22
-rw-r--r--ext/cache/01_cache.js7
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 4d7c6511b..8b84bfc6d 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 b08de3675..c2843cedb 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) {