Skip to content

Commit 277ade9

Browse files
SkyZeroZxthePunderWoman
authored andcommitted
fix(http): correctly cache blob responses in transfer cache (#67002)
Previously, Blob values were passed to `Uint8Array` this resulted in silently producing an empty array (length = 0) without throwing an error, leading to empty cached data PR Close #67002
1 parent aeb9b81 commit 277ade9

File tree

3 files changed

+205
-144
lines changed

3 files changed

+205
-144
lines changed

packages/common/http/src/transfer_cache.ts

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ import {
2121
ɵRuntimeError as RuntimeError,
2222
} from '@angular/core';
2323
import {Observable, of} from 'rxjs';
24-
import {tap} from 'rxjs/operators';
24+
import {concatMap} from 'rxjs/operators';
2525

2626
import {RuntimeErrorCode} from './errors';
2727
import {HttpHeaders} from './headers';
@@ -267,21 +267,32 @@ export function transferCacheInterceptorFn(
267267
if (typeof ngServerMode !== 'undefined' && ngServerMode) {
268268
// Request not found in cache. Make the request and cache it if on the server.
269269
return event$.pipe(
270-
tap((event: HttpEvent<unknown>) => {
270+
concatMap(async (event: HttpEvent<unknown>) => {
271271
// Only cache successful HTTP responses.
272272
if (event instanceof HttpResponse) {
273+
let body = event.body;
274+
if (req.responseType === 'blob') {
275+
// Note: Blob is converted to ArrayBuffer because Uint8Array constructor
276+
// doesn't accept Blob directly, which would result in an empty array.
277+
// Type assertion is safe here: when responseType is 'blob', the body is guaranteed to be a Blob
278+
const arrayBuffer = await (event.body as Blob).arrayBuffer();
279+
body = toBase64(arrayBuffer);
280+
} else if (req.responseType === 'arraybuffer') {
281+
// For arraybuffer, convert to base64; for other types (json, text), store as-is.
282+
// Type assertion is safe here: when responseType is 'arraybuffer', the body is
283+
// guaranteed to be an ArrayBuffer
284+
body = toBase64(event.body as ArrayBufferLike);
285+
}
273286
transferState.set<TransferHttpResponse>(storeKey, {
274-
[BODY]:
275-
req.responseType === 'arraybuffer' || req.responseType === 'blob'
276-
? toBase64(event.body as ArrayBufferLike)
277-
: event.body,
287+
[BODY]: body,
278288
[HEADERS]: getFilteredHeaders(event.headers, headersToInclude),
279289
[STATUS]: event.status,
280290
[STATUS_TEXT]: event.statusText,
281291
[REQ_URL]: requestUrl,
282292
[RESPONSE_TYPE]: req.responseType,
283293
});
284294
}
295+
return event;
285296
}),
286297
);
287298
}

0 commit comments

Comments
 (0)