Revert "fix(platform-server): correctly handle absolute relative URLs (#37341)" (#37547)

This reverts commit 420d1c35f5.

PR Close #37547
This commit is contained in:
Adam
2020-06-11 19:23:59 -05:00
committed by Misko Hevery
parent bad6e719de
commit 1502ae78b6
3 changed files with 15 additions and 65 deletions

View File

@ -10,12 +10,13 @@
const xhr2: any = require('xhr2'); const xhr2: any = require('xhr2');
import {Injectable, Injector, Provider} from '@angular/core'; import {Injectable, Injector, Provider} from '@angular/core';
import {PlatformLocation} from '@angular/common'; import {DOCUMENT} from '@angular/common';
import {HttpEvent, HttpRequest, HttpHandler, 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'; import {Observable, Observer, Subscription} from 'rxjs';
// @see https://www.w3.org/Protocols/HTTP/1.1/draft-ietf-http-v11-spec-01#URI-syntax // @see https://www.w3.org/Protocols/HTTP/1.1/draft-ietf-http-v11-spec-01#URI-syntax
const isAbsoluteUrl = /^[a-zA-Z\-\+.]+:\/\//; const isAbsoluteUrl = /^[a-zA-Z\-\+.]+:\/\//;
const FORWARD_SLASH = '/';
@Injectable() @Injectable()
export class ServerXhr implements XhrFactory { export class ServerXhr implements XhrFactory {
@ -104,18 +105,20 @@ export abstract class ZoneMacroTaskWrapper<S, R> {
export class ZoneClientBackend extends export class ZoneClientBackend extends
ZoneMacroTaskWrapper<HttpRequest<any>, HttpEvent<any>> implements HttpBackend { ZoneMacroTaskWrapper<HttpRequest<any>, HttpEvent<any>> implements HttpBackend {
constructor(private backend: HttpBackend, private platformLocation: PlatformLocation) { constructor(private backend: HttpBackend, private doc: Document) {
super(); super();
} }
handle(request: HttpRequest<any>): Observable<HttpEvent<any>> { handle(request: HttpRequest<any>): Observable<HttpEvent<any>> {
const {href, protocol, hostname} = this.platformLocation; const href = this.doc.location.href;
if (!isAbsoluteUrl.test(request.url) && href !== '/') { if (!isAbsoluteUrl.test(request.url) && href) {
const baseHref = this.platformLocation.getBaseHrefFromDOM() || href; const urlParts = Array.from(request.url);
const urlPrefix = `${protocol}//${hostname}`; if (request.url[0] === FORWARD_SLASH && href[href.length - 1] === FORWARD_SLASH) {
const baseUrl = new URL(baseHref, urlPrefix); urlParts.shift();
const url = new URL(request.url, baseUrl); } else if (request.url[0] !== FORWARD_SLASH && href[href.length - 1] !== FORWARD_SLASH) {
return this.wrap(request.clone({url: url.toString()})); urlParts.splice(0, 0, FORWARD_SLASH);
}
return this.wrap(request.clone({url: href + urlParts.join('')}));
} }
return this.wrap(request); return this.wrap(request);
} }
@ -126,15 +129,15 @@ export class ZoneClientBackend extends
} }
export function zoneWrappedInterceptingHandler( export function zoneWrappedInterceptingHandler(
backend: HttpBackend, injector: Injector, platformLocation: PlatformLocation) { backend: HttpBackend, injector: Injector, doc: Document) {
const realBackend: HttpBackend = new HttpInterceptingHandler(backend, injector); const realBackend: HttpBackend = new HttpInterceptingHandler(backend, injector);
return new ZoneClientBackend(realBackend, platformLocation); return new ZoneClientBackend(realBackend, doc);
} }
export const SERVER_HTTP_PROVIDERS: Provider[] = [ export const SERVER_HTTP_PROVIDERS: Provider[] = [
{provide: XhrFactory, useClass: ServerXhr}, { {provide: XhrFactory, useClass: ServerXhr}, {
provide: HttpHandler, provide: HttpHandler,
useFactory: zoneWrappedInterceptingHandler, useFactory: zoneWrappedInterceptingHandler,
deps: [HttpBackend, Injector, PlatformLocation] deps: [HttpBackend, Injector, DOCUMENT]
} }
]; ];

View File

@ -51,7 +51,6 @@ export class ServerPlatformLocation implements PlatformLocation {
this.pathname = parsedUrl.pathname; this.pathname = parsedUrl.pathname;
this.search = parsedUrl.search; this.search = parsedUrl.search;
this.hash = parsedUrl.hash; this.hash = parsedUrl.hash;
this.href = _doc.location.href;
} }
} }

View File

@ -841,58 +841,6 @@ describe('platform-server integration', () => {
}); });
}); });
it('can make relative HttpClient requests no slashes longer url', async () => {
const platform = platformDynamicServer([{
provide: INITIAL_CONFIG,
useValue: {document: '<app></app>', url: 'http://localhost/path/page'}
}]);
const ref = await platform.bootstrapModule(HttpClientExampleModule);
const mock = ref.injector.get(HttpTestingController) as HttpTestingController;
const http = ref.injector.get(HttpClient);
ref.injector.get(NgZone).run(() => {
http.get<string>('testing').subscribe((body: string) => {
NgZone.assertInAngularZone();
expect(body).toEqual('success!');
});
mock.expectOne('http://localhost/path/testing').flush('success!');
});
});
it('can make relative HttpClient requests slashes longer url', async () => {
const platform = platformDynamicServer([{
provide: INITIAL_CONFIG,
useValue: {document: '<app></app>', url: 'http://localhost/path/page'}
}]);
const ref = await platform.bootstrapModule(HttpClientExampleModule);
const mock = ref.injector.get(HttpTestingController) as HttpTestingController;
const http = ref.injector.get(HttpClient);
ref.injector.get(NgZone).run(() => {
http.get<string>('/testing').subscribe((body: string) => {
NgZone.assertInAngularZone();
expect(body).toEqual('success!');
});
mock.expectOne('http://localhost/testing').flush('success!');
});
});
it('can make relative HttpClient requests slashes longer url with base href', async () => {
const platform = platformDynamicServer([{
provide: INITIAL_CONFIG,
useValue:
{document: '<base href="http://other"><app></app>', url: 'http://localhost/path/page'}
}]);
const ref = await platform.bootstrapModule(HttpClientExampleModule);
const mock = ref.injector.get(HttpTestingController) as HttpTestingController;
const http = ref.injector.get(HttpClient);
ref.injector.get(NgZone).run(() => {
http.get<string>('/testing').subscribe((body: string) => {
NgZone.assertInAngularZone();
expect(body).toEqual('success!');
});
mock.expectOne('http://other/testing').flush('success!');
});
});
it('requests are macrotasks', async(() => { it('requests are macrotasks', async(() => {
const platform = platformDynamicServer( const platform = platformDynamicServer(
[{provide: INITIAL_CONFIG, useValue: {document: '<app></app>'}}]); [{provide: INITIAL_CONFIG, useValue: {document: '<app></app>'}}]);