From 1d15d21a221337d676f3af7d5d99db03bf600b71 Mon Sep 17 00:00:00 2001 From: SkyZeroZx <73321943+SkyZeroZx@users.noreply.github.com> Date: Tue, 14 Jul 2026 23:59:39 -0500 Subject: [PATCH 1/4] fix(http): run root interceptors in the terminal request chain Represent withRequestsMadeViaParent() with an internal delegating backend so the interceptor handler can distinguish delegated clients from independent child configurations. Delegated clients leave inherited root interceptors to the parent chain. This prevents duplicate execution and lets HttpTransferCache evaluate authentication and cache filters after parent request interceptors, while independent child clients continue to inherit framework root interceptors. Add coverage for independent root inheritance, request and response ordering, authenticated requests, cache filters, and public cache hits. Fixes #69777 --- packages/common/http/src/backend.ts | 21 ++- packages/common/http/src/provider.ts | 4 +- packages/common/http/test/provider_spec.ts | 89 ++++++++++++- .../common/http/test/transfer_cache_spec.ts | 122 ++++++++++++++++++ 4 files changed, 229 insertions(+), 7 deletions(-) diff --git a/packages/common/http/src/backend.ts b/packages/common/http/src/backend.ts index 7a055d3dbb52..5351cc95bd17 100644 --- a/packages/common/http/src/backend.ts +++ b/packages/common/http/src/backend.ts @@ -47,6 +47,17 @@ export abstract class HttpBackend implements HttpHandler { abstract handle(req: HttpRequest): Observable>; } +/** + * An `HttpBackend` that delegates requests to the parent injector's `HttpHandler`. + */ +export class HttpParentBackend implements HttpBackend { + constructor(private parent: HttpHandler) {} + + handle(req: HttpRequest): Observable> { + return this.parent.handle(req); + } +} + let fetchBackendWarningDisplayed = false; /** Internal function to reset the flag in tests */ @@ -99,11 +110,13 @@ export class HttpInterceptorHandler implements HttpHandler { handle(initialRequest: HttpRequest): Observable> { if (this.chain === null) { + const rootInterceptorFns = this.injector.get( + HTTP_ROOT_INTERCEPTOR_FNS, + [], + this.backend instanceof HttpParentBackend ? {self: true} : undefined, + ); const dedupedInterceptorFns = Array.from( - new Set([ - ...this.injector.get(HTTP_INTERCEPTOR_FNS), - ...this.injector.get(HTTP_ROOT_INTERCEPTOR_FNS, []), - ]), + new Set([...this.injector.get(HTTP_INTERCEPTOR_FNS), ...rootInterceptorFns]), ); // Note: interceptors are wrapped right-to-left so that final execution order is diff --git a/packages/common/http/src/provider.ts b/packages/common/http/src/provider.ts index cb110e5ed1a7..cbd3275cfaf1 100644 --- a/packages/common/http/src/provider.ts +++ b/packages/common/http/src/provider.ts @@ -14,7 +14,7 @@ import { Provider, } from '@angular/core'; -import {HttpBackend, HttpHandler, HttpInterceptorHandler} from './backend'; +import {HttpBackend, HttpHandler, HttpInterceptorHandler, HttpParentBackend} from './backend'; import {HttpClient} from './client'; import {FetchBackend} from './fetch'; import {HTTP_INTERCEPTOR_FNS, HttpInterceptorFn, legacyInterceptorFnFactory} from './interceptor'; @@ -282,7 +282,7 @@ export function withRequestsMadeViaParent(): HttpFeature { req.flush(''); }); + it('should include root interceptors in independent child contexts', () => { + TestBed.configureTestingModule({ + providers: [ + provideHttpClient(...commonHttpFeatures), + { + provide: HTTP_ROOT_INTERCEPTOR_FNS, + useValue: makeLiteralTagInterceptorFn('root'), + multi: true, + }, + provideHttpClientTesting(), + ], + }); + + const child = createEnvironmentInjector( + [ + provideHttpClient(withInterceptors([makeLiteralTagInterceptorFn('child')])), + { + provide: HttpBackend, + useFactory: () => inject(HttpBackend, {skipSelf: true}), + }, + ], + TestBed.inject(EnvironmentInjector), + ); + + child.get(HttpClient).get('/test', {responseType: 'text'}).subscribe(); + const req = TestBed.inject(HttpTestingController).expectOne('/test'); + expect(req.request.headers.get('X-Tag')).toEqual('child,root'); + req.flush(''); + }); + + it('should run root interceptors once in the parent request and response chain', () => { + const order: string[] = []; + + TestBed.configureTestingModule({ + providers: [ + provideHttpClient( + ...commonHttpFeatures, + withInterceptors([makeOrderedTagInterceptorFn('parent', order)]), + ), + { + provide: HTTP_ROOT_INTERCEPTOR_FNS, + useValue: makeOrderedTagInterceptorFn('root', order), + multi: true, + }, + provideHttpClientTesting(), + ], + }); + + const child = createEnvironmentInjector( + [ + provideHttpClient( + withRequestsMadeViaParent(), + withInterceptors([makeOrderedTagInterceptorFn('child', order)]), + ), + ], + TestBed.inject(EnvironmentInjector), + ); + + child.get(HttpClient).get('/test', {responseType: 'text'}).subscribe(); + const req = TestBed.inject(HttpTestingController).expectOne('/test'); + expect(req.request.headers.get('X-Tag')).toEqual('child,parent,root'); + expect(order).toEqual(['child:request', 'parent:request', 'root:request']); + req.flush(''); + expect(order).toEqual([ + 'child:request', + 'parent:request', + 'root:request', + 'root:response', + 'parent:response', + 'child:response', + ]); + }); + it('should be able to connect to a legacy-provided HttpClient context', () => { TestBed.configureTestingModule({ imports: [HttpClientTestingModule], @@ -653,6 +727,19 @@ function makeLiteralTagInterceptorFn(tag: string): HttpInterceptorFn { return (req, next) => next(addTagToRequest(req, tag)); } +function makeOrderedTagInterceptorFn(tag: string, order: string[]): HttpInterceptorFn { + return (req, next) => { + order.push(`${tag}:request`); + return next(addTagToRequest(req, tag)).pipe( + tap((event) => { + if (event instanceof HttpResponse) { + order.push(`${tag}:response`); + } + }), + ); + }; +} + function makeTokenTagInterceptorFn(tag: InjectionToken): HttpInterceptorFn { return (req, next) => next(addTagToRequest(req, inject(tag))); } diff --git a/packages/common/http/test/transfer_cache_spec.ts b/packages/common/http/test/transfer_cache_spec.ts index 652665965dd6..de4d316bf89d 100644 --- a/packages/common/http/test/transfer_cache_spec.ts +++ b/packages/common/http/test/transfer_cache_spec.ts @@ -10,6 +10,8 @@ import {DOCUMENT} from '../../index'; import { ApplicationRef, Component, + createEnvironmentInjector, + EnvironmentInjector, Injectable, PLATFORM_ID, TransferState, @@ -26,6 +28,8 @@ import { HttpRequest, HttpResponse, provideHttpClient, + withInterceptors, + withRequestsMadeViaParent, } from '../public_api'; import { BODY, @@ -295,6 +299,124 @@ describe('TransferCache', () => { }); }); + describe('withRequestsMadeViaParent()', () => { + let childInjector: EnvironmentInjector; + + beforeEach(() => { + globalThis['ngServerMode'] = true; + + TestBed.configureTestingModule({ + providers: [ + TransferState, + withHttpTransferCache({ + filter: (request) => !request.headers.has('X-API-Key'), + }), + provideHttpClient( + withInterceptors([ + (request, next) => { + if (request.url === '/private') { + request = request.clone({ + setHeaders: {Authorization: 'Bearer server-token'}, + }); + } else if (request.url === '/secret') { + request = request.clone({setHeaders: {'X-API-Key': 'secret-a'}}); + } else if (request.url === '/public-alias') { + request = request.clone({url: '/public'}); + } + + return next(request); + }, + ]), + ), + provideHttpClientTesting(), + ], + }); + + childInjector = createEnvironmentInjector( + [ + provideHttpClient( + withInterceptors([ + (request, next) => + next(request.clone({setHeaders: {'X-Trace-Id': 'feature-request'}})), + ]), + withRequestsMadeViaParent(), + ), + ], + TestBed.inject(EnvironmentInjector), + ); + }); + + afterEach(() => { + childInjector.destroy(); + TestBed.inject(HttpTestingController).verify(); + globalThis['ngServerMode'] = undefined; + }); + + it('should evaluate cache eligibility and keys after parent interceptors', () => { + const httpClient = childInjector.get(HttpClient); + const httpTestingController = TestBed.inject(HttpTestingController); + const transferState = TestBed.inject(TransferState); + + let privateResponse: unknown; + httpClient.get('/private').subscribe((response) => (privateResponse = response)); + const privateRequest = httpTestingController.expectOne('/private'); + expect(privateRequest.request.headers.get('Authorization')).toBe('Bearer server-token'); + expect(privateRequest.request.headers.get('X-Trace-Id')).toBe('feature-request'); + privateRequest.flush({internalSecret: 'server-only'}); + + expect(privateResponse).toEqual({internalSecret: 'server-only'}); + expect(JSON.parse(transferState.toJson())).toEqual({}); + + let publicResponse: unknown; + httpClient.get('/public-alias').subscribe((response) => (publicResponse = response)); + httpTestingController.expectOne('/public').flush({message: 'public'}); + + publicResponse = undefined; + httpClient.get('/public-alias').subscribe((response) => (publicResponse = response)); + httpTestingController.expectNone('/public'); + expect(publicResponse).toEqual({message: 'public'}); + }); + + it('should evaluate cache filters after parent interceptors', () => { + const httpClient = childInjector.get(HttpClient); + const httpTestingController = TestBed.inject(HttpTestingController); + const transferState = TestBed.inject(TransferState); + + let response: unknown; + httpClient.get('/secret').subscribe((value) => (response = value)); + const request = httpTestingController.expectOne('/secret'); + expect(request.request.headers.get('X-API-KEY')).toBe('secret-a'); + request.flush({internalSecret: 'secret-only'}); + + expect(response).toEqual({internalSecret: 'secret-only'}); + expect(JSON.parse(transferState.toJson())).toEqual({}); + }); + + it('should evaluate cache eligibility through multiple parent clients', () => { + const grandchildInjector = createEnvironmentInjector( + [provideHttpClient(withRequestsMadeViaParent())], + childInjector, + ); + + try { + const httpClient = grandchildInjector.get(HttpClient); + const httpTestingController = TestBed.inject(HttpTestingController); + const transferState = TestBed.inject(TransferState); + + let privateResponse: unknown; + httpClient.get('/private').subscribe((response) => (privateResponse = response)); + const privateRequest = httpTestingController.expectOne('/private'); + expect(privateRequest.request.headers.get('Authorization')).toBe('Bearer server-token'); + privateRequest.flush({internalSecret: 'server-only'}); + + expect(privateResponse).toEqual({internalSecret: 'server-only'}); + expect(JSON.parse(transferState.toJson())).toEqual({}); + } finally { + grandchildInjector.destroy(); + } + }); + }); + describe('withHttpTransferCache', () => { let isStable: BehaviorSubject; From 2e1ce8d6ba984322802798acc9b0afac3d316012 Mon Sep 17 00:00:00 2001 From: SkyZeroZx <73321943+SkyZeroZx@users.noreply.github.com> Date: Wed, 15 Jul 2026 18:22:24 -0500 Subject: [PATCH 2/4] fixup! fix(http): run root interceptors in the terminal request chain --- packages/common/http/test/provider_spec.ts | 31 ++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/packages/common/http/test/provider_spec.ts b/packages/common/http/test/provider_spec.ts index 1d775e8208fb..62ddd6006fa0 100644 --- a/packages/common/http/test/provider_spec.ts +++ b/packages/common/http/test/provider_spec.ts @@ -53,6 +53,7 @@ import { withXsrfConfiguration, } from '../src/provider'; import {resetFetchBackendWarningFlag} from '../src/backend'; +import {MockXhrFactory} from './xhr_mock'; describe('without provideHttpClientTesting', () => { it('should contribute to stability', async () => { @@ -537,6 +538,36 @@ describe('provideHttpClient', () => { }); }); } + + it('should inherit root interceptors when withXhr overrides parent delegation', () => { + TestBed.configureTestingModule({ + providers: [ + provideHttpClient(), + { + provide: HTTP_ROOT_INTERCEPTOR_FNS, + useValue: makeLiteralTagInterceptorFn('root'), + multi: true, + }, + ], + }); + + const child = createEnvironmentInjector( + [ + provideHttpClient(withRequestsMadeViaParent(), withXhr()), + {provide: XhrFactory, useClass: MockXhrFactory}, + ], + TestBed.inject(EnvironmentInjector), + ); + + try { + child.get(HttpClient).get('/test').subscribe(); + const factory = child.get(XhrFactory) as MockXhrFactory; + expect(factory.mock.mockHeaders['X-Tag']).toBe('root'); + factory.mock.mockFlush(200, 'OK', '{}'); + } finally { + child.destroy(); + } + }); }); describe('compatibility with Http NgModules', () => { From b1f5851d602b3e3514b9703a4e672fed33c65b07 Mon Sep 17 00:00:00 2001 From: SkyZeroZx <73321943+SkyZeroZx@users.noreply.github.com> Date: Mon, 20 Jul 2026 11:55:48 -0500 Subject: [PATCH 3/4] fixup! fix(http): run root interceptors in the terminal request chain --- packages/common/http/src/backend.ts | 18 ++-- packages/common/http/src/provider.ts | 30 +++++-- packages/common/http/test/provider_spec.ts | 97 +++++++++++++++------- 3 files changed, 100 insertions(+), 45 deletions(-) diff --git a/packages/common/http/src/backend.ts b/packages/common/http/src/backend.ts index 5351cc95bd17..78bed97fcde0 100644 --- a/packages/common/http/src/backend.ts +++ b/packages/common/http/src/backend.ts @@ -12,6 +12,7 @@ import { EnvironmentInjector, inject, Injectable, + InjectionToken, untracked, ɵConsole as Console, ɵformatRuntimeError as formatRuntimeError, @@ -47,16 +48,10 @@ export abstract class HttpBackend implements HttpHandler { abstract handle(req: HttpRequest): Observable>; } -/** - * An `HttpBackend` that delegates requests to the parent injector's `HttpHandler`. - */ -export class HttpParentBackend implements HttpBackend { - constructor(private parent: HttpHandler) {} - - handle(req: HttpRequest): Observable> { - return this.parent.handle(req); - } -} +/** Indicates that the current `HttpClient` delegates requests to its parent. */ +export const ɵHTTP_CLIENT_IS_DELEGATING = new InjectionToken( + typeof ngDevMode !== 'undefined' && ngDevMode ? 'ɵHTTP_CLIENT_IS_DELEGATING ' : '', +); let fetchBackendWarningDisplayed = false; @@ -110,10 +105,11 @@ export class HttpInterceptorHandler implements HttpHandler { handle(initialRequest: HttpRequest): Observable> { if (this.chain === null) { + const isDelegating = this.injector.get(ɵHTTP_CLIENT_IS_DELEGATING, false, {self: true}); const rootInterceptorFns = this.injector.get( HTTP_ROOT_INTERCEPTOR_FNS, [], - this.backend instanceof HttpParentBackend ? {self: true} : undefined, + isDelegating ? {self: true} : undefined, ); const dedupedInterceptorFns = Array.from( new Set([...this.injector.get(HTTP_INTERCEPTOR_FNS), ...rootInterceptorFns]), diff --git a/packages/common/http/src/provider.ts b/packages/common/http/src/provider.ts index cbd3275cfaf1..12d11507fd81 100644 --- a/packages/common/http/src/provider.ts +++ b/packages/common/http/src/provider.ts @@ -14,7 +14,12 @@ import { Provider, } from '@angular/core'; -import {HttpBackend, HttpHandler, HttpInterceptorHandler, HttpParentBackend} from './backend'; +import { + ɵHTTP_CLIENT_IS_DELEGATING, + HttpBackend, + HttpHandler, + HttpInterceptorHandler, +} from './backend'; import {HttpClient} from './client'; import {FetchBackend} from './fetch'; import {HTTP_INTERCEPTOR_FNS, HttpInterceptorFn, legacyInterceptorFnFactory} from './interceptor'; @@ -106,9 +111,15 @@ export function provideHttpClient( featureKinds.has(HttpFeatureKind.CustomXsrfConfiguration) ) { throw new Error( - ngDevMode - ? `Configuration error: found both withXsrfConfiguration() and withNoXsrfProtection() in the same call to provideHttpClient(), which is a contradiction.` - : '', + `Configuration error: found both withXsrfConfiguration() and withNoXsrfProtection() in the same call to provideHttpClient(), which is a contradiction.`, + ); + } + + const hasBackendOverride = + featureKinds.has(HttpFeatureKind.Fetch) || featureKinds.has(HttpFeatureKind.Xhr); + if (featureKinds.has(HttpFeatureKind.RequestsMadeViaParent) && hasBackendOverride) { + throw new Error( + `Configuration error: withRequestsMadeViaParent() cannot be combined with withFetch() or withXhr() in the same call to provideHttpClient().`, ); } } @@ -267,6 +278,8 @@ export function withJsonpSupport(): HttpFeature { * "bubble up" until either reaching the root level or an `HttpClient` which was not configured with * this option. * + * This feature is incompatible with the `withFetch` and `withXhr` features. + * * @see [HTTP client setup](guide/http/setup#withrequestsmadeviaparent) * @see {@link provideHttpClient} * @publicApi 19.0 @@ -282,9 +295,16 @@ export function withRequestsMadeViaParent(): HttpFeature + inject(HttpBackend) === inject(HttpHandler, {skipSelf: true, optional: true}), + }, ]); } diff --git a/packages/common/http/test/provider_spec.ts b/packages/common/http/test/provider_spec.ts index 62ddd6006fa0..97455a397245 100644 --- a/packages/common/http/test/provider_spec.ts +++ b/packages/common/http/test/provider_spec.ts @@ -44,6 +44,7 @@ import { HttpFeature, HttpFeatureKind, provideHttpClient, + withFetch, withInterceptors, withInterceptorsFromDi, withJsonpSupport, @@ -53,7 +54,6 @@ import { withXsrfConfiguration, } from '../src/provider'; import {resetFetchBackendWarningFlag} from '../src/backend'; -import {MockXhrFactory} from './xhr_mock'; describe('without provideHttpClientTesting', () => { it('should contribute to stability', async () => { @@ -513,33 +513,68 @@ describe('provideHttpClient', () => { 'child:response', ]); }); + }); + } - it('should be able to connect to a legacy-provided HttpClient context', () => { - TestBed.configureTestingModule({ - imports: [HttpClientTestingModule], - providers: [provideLegacyInterceptor('parent')], - }); + it('should be able to connect to a legacy-provided HttpClient context', () => { + TestBed.configureTestingModule({ + imports: [HttpClientTestingModule], + providers: [provideLegacyInterceptor('parent')], + }); - const child = createEnvironmentInjector( - [ - provideHttpClient( - ...commonHttpFeatures, - withRequestsMadeViaParent(), - withInterceptors([makeLiteralTagInterceptorFn('child')]), - ), - ], - TestBed.inject(EnvironmentInjector), - ); + const child = createEnvironmentInjector( + [ + provideHttpClient( + withRequestsMadeViaParent(), + withInterceptors([makeLiteralTagInterceptorFn('child')]), + ), + ], + TestBed.inject(EnvironmentInjector), + ); - child.get(HttpClient).get('/test', {responseType: 'text'}).subscribe(); - const req = TestBed.inject(HttpTestingController).expectOne('/test'); - expect(req.request.headers.get('X-Tag')).toEqual('child,parent'); - req.flush(''); - }); + child.get(HttpClient).get('/test', {responseType: 'text'}).subscribe(); + const req = TestBed.inject(HttpTestingController).expectOne('/test'); + expect(req.request.headers.get('X-Tag')).toEqual('child,parent'); + req.flush(''); + }); + + it('should not inherit the delegation marker in independent child contexts', () => { + TestBed.configureTestingModule({ + providers: [ + provideHttpClient(), + { + provide: HTTP_ROOT_INTERCEPTOR_FNS, + useValue: makeLiteralTagInterceptorFn('root'), + multi: true, + }, + provideHttpClientTesting(), + ], }); - } - it('should inherit root interceptors when withXhr overrides parent delegation', () => { + const delegatingParent = createEnvironmentInjector( + [provideHttpClient(withRequestsMadeViaParent())], + TestBed.inject(EnvironmentInjector), + ); + const independentChild = createEnvironmentInjector( + [ + provideHttpClient(withInterceptors([makeLiteralTagInterceptorFn('child')])), + {provide: HttpBackend, useValue: TestBed.inject(HttpBackend)}, + ], + delegatingParent, + ); + + try { + independentChild.get(HttpClient).get('/test', {responseType: 'text'}).subscribe(); + const req = TestBed.inject(HttpTestingController).expectOne('/test'); + expect(req.request.headers.get('X-Tag')).toEqual('child,root'); + req.flush(''); + } finally { + independentChild.destroy(); + delegatingParent.destroy(); + } + }); + + it('should inherit root interceptors when a custom provider overrides delegation', () => { TestBed.configureTestingModule({ providers: [ provideHttpClient(), @@ -548,22 +583,26 @@ describe('provideHttpClient', () => { useValue: makeLiteralTagInterceptorFn('root'), multi: true, }, + provideHttpClientTesting(), ], }); const child = createEnvironmentInjector( [ - provideHttpClient(withRequestsMadeViaParent(), withXhr()), - {provide: XhrFactory, useClass: MockXhrFactory}, + provideHttpClient( + withRequestsMadeViaParent(), + withInterceptors([makeLiteralTagInterceptorFn('child')]), + ), + {provide: HttpBackend, useValue: TestBed.inject(HttpBackend)}, ], TestBed.inject(EnvironmentInjector), ); try { - child.get(HttpClient).get('/test').subscribe(); - const factory = child.get(XhrFactory) as MockXhrFactory; - expect(factory.mock.mockHeaders['X-Tag']).toBe('root'); - factory.mock.mockFlush(200, 'OK', '{}'); + child.get(HttpClient).get('/test', {responseType: 'text'}).subscribe(); + const req = TestBed.inject(HttpTestingController).expectOne('/test'); + expect(req.request.headers.get('X-Tag')).toEqual('child,root'); + req.flush(''); } finally { child.destroy(); } From 51616ee4946c0f0c7f77945f78ab9820f665c93b Mon Sep 17 00:00:00 2001 From: SkyZeroZx <73321943+SkyZeroZx@users.noreply.github.com> Date: Wed, 22 Jul 2026 09:31:01 -0500 Subject: [PATCH 4/4] fixup! fix(http): run root interceptors in the terminal request chain --- packages/common/http/src/backend.ts | 9 ++------- packages/common/http/src/provider.ts | 14 +------------- packages/common/http/test/provider_spec.ts | 2 +- 3 files changed, 4 insertions(+), 21 deletions(-) diff --git a/packages/common/http/src/backend.ts b/packages/common/http/src/backend.ts index 78bed97fcde0..8c41faca5009 100644 --- a/packages/common/http/src/backend.ts +++ b/packages/common/http/src/backend.ts @@ -12,7 +12,6 @@ import { EnvironmentInjector, inject, Injectable, - InjectionToken, untracked, ɵConsole as Console, ɵformatRuntimeError as formatRuntimeError, @@ -48,11 +47,6 @@ export abstract class HttpBackend implements HttpHandler { abstract handle(req: HttpRequest): Observable>; } -/** Indicates that the current `HttpClient` delegates requests to its parent. */ -export const ɵHTTP_CLIENT_IS_DELEGATING = new InjectionToken( - typeof ngDevMode !== 'undefined' && ngDevMode ? 'ɵHTTP_CLIENT_IS_DELEGATING ' : '', -); - let fetchBackendWarningDisplayed = false; /** Internal function to reset the flag in tests */ @@ -105,7 +99,8 @@ export class HttpInterceptorHandler implements HttpHandler { handle(initialRequest: HttpRequest): Observable> { if (this.chain === null) { - const isDelegating = this.injector.get(ɵHTTP_CLIENT_IS_DELEGATING, false, {self: true}); + const parentHandler = this.injector.get(HttpHandler, null, {skipSelf: true}); + const isDelegating = parentHandler !== null && this.backend === parentHandler; const rootInterceptorFns = this.injector.get( HTTP_ROOT_INTERCEPTOR_FNS, [], diff --git a/packages/common/http/src/provider.ts b/packages/common/http/src/provider.ts index 12d11507fd81..0c3e8633ebd0 100644 --- a/packages/common/http/src/provider.ts +++ b/packages/common/http/src/provider.ts @@ -14,12 +14,7 @@ import { Provider, } from '@angular/core'; -import { - ɵHTTP_CLIENT_IS_DELEGATING, - HttpBackend, - HttpHandler, - HttpInterceptorHandler, -} from './backend'; +import {HttpBackend, HttpHandler, HttpInterceptorHandler} from './backend'; import {HttpClient} from './client'; import {FetchBackend} from './fetch'; import {HTTP_INTERCEPTOR_FNS, HttpInterceptorFn, legacyInterceptorFnFactory} from './interceptor'; @@ -298,13 +293,6 @@ export function withRequestsMadeViaParent(): HttpFeature - inject(HttpBackend) === inject(HttpHandler, {skipSelf: true, optional: true}), - }, ]); } diff --git a/packages/common/http/test/provider_spec.ts b/packages/common/http/test/provider_spec.ts index 97455a397245..3d4d2837b0b7 100644 --- a/packages/common/http/test/provider_spec.ts +++ b/packages/common/http/test/provider_spec.ts @@ -538,7 +538,7 @@ describe('provideHttpClient', () => { req.flush(''); }); - it('should not inherit the delegation marker in independent child contexts', () => { + it('should inherit root interceptors in independent child contexts', () => { TestBed.configureTestingModule({ providers: [ provideHttpClient(),