From 9745f55a657edee13ba473aec91c9bb22304a54f Mon Sep 17 00:00:00 2001 From: Adam Plumer Date: Tue, 19 Mar 2019 19:41:12 -0500 Subject: [PATCH] feat: remove @angular/http dependency from @angular/platform-server (#29408) PR Close #29408 --- packages/platform-server/BUILD.bazel | 1 - packages/platform-server/package.json | 1 - packages/platform-server/src/http.ts | 58 +------- packages/platform-server/src/server.ts | 3 +- packages/platform-server/test/BUILD.bazel | 2 - .../platform-server/test/integration_spec.ts | 132 ------------------ 6 files changed, 5 insertions(+), 192 deletions(-) diff --git a/packages/platform-server/BUILD.bazel b/packages/platform-server/BUILD.bazel index a2b26739d6b..dceccb07e07 100644 --- a/packages/platform-server/BUILD.bazel +++ b/packages/platform-server/BUILD.bazel @@ -16,7 +16,6 @@ ng_module( "//packages/common/http", "//packages/compiler", "//packages/core", - "//packages/http", "//packages/platform-browser", "//packages/platform-browser-dynamic", "//packages/platform-browser/animations", diff --git a/packages/platform-server/package.json b/packages/platform-server/package.json index ef121fadabe..d3b46949d4f 100644 --- a/packages/platform-server/package.json +++ b/packages/platform-server/package.json @@ -17,7 +17,6 @@ "@angular/common": "0.0.0-PLACEHOLDER", "@angular/compiler": "0.0.0-PLACEHOLDER", "@angular/core": "0.0.0-PLACEHOLDER", - "@angular/http": "0.0.0-PLACEHOLDER", "@angular/platform-browser": "0.0.0-PLACEHOLDER", "@angular/platform-browser-dynamic": "0.0.0-PLACEHOLDER" }, diff --git a/packages/platform-server/src/http.ts b/packages/platform-server/src/http.ts index 58453a80ee4..37fec07dd8f 100644 --- a/packages/platform-server/src/http.ts +++ b/packages/platform-server/src/http.ts @@ -6,33 +6,20 @@ * found in the LICENSE file at https://angular.io/license */ + const xhr2: any = require('xhr2'); -import {Injectable, Injector, Optional, Provider, InjectFlags} from '@angular/core'; -import {BrowserXhr, Connection, ConnectionBackend, Http, ReadyState, Request, RequestOptions, Response, XHRBackend, XSRFStrategy} from '@angular/http'; +import {Injectable, Injector, Provider} from '@angular/core'; -import {HttpEvent, HttpRequest, HttpHandler, HttpInterceptor, HTTP_INTERCEPTORS, HttpBackend, XhrFactory, ɵHttpInterceptingHandler as HttpInterceptingHandler} from '@angular/common/http'; +import {HttpEvent, HttpRequest, HttpHandler, HttpBackend, XhrFactory, ɵHttpInterceptingHandler as HttpInterceptingHandler} from '@angular/common/http'; import {Observable, Observer, Subscription} from 'rxjs'; -const isAbsoluteUrl = /^[a-zA-Z\-\+.]+:\/\//; - -function validateRequestUrl(url: string): void { - if (!isAbsoluteUrl.test(url)) { - throw new Error(`URLs requested via Http on the server must be absolute. URL: ${url}`); - } -} - @Injectable() -export class ServerXhr implements BrowserXhr { +export class ServerXhr implements XhrFactory { build(): XMLHttpRequest { return new xhr2.XMLHttpRequest(); } } -@Injectable() -export class ServerXsrfStrategy implements XSRFStrategy { - configureRequest(req: Request): void {} -} - export abstract class ZoneMacroTaskWrapper { wrap(request: S): Observable { return new Observable((observer: Observer) => { @@ -111,36 +98,6 @@ export abstract class ZoneMacroTaskWrapper { protected abstract delegate(request: S): Observable; } -export class ZoneMacroTaskConnection extends ZoneMacroTaskWrapper implements - Connection { - response: Observable; - // TODO(issue/24571): remove '!'. - lastConnection !: Connection; - - constructor(public request: Request, private backend: XHRBackend) { - super(); - validateRequestUrl(request.url); - this.response = this.wrap(request); - } - - delegate(request: Request): Observable { - this.lastConnection = this.backend.createConnection(request); - return this.lastConnection.response as Observable; - } - - get readyState(): ReadyState { - return !!this.lastConnection ? this.lastConnection.readyState : ReadyState.Unsent; - } -} - -export class ZoneMacroTaskBackend implements ConnectionBackend { - constructor(private backend: XHRBackend) {} - - createConnection(request: any): ZoneMacroTaskConnection { - return new ZoneMacroTaskConnection(request, this.backend); - } -} - export class ZoneClientBackend extends ZoneMacroTaskWrapper, HttpEvent> implements HttpBackend { constructor(private backend: HttpBackend) { super(); } @@ -152,19 +109,12 @@ export class ZoneClientBackend extends } } -export function httpFactory(xhrBackend: XHRBackend, options: RequestOptions) { - const macroBackend = new ZoneMacroTaskBackend(xhrBackend); - return new Http(macroBackend, options); -} - export function zoneWrappedInterceptingHandler(backend: HttpBackend, injector: Injector) { const realBackend: HttpBackend = new HttpInterceptingHandler(backend, injector); return new ZoneClientBackend(realBackend); } export const SERVER_HTTP_PROVIDERS: Provider[] = [ - {provide: Http, useFactory: httpFactory, deps: [XHRBackend, RequestOptions]}, - {provide: BrowserXhr, useClass: ServerXhr}, {provide: XSRFStrategy, useClass: ServerXsrfStrategy}, {provide: XhrFactory, useClass: ServerXhr}, { provide: HttpHandler, useFactory: zoneWrappedInterceptingHandler, diff --git a/packages/platform-server/src/server.ts b/packages/platform-server/src/server.ts index a8a9cbed836..0e65b23c4c9 100644 --- a/packages/platform-server/src/server.ts +++ b/packages/platform-server/src/server.ts @@ -10,7 +10,6 @@ import {ɵAnimationEngine} from '@angular/animations/browser'; import {DOCUMENT, PlatformLocation, ViewportScroller, ɵNullViewportScroller as NullViewportScroller, ɵPLATFORM_SERVER_ID as PLATFORM_SERVER_ID} from '@angular/common'; import {HttpClientModule} from '@angular/common/http'; import {Injectable, InjectionToken, Injector, NgModule, NgZone, Optional, PLATFORM_ID, PLATFORM_INITIALIZER, PlatformRef, Provider, RendererFactory2, RootRenderer, StaticProvider, Testability, createPlatformFactory, platformCore, ɵALLOW_MULTIPLE_PLATFORMS as ALLOW_MULTIPLE_PLATFORMS} from '@angular/core'; -import {HttpModule} from '@angular/http'; import {BrowserModule, EVENT_MANAGER_PLUGINS, ɵSharedStylesHost as SharedStylesHost, ɵgetDOM as getDOM} from '@angular/platform-browser'; import {ɵplatformCoreDynamic as platformCoreDynamic} from '@angular/platform-browser-dynamic'; import {NoopAnimationsModule, ɵAnimationRendererFactory} from '@angular/platform-browser/animations'; @@ -69,7 +68,7 @@ export const SERVER_RENDER_PROVIDERS: Provider[] = [ */ @NgModule({ exports: [BrowserModule], - imports: [HttpModule, HttpClientModule, NoopAnimationsModule], + imports: [HttpClientModule, NoopAnimationsModule], providers: [ SERVER_RENDER_PROVIDERS, SERVER_HTTP_PROVIDERS, diff --git a/packages/platform-server/test/BUILD.bazel b/packages/platform-server/test/BUILD.bazel index c71f1377cdc..187430ed560 100644 --- a/packages/platform-server/test/BUILD.bazel +++ b/packages/platform-server/test/BUILD.bazel @@ -13,8 +13,6 @@ ts_library( "//packages/compiler", "//packages/core", "//packages/core/testing", - "//packages/http", - "//packages/http/testing", "//packages/platform-browser", "//packages/platform-server", "//packages/private/testing", diff --git a/packages/platform-server/test/integration_spec.ts b/packages/platform-server/test/integration_spec.ts index e1831fcaa52..59f4b4fb0fa 100644 --- a/packages/platform-server/test/integration_spec.ts +++ b/packages/platform-server/test/integration_spec.ts @@ -12,8 +12,6 @@ import {HTTP_INTERCEPTORS, HttpClient, HttpClientModule, HttpEvent, HttpHandler, import {HttpClientTestingModule, HttpTestingController} from '@angular/common/http/testing'; import {ApplicationRef, CompilerFactory, Component, HostListener, Inject, Injectable, Input, NgModule, NgZone, PLATFORM_ID, PlatformRef, ViewEncapsulation, destroyPlatform, getPlatform} from '@angular/core'; import {async, inject} from '@angular/core/testing'; -import {Http, HttpModule, Response, ResponseOptions, XHRBackend} from '@angular/http'; -import {MockBackend, MockConnection} from '@angular/http/testing'; import {BrowserModule, Title, TransferState, makeStateKey} from '@angular/platform-browser'; import {getDOM} from '@angular/platform-browser/src/dom/dom_adapter'; import {BEFORE_APP_SERIALIZED, INITIAL_CONFIG, PlatformState, ServerModule, ServerTransferStateModule, platformDynamicServer, renderModule, renderModuleFactory} from '@angular/platform-server'; @@ -29,10 +27,6 @@ class MyServerApp { bootstrap: [MyServerApp], declarations: [MyServerApp], imports: [ServerModule], - providers: [ - MockBackend, - {provide: XHRBackend, useExisting: MockBackend}, - ] }) class ExampleModule { } @@ -232,30 +226,6 @@ class MyStylesApp { class ExampleStylesModule { } -@NgModule({ - bootstrap: [MyServerApp], - declarations: [MyServerApp], - imports: [HttpModule, ServerModule], - providers: [ - MockBackend, - {provide: XHRBackend, useExisting: MockBackend}, - ] -}) -export class HttpBeforeExampleModule { -} - -@NgModule({ - bootstrap: [MyServerApp], - declarations: [MyServerApp], - imports: [ServerModule, HttpModule], - providers: [ - MockBackend, - {provide: XHRBackend, useExisting: MockBackend}, - ] -}) -export class HttpAfterExampleModule { -} - @NgModule({ bootstrap: [MyServerApp], declarations: [MyServerApp], @@ -774,108 +744,6 @@ class HiddenModule { })); }); - describe('http', () => { - it('can inject Http', async(() => { - const platform = platformDynamicServer( - [{provide: INITIAL_CONFIG, useValue: {document: ''}}]); - platform.bootstrapModule(ExampleModule).then(ref => { - expect(ref.injector.get(Http) instanceof Http).toBeTruthy(); - }); - })); - - it('can make Http requests', async(() => { - const platform = platformDynamicServer( - [{provide: INITIAL_CONFIG, useValue: {document: ''}}]); - platform.bootstrapModule(ExampleModule).then(ref => { - const mock = ref.injector.get(MockBackend); - const http = ref.injector.get(Http); - ref.injector.get(NgZone).run(() => { - NgZone.assertInAngularZone(); - mock.connections.subscribe((mc: MockConnection) => { - NgZone.assertInAngularZone(); - expect(mc.request.url).toBe('http://localhost/testing'); - mc.mockRespond(new Response(new ResponseOptions({body: 'success!', status: 200}))); - }); - http.get('http://localhost/testing').subscribe(resp => { - NgZone.assertInAngularZone(); - expect(resp.text()).toBe('success!'); - }); - }); - }); - })); - - it('requests are macrotasks', async(() => { - const platform = platformDynamicServer( - [{provide: INITIAL_CONFIG, useValue: {document: ''}}]); - platform.bootstrapModule(ExampleModule).then(ref => { - const mock = ref.injector.get(MockBackend); - const http = ref.injector.get(Http); - expect(ref.injector.get(NgZone).hasPendingMacrotasks).toBeFalsy(); - ref.injector.get(NgZone).run(() => { - NgZone.assertInAngularZone(); - mock.connections.subscribe((mc: MockConnection) => { - expect(ref.injector.get(NgZone).hasPendingMacrotasks).toBeTruthy(); - mc.mockRespond(new Response(new ResponseOptions({body: 'success!', status: 200}))); - }); - http.get('http://localhost/testing').subscribe(resp => { - expect(resp.text()).toBe('success!'); - }); - }); - }); - })); - - it('works when HttpModule is included before ServerModule', async(() => { - const platform = platformDynamicServer( - [{provide: INITIAL_CONFIG, useValue: {document: ''}}]); - platform.bootstrapModule(HttpBeforeExampleModule).then(ref => { - const mock = ref.injector.get(MockBackend); - const http = ref.injector.get(Http); - expect(ref.injector.get(NgZone).hasPendingMacrotasks).toBeFalsy(); - ref.injector.get(NgZone).run(() => { - NgZone.assertInAngularZone(); - mock.connections.subscribe((mc: MockConnection) => { - expect(ref.injector.get(NgZone).hasPendingMacrotasks).toBeTruthy(); - mc.mockRespond(new Response(new ResponseOptions({body: 'success!', status: 200}))); - }); - http.get('http://localhost/testing').subscribe(resp => { - expect(resp.text()).toBe('success!'); - }); - }); - }); - })); - - it('works when HttpModule is included after ServerModule', async(() => { - const platform = platformDynamicServer( - [{provide: INITIAL_CONFIG, useValue: {document: ''}}]); - platform.bootstrapModule(HttpAfterExampleModule).then(ref => { - const mock = ref.injector.get(MockBackend); - const http = ref.injector.get(Http); - expect(ref.injector.get(NgZone).hasPendingMacrotasks).toBeFalsy(); - ref.injector.get(NgZone).run(() => { - NgZone.assertInAngularZone(); - mock.connections.subscribe((mc: MockConnection) => { - expect(ref.injector.get(NgZone).hasPendingMacrotasks).toBeTruthy(); - mc.mockRespond(new Response(new ResponseOptions({body: 'success!', status: 200}))); - }); - http.get('http://localhost/testing').subscribe(resp => { - expect(resp.text()).toBe('success!'); - }); - }); - }); - })); - - it('throws when given a relative URL', async(() => { - const platform = platformDynamicServer( - [{provide: INITIAL_CONFIG, useValue: {document: ''}}]); - platform.bootstrapModule(ExampleModule).then(ref => { - const http = ref.injector.get(Http); - expect(() => http.get('/testing')) - .toThrowError( - 'URLs requested via Http on the server must be absolute. URL: /testing'); - }); - })); - }); - describe('HttpClient', () => { it('can inject HttpClient', async(() => { const platform = platformDynamicServer(