Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 948a8d6

Browse files
Hexix23alxhub
authored andcommitted
fix(http): distinguish repeated transfer cache params
Serialize transfer cache request parameters without comma-joining repeated values so distinct HttpClient requests cannot reuse the same cached response.
1 parent e2660c3 commit 948a8d6

2 files changed

Lines changed: 45 additions & 6 deletions

File tree

‎packages/common/http/src/transfer_cache.ts‎

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -374,17 +374,17 @@ function getFilteredHeaders(
374374
}
375375

376376
function sortAndConcatParams(params: HttpParams | URLSearchParams): string {
377-
return [...params.keys()]
378-
.sort()
379-
.map((k) => `${k}=${params.getAll(k)}`)
380-
.join('&');
377+
const searchParams = new URLSearchParams(
378+
params instanceof URLSearchParams ? params : params.toString(),
379+
);
380+
searchParams.sort();
381+
return searchParams.toString();
381382
}
382383

383384
function makeCacheKey(
384385
request: HttpRequest<any>,
385386
mappedRequestUrl: string,
386387
): StateKey<TransferHttpResponse> {
387-
// make the params encoded same as a url so it's easy to identify
388388
const {params, method, responseType} = request;
389389
const encodedParams = sortAndConcatParams(params);
390390

‎packages/common/http/test/transfer_cache_spec.ts‎

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,14 @@ import {TestBed} from '@angular/core/testing';
1919
import {useAutoTick, timeout, withBody} from '@angular/private/testing';
2020
import {BehaviorSubject, Observable, of} from 'rxjs';
2121

22-
import {HttpClient, HttpHeaders, HttpRequest, HttpResponse, provideHttpClient} from '../public_api';
22+
import {
23+
HttpClient,
24+
HttpHeaders,
25+
HttpParams,
26+
HttpRequest,
27+
HttpResponse,
28+
provideHttpClient,
29+
} from '../public_api';
2330
import {
2431
BODY,
2532
CACHE_OPTIONS,
@@ -458,6 +465,38 @@ describe('TransferCache', () => {
458465
);
459466
});
460467

468+
it('should differentiate repeated parameters from scalar comma parameters', () => {
469+
let scalarResponse!: string;
470+
TestBed.inject(HttpClient)
471+
.get('/test-params', {params: new HttpParams().set('role', 'user,admin')})
472+
.subscribe((response) => (scalarResponse = response as string));
473+
TestBed.inject(HttpTestingController)
474+
.expectOne('/test-params?role=user,admin')
475+
.flush('scalar');
476+
477+
let repeatedResponse!: string;
478+
TestBed.inject(HttpClient)
479+
.get('/test-params', {
480+
params: new HttpParams().append('role', 'user').append('role', 'admin'),
481+
})
482+
.subscribe((response) => (repeatedResponse = response as string));
483+
TestBed.inject(HttpTestingController)
484+
.expectOne('/test-params?role=user&role=admin')
485+
.flush('repeated');
486+
487+
let repeatedCachedResponse!: string;
488+
TestBed.inject(HttpClient)
489+
.get('/test-params', {
490+
params: new HttpParams().append('role', 'user').append('role', 'admin'),
491+
})
492+
.subscribe((response) => (repeatedCachedResponse = response as string));
493+
TestBed.inject(HttpTestingController).expectNone('/test-params?role=user&role=admin');
494+
495+
expect(scalarResponse).toBe('scalar');
496+
expect(repeatedResponse).toBe('repeated');
497+
expect(repeatedCachedResponse).toBe('repeated');
498+
});
499+
461500
it('should skip cache when specified', () => {
462501
makeRequestAndExpectOne('/test-1?foo=1', 'foo', {transferCache: false});
463502
// The previous request wasn't cached so this one can't use the cache

0 commit comments

Comments
 (0)