diff --git a/src/app/components/components/http/http.component.html b/src/app/components/components/http/http.component.html
index aa02c6caba..a4f005fcef 100644
--- a/src/app/components/components/http/http.component.html
+++ b/src/app/components/components/http/http.component.html
@@ -70,17 +70,31 @@
Setup:
}
]]>
- Then, import the [CovalentHttpModule] using the forRoot()
method with the desired interceptors in your NgModule:
+ Then, import the [CovalentHttpModule] using the forRoot()
method with the desired interceptors and paths to intercept in your NgModule:
[] = [
+ CustomInterceptor,
+ ...
+ ];
+
@NgModule({
imports: [
HttpModule, /* or CovalentCoreModule.forRoot() */
- CovalentHttpModule.forRoot([CustomInterceptor]),
+ CovalentHttpModule.forRoot({
+ interceptors: [{
+ interceptor: CustomInterceptor, paths: ['**'],
+ }],
+ }),
+ ...
+ ],
+ providers: [
+ httpInterceptorProviders,
...
],
...
@@ -89,6 +103,63 @@ Setup:
]]>
After that, just inject [HttpInterceptorService] and use it for your requests.
+ Paths:
+ The following characters are accepted as a path to intercept:
+
+
+- `**` is a wildcard for `[a-zA-Z0-9-_]` (including `/`)
+- `*` is a wildcard for `[a-zA-Z0-9-_]` (excluding `/`)
+- `[a-zA-Z0-9-_]`
+
+
+ Examples:
+
+
+Example 1
+
+`/users/*/groups` intercepts:
+- `www.url.com/users/id-of-user/groups`
+- `www.url.com/users/id/groups`
+
+`/users/*/groups` DOES NOT intercept:
+- `www.url.com/users/id-of-user/groups/path`
+- `www.url.com/users/id-of-user/path/groups`
+- `www.url.com/users/groups`
+
+Example 2
+
+`/users/**/groups` intercepts:
+- `www.url.com/users/id-of-user/groups`
+- `www.url.com/users/id/groups`
+- `www.url.com/users/id-of-user/path/groups`
+
+`/users/**/groups` DOES NOT intercept:
+- `www.url.com/users/id-of-user/groups/path`
+- `www.url.com/users/groups`
+
+Example 3
+
+`/users/**` intercepts:
+- `www.url.com/users/id-of-user/groups`
+- `www.url.com/users/id/groups`
+- `www.url.com/users/id-of-user/path/groups`
+- `www.url.com/users/id-of-user/groups/path`
+- `www.url.com/users/groups`
+
+`/users/**` DOES NOT intercept:
+- `www.url.com/users`
+
+Example 4
+
+`/users**` intercepts:
+- `www.url.com/users/id-of-user/groups`
+- `www.url.com/users/id/groups`
+- `www.url.com/users/id-of-user/path/groups`
+- `www.url.com/users/id-of-user/groups/path`
+- `www.url.com/users/groups`
+- `www.url.com/users`
+
+
diff --git a/src/platform/http/README.md b/src/platform/http/README.md
index e6cfe7665a..4b154e691d 100644
--- a/src/platform/http/README.md
+++ b/src/platform/http/README.md
@@ -73,16 +73,31 @@ export class CustomInterceptor implements IHttpInterceptor {
```
-Then, import the [CovalentHttpModule] using the forRoot() method with the desired interceptors in your NgModule:
+Then, import the [CovalentHttpModule] using the forRoot() method with the desired interceptors and paths to intercept in your NgModule:
```typescript
+import { NgModule, Type } from '@angular/core';
import { HttpModule } from '@angular/http';
-import { CovalentHttpModule } from '@covalent/http';
+import { CovalentHttpModule, IHttpInterceptor } from '@covalent/http';
import { CustomInterceptor } from 'dir/to/interceptor';
+
+const httpInterceptorProviders: Type[] = [
+ CustomInterceptor,
+ ...
+];
+
@NgModule({
imports: [
HttpModule, /* or CovalentCoreModule.forRoot() */
- CovalentHttpModule.forRoot([CustomInterceptor]),
+ CovalentHttpModule.forRoot({
+ interceptors: [{
+ interceptor: CustomInterceptor, paths: ['**'],
+ }],
+ }),
+ ...
+ ],
+ providers: [
+ httpInterceptorProviders,
...
],
...
@@ -92,6 +107,59 @@ export class MyModule {}
After that, just inject [HttpInterceptorService] and use it for your requests.
+## Paths
+
+The following characters are accepted as a path to intercept
+- `**` is a wildcard for `[a-zA-Z0-9-_]` (including `/`)
+- `*` is a wildcard for `[a-zA-Z0-9-_]` (excluding `/`)
+- `[a-zA-Z0-9-_]`
+
+#### Examples
+
+Example 1
+
+`/users/*/groups` intercepts:
+- `www.url.com/users/id-of-user/groups`
+- `www.url.com/users/id/groups`
+
+`/users/*/groups` DOES NOT intercept:
+- `www.url.com/users/id-of-user/groups/path`
+- `www.url.com/users/id-of-user/path/groups`
+- `www.url.com/users/groups`
+
+Example 2
+
+`/users/**/groups` intercepts:
+- `www.url.com/users/id-of-user/groups`
+- `www.url.com/users/id/groups`
+- `www.url.com/users/id-of-user/path/groups`
+
+`/users/**/groups` DOES NOT intercept:
+- `www.url.com/users/id-of-user/groups/path`
+- `www.url.com/users/groups`
+
+Example 3
+
+`/users/**` intercepts:
+- `www.url.com/users/id-of-user/groups`
+- `www.url.com/users/id/groups`
+- `www.url.com/users/id-of-user/path/groups`
+- `www.url.com/users/id-of-user/groups/path`
+- `www.url.com/users/groups`
+
+`/users/**` DOES NOT intercept:
+- `www.url.com/users`
+
+Example 4
+
+`/users**` intercepts:
+- `www.url.com/users/id-of-user/groups`
+- `www.url.com/users/id/groups`
+- `www.url.com/users/id-of-user/path/groups`
+- `www.url.com/users/id-of-user/groups/path`
+- `www.url.com/users/groups`
+- `www.url.com/users`
+
# RESTService
diff --git a/src/platform/http/http-interceptor.service.spec.ts b/src/platform/http/http-interceptor.service.spec.ts
deleted file mode 100644
index 914ff7a67e..0000000000
--- a/src/platform/http/http-interceptor.service.spec.ts
+++ /dev/null
@@ -1,154 +0,0 @@
-import {
- TestBed,
- inject,
- async,
-} from '@angular/core/testing';
-import { Injector } from '@angular/core';
-import { XHRBackend, Response, ResponseOptions } from '@angular/http';
-import { Observable } from 'rxjs/Observable';
-import { MockBackend } from '@angular/http/testing';
-import { HttpModule, Http } from '@angular/http';
-import { HttpInterceptorService } from './http-interceptor.service';
-import 'rxjs/Rx';
-
-describe('Service: HttpInterceptor', () => {
-
- beforeEach(async(() => {
- TestBed.configureTestingModule({
- imports: [
- HttpModule,
- ],
- providers: [
- MockBackend, {
- provide: XHRBackend,
- useExisting: MockBackend,
- }, {
- provide: HttpInterceptorService,
- useFactory: (http: Http, injector: Injector): HttpInterceptorService => {
- return new HttpInterceptorService(http, injector, []);
- },
- deps: [Http, Injector],
- },
- ],
- });
- }));
-
- it('expect to do a forkJoin get succesfully with observables',
- async(inject([HttpInterceptorService, MockBackend], (service: HttpInterceptorService, mockBackend: MockBackend) => {
- mockBackend.connections.subscribe((connection: any) => {
- connection.mockRespond(new Response(new ResponseOptions({
- status: 200,
- body: JSON.stringify('success')}
- )));
- });
- let success: boolean = false;
- let error: boolean = false;
- let complete: boolean = false;
-
- Observable.forkJoin(
- service.get('testurl'),
- service.get('testurl'))
- .subscribe((response: Response[]) => {
- success = true;
- }, () => {
- error = true;
- }, () => {
- complete = true;
- });
-
- expect(success).toBe(true, 'on success didnt execute with observables');
- expect(error).toBe(false, 'on error executed when it shouldnt have with observables');
- expect(complete).toBe(true, 'on complete didnt execute with observables');
- })
- ));
-
- it('expect to do a post succesfully with observables',
- async(inject([HttpInterceptorService, MockBackend], (service: HttpInterceptorService, mockBackend: MockBackend) => {
- mockBackend.connections.subscribe((connection: any) => {
- connection.mockRespond(new Response(new ResponseOptions({
- status: 200,
- body: JSON.stringify('success')}
- )));
- });
- let success: boolean = false;
- let error: boolean = false;
- let complete: boolean = false;
- service.post('testurl', {}).map((res: Response) => res.json()).subscribe((data: string) => {
- expect(data).toBe('success');
- success = true;
- }, () => {
- error = true;
- }, () => {
- complete = true;
- });
- expect(success).toBe(true, 'on success didnt execute with observables');
- expect(error).toBe(false, 'on error executed when it shouldnt have with observables');
- expect(complete).toBe(true, 'on complete didnt execute with observables');
- })
- ));
-
- it('expect to do a post failure with observables',
- async(inject([HttpInterceptorService, MockBackend], (service: HttpInterceptorService, mockBackend: MockBackend) => {
- mockBackend.connections.subscribe((connection: any) => {
- connection.mockError(new Error('error'));
- });
- let success: boolean = false;
- let error: boolean = false;
- let complete: boolean = false;
- service.post('testurl', {}).map((res: Response) => res.json()).subscribe(() => {
- success = true;
- }, (err: Error) => {
- expect(err.message).toBe('error');
- error = true;
- }, () => {
- complete = true;
- });
- expect(success).toBe(false, 'on success execute when it shouldnt have with observables');
- expect(error).toBe(true, 'on error didnt execute with observables');
- expect(complete).toBe(false, 'on complete execute when it shouldnt have with observables');
- })
- ));
-
- it('expect to do a post succesfully with promises',
- async(inject([HttpInterceptorService, MockBackend], (service: HttpInterceptorService, mockBackend: MockBackend) => {
- mockBackend.connections.subscribe((connection: any) => {
- connection.mockRespond(new Response(new ResponseOptions({
- status: 200,
- body: JSON.stringify('success')}
- )));
- });
- let success: boolean = false;
- let error: boolean = false;
- service.post('testurl', {}).map((res: Response) => res.json()).toPromise().then((data: string) => {
- expect(data).toBe('success');
- success = true;
- }, () => {
- error = true;
- });
- setTimeout(() => {
- expect(success).toBe(true, 'on success didnt execute with promises');
- expect(error).toBe(false, 'on error executed when it shouldnt have with promises');
- });
- })
- ));
-
- it('expect to do a post failure with promises',
- async(inject([HttpInterceptorService, MockBackend], (service: HttpInterceptorService, mockBackend: MockBackend) => {
- mockBackend.connections.subscribe((connection: any) => {
- connection.mockError(new Error('error'));
- });
- let success: boolean = false;
- let error: boolean = false;
- service.post('testurl', {}).map((res: Response) => res.json()).toPromise().then(() => {
- success = true;
- }, (err: Error) => {
- expect(err.message).toBe('error');
- error = true;
- });
- setTimeout(() => {
- expect(success).toBe(false, 'on success execute when it shouldnt have with promises');
- expect(error).toBe(true, 'on error didnt execute with promises');
- });
- })
- ));
-});
diff --git a/src/platform/http/http-interceptor.service.ts b/src/platform/http/http-interceptor.service.ts
deleted file mode 100644
index cce6825abb..0000000000
--- a/src/platform/http/http-interceptor.service.ts
+++ /dev/null
@@ -1,160 +0,0 @@
-import { Injectable, Type, Injector } from '@angular/core';
-import { Http, RequestOptionsArgs, Response, Request } from '@angular/http';
-
-import { Observable } from 'rxjs/Observable';
-import { Subscriber } from 'rxjs/Subscriber';
-
-export interface IHttpInterceptor {
- onRequest?: (requestOptions: RequestOptionsArgs) => RequestOptionsArgs;
- onRequestError?: (requestOptions: RequestOptionsArgs) => RequestOptionsArgs;
- onResponse?: (response: Response) => Response;
- onResponseError?: (error: Response) => Response;
-}
-
-@Injectable()
-export class HttpInterceptorService {
-
- private _requestInterceptors: IHttpInterceptor[] = [];
-
- constructor(private _http: Http, private _injector: Injector, requestInterceptors: Type[]) {
- requestInterceptors.forEach((interceptor: Type) => {
- this._requestInterceptors.push(_injector.get(interceptor));
- });
- }
-
- request(url: string | Request, options: RequestOptionsArgs = {}): Observable {
- let requestOptionsArgs: RequestOptionsArgs;
- try {
- requestOptionsArgs = this._requestResolve(options);
- } catch (e) {
- return new Observable((subscriber: Subscriber) => {
- subscriber.error(e);
- });
- }
- return this._setupRequest(this._http.request(url, requestOptionsArgs));
- }
-
- delete(url: string, options: RequestOptionsArgs = {}): Observable {
- let requestOptionsArgs: RequestOptionsArgs;
- try {
- requestOptionsArgs = this._requestResolve(options);
- } catch (e) {
- return new Observable((subscriber: Subscriber) => {
- subscriber.error(e);
- });
- }
- return this._setupRequest(this._http.delete(url, requestOptionsArgs));
- }
-
- get(url: string, options: RequestOptionsArgs = {}): Observable {
- let requestOptionsArgs: RequestOptionsArgs;
- try {
- requestOptionsArgs = this._requestResolve(options);
- } catch (e) {
- return new Observable((subscriber: Subscriber) => {
- subscriber.error(e);
- });
- }
- return this._setupRequest(this._http.get(url, requestOptionsArgs));
- }
-
- head(url: string, options: RequestOptionsArgs = {}): Observable {
- let requestOptionsArgs: RequestOptionsArgs;
- try {
- requestOptionsArgs = this._requestResolve(options);
- } catch (e) {
- return new Observable((subscriber: Subscriber) => {
- subscriber.error(e);
- });
- }
- return this._setupRequest(this._http.head(url, requestOptionsArgs));
- }
-
- patch(url: string, data: any, options: RequestOptionsArgs = {}): Observable {
- let requestOptionsArgs: RequestOptionsArgs;
- try {
- requestOptionsArgs = this._requestResolve(options);
- } catch (e) {
- return new Observable((subscriber: Subscriber) => {
- subscriber.error(e);
- });
- }
- return this._setupRequest(this._http.patch(url, data, requestOptionsArgs));
- }
-
- post(url: string, data: any, options: RequestOptionsArgs = {}): Observable {
- let requestOptionsArgs: RequestOptionsArgs;
- try {
- requestOptionsArgs = this._requestResolve(options);
- } catch (e) {
- return new Observable((subscriber: Subscriber) => {
- subscriber.error(e);
- });
- }
- return this._setupRequest(this._http.post(url, data, requestOptionsArgs));
- }
-
- put(url: string, data: any, options: RequestOptionsArgs = {}): Observable {
- let requestOptionsArgs: RequestOptionsArgs;
- try {
- requestOptionsArgs = this._requestResolve(options);
- } catch (e) {
- return new Observable((subscriber: Subscriber) => {
- subscriber.error(e);
- });
- }
- return this._setupRequest(this._http.put(url, data, requestOptionsArgs));
- }
-
- private _setupRequest(responseObservable: Observable): Observable {
- return new Observable((subscriber: Subscriber) => {
- responseObservable.do((response: Response) => {
- subscriber.next(this._responseResolve(response));
- subscriber.complete();
- }).catch((error: Response) => {
- return new Observable(() => {
- subscriber.error(this._responseErrorResolve(error));
- });
- }).subscribe();
- });
- }
-
- private _requestResolve(requestOptions: RequestOptionsArgs): RequestOptionsArgs {
- this._requestInterceptors.forEach((interceptor: IHttpInterceptor) => {
- if (interceptor.onRequest) {
- try {
- requestOptions = interceptor.onRequest(requestOptions);
- } catch (e) {
- if (interceptor.onRequestError) {
- requestOptions = interceptor.onRequestError(requestOptions);
- if (!requestOptions) {
- throw e;
- }
- } else {
- throw e;
- }
- }
- }
- });
- return requestOptions;
- }
-
- private _responseResolve(response: Response): Response {
- this._requestInterceptors.forEach((interceptor: IHttpInterceptor) => {
- if (interceptor.onResponse) {
- response = interceptor.onResponse(response);
- }
- });
- return response;
- }
-
- private _responseErrorResolve(error: Response): Response {
- this._requestInterceptors.forEach((interceptor: IHttpInterceptor) => {
- if (interceptor.onResponseError) {
- error = interceptor.onResponseError(error);
- }
- });
- return error;
- }
-
-}
diff --git a/src/platform/http/http.module.ts b/src/platform/http/http.module.ts
index 85f02379ed..063e094bd4 100644
--- a/src/platform/http/http.module.ts
+++ b/src/platform/http/http.module.ts
@@ -1,32 +1,35 @@
-import { NgModule, ModuleWithProviders, Type, Injector } from '@angular/core';
+import { NgModule, ModuleWithProviders, Injector, OpaqueToken } from '@angular/core';
import { HttpModule, Http } from '@angular/http';
-import { HttpInterceptorService } from './http-interceptor.service';
+import { HttpInterceptorService, IHttpInterceptorConfig } from './interceptors/http-interceptor.service';
+import { URLRegExpInterceptorMatcher } from './interceptors/url-regexp-interceptor-matcher.class';
+
+export const HTTP_CONFIG: OpaqueToken = new OpaqueToken('HTTP_CONFIG');
+
+export type HttpConfig = {inteceptors: IHttpInterceptorConfig[]};
+
+export function httpFactory(http: Http, injector: Injector, config: HttpConfig): HttpInterceptorService {
+ return new HttpInterceptorService(http, injector, new URLRegExpInterceptorMatcher(), config.inteceptors);
+}
@NgModule({
imports: [
HttpModule,
],
- providers: [
- HttpInterceptorService,
- ],
})
export class CovalentHttpModule {
- static forRoot(requestInterceptors: Type[] = []): ModuleWithProviders {
- let providers: any[] = [];
- requestInterceptors.forEach((interceptor: Type) => {
- providers.push(interceptor);
- });
- providers.push({
- provide: HttpInterceptorService,
- useFactory: (http: Http, injector: Injector): HttpInterceptorService => {
- return new HttpInterceptorService(http, injector, requestInterceptors);
- },
- deps: [Http, Injector],
- });
+ static forRoot(config: HttpConfig = {inteceptors: []}): ModuleWithProviders {
return {
ngModule: CovalentHttpModule,
- providers: providers,
+ providers: [{
+ provide: HTTP_CONFIG,
+ useValue: config,
+ }, {
+ provide: HttpInterceptorService,
+ useFactory: httpFactory,
+ deps: [Http, Injector, HTTP_CONFIG],
+ },
+ ],
};
}
}
diff --git a/src/platform/http/index.ts b/src/platform/http/index.ts
index 47d596a918..ed64edb854 100644
--- a/src/platform/http/index.ts
+++ b/src/platform/http/index.ts
@@ -1,3 +1,4 @@
export { RESTService, IRestTransform, IRestConfig, IRestQuery, IHttp } from './http-rest.service';
-export { IHttpInterceptor, HttpInterceptorService } from './http-interceptor.service';
-export { CovalentHttpModule } from './http.module';
+export { HttpInterceptorService, IHttpInterceptorConfig } from './interceptors/http-interceptor.service';
+export { IHttpInterceptor } from './interceptors/http-interceptor.interface';
+export { CovalentHttpModule, HttpConfig } from './http.module';
diff --git a/src/platform/http/interceptors/http-interceptor-mapping.interface.ts b/src/platform/http/interceptors/http-interceptor-mapping.interface.ts
new file mode 100644
index 0000000000..0f2315edad
--- /dev/null
+++ b/src/platform/http/interceptors/http-interceptor-mapping.interface.ts
@@ -0,0 +1,10 @@
+import { IHttpInterceptor } from './http-interceptor.interface';
+
+/**
+ * Interface for http interceptor mappings.
+ * Maps the interceptor with the desired interception rule.
+ */
+export interface IHttpInterceptorMapping {
+ interceptor: IHttpInterceptor;
+ paths: string[];
+}
diff --git a/src/platform/http/interceptors/http-interceptor-matcher.interface.ts b/src/platform/http/interceptors/http-interceptor-matcher.interface.ts
new file mode 100644
index 0000000000..e638eab5a4
--- /dev/null
+++ b/src/platform/http/interceptors/http-interceptor-matcher.interface.ts
@@ -0,0 +1,13 @@
+import { RequestOptionsArgs } from '@angular/http';
+
+import { IHttpInterceptorMapping } from './http-interceptor-mapping.interface';
+
+/**
+ * Interface for http interceptor matchers.
+ * Implement a class to set the behavior of how the interceptors are matched with the requests.
+ */
+export interface IHttpInterceptorMatcher {
+
+ matches(options: RequestOptionsArgs, mapping: IHttpInterceptorMapping): boolean;
+
+}
diff --git a/src/platform/http/interceptors/http-interceptor.interface.ts b/src/platform/http/interceptors/http-interceptor.interface.ts
new file mode 100644
index 0000000000..d47c2daddd
--- /dev/null
+++ b/src/platform/http/interceptors/http-interceptor.interface.ts
@@ -0,0 +1,12 @@
+import { RequestOptionsArgs, Response } from '@angular/http';
+
+/**
+ * Interface for http interceptors.
+ * Implement the methods you want to be executed in the request pipeline on interception.
+ */
+export interface IHttpInterceptor {
+ onRequest?: (requestOptions: RequestOptionsArgs) => RequestOptionsArgs;
+ onRequestError?: (requestOptions: RequestOptionsArgs) => RequestOptionsArgs;
+ onResponse?: (response: Response) => Response;
+ onResponseError?: (error: Response) => Response;
+}
diff --git a/src/platform/http/interceptors/http-interceptor.service.spec.ts b/src/platform/http/interceptors/http-interceptor.service.spec.ts
new file mode 100644
index 0000000000..ca7c06c1a4
--- /dev/null
+++ b/src/platform/http/interceptors/http-interceptor.service.spec.ts
@@ -0,0 +1,386 @@
+import {
+ TestBed,
+ inject,
+ async,
+} from '@angular/core/testing';
+import { Injector, Injectable, Type } from '@angular/core';
+import { Headers, XHRBackend, Response, ResponseOptions, RequestOptionsArgs } from '@angular/http';
+import { Observable } from 'rxjs/Observable';
+import { MockBackend, MockConnection } from '@angular/http/testing';
+import { HttpModule, Http } from '@angular/http';
+import { HttpInterceptorService, HttpConfig, CovalentHttpModule, IHttpInterceptor } from '../';
+import { URLRegExpInterceptorMatcher } from './url-regexp-interceptor-matcher.class';
+import 'rxjs/Rx';
+
+@Injectable()
+export class ResponseOverrideInterceptor {
+
+ onResponse(response: Response): Response {
+ return new Response(new ResponseOptions({body: JSON.stringify('override'), status: 200}));
+ }
+}
+
+@Injectable()
+export class RequestAuthInterceptor {
+ onRequest(request: RequestOptionsArgs): RequestOptionsArgs {
+ if (!request.headers) {
+ request.headers = new Headers();
+ }
+ request.headers.set('auth', 'test-auth');
+ return request;
+ }
+}
+
+@Injectable()
+export class RequestFailureInterceptor {
+ onRequest(request: RequestOptionsArgs): RequestOptionsArgs {
+ throw 'error';
+ }
+}
+
+@Injectable()
+export class RequestRecoveryInterceptor {
+ onRequest(request: RequestOptionsArgs): RequestOptionsArgs {
+ throw 'error';
+ }
+
+ onRequestError(request: RequestOptionsArgs): RequestOptionsArgs {
+ if (!request.headers) {
+ request.headers = new Headers();
+ }
+ request.headers.set('recovered', 'yes');
+ return request;
+ }
+
+ onResponse(response: Response): Response {
+ return new Response(new ResponseOptions({body: JSON.stringify('recovered'), status: 200}));
+ }
+}
+
+describe('Service: HttpInterceptor', () => {
+
+ let config: HttpConfig = {
+ inteceptors: [{
+ interceptor: ResponseOverrideInterceptor, paths: ['/url**'],
+ }, {
+ interceptor: RequestAuthInterceptor, paths: ['**'],
+ }, {
+ interceptor: RequestFailureInterceptor, paths: ['/error'],
+ }, {
+ interceptor: RequestRecoveryInterceptor, paths: ['/recovery/*/fromerror'],
+ }],
+ };
+
+ const httpInterceptorProviders: Type[] = [
+ ResponseOverrideInterceptor,
+ RequestAuthInterceptor,
+ RequestFailureInterceptor,
+ RequestRecoveryInterceptor,
+ ];
+
+ beforeEach(async(() => {
+ TestBed.configureTestingModule({
+ imports: [
+ CovalentHttpModule.forRoot(config),
+ ],
+ providers: [
+ MockBackend, {
+ provide: XHRBackend,
+ useExisting: MockBackend,
+ },
+ httpInterceptorProviders,
+ ],
+ });
+ }));
+
+ it('expect to intercept only the route with `/recovery/*/fromerror` and recover from a failure',
+ async(inject([HttpInterceptorService, MockBackend], (service: HttpInterceptorService, mockBackend: MockBackend) => {
+ mockBackend.connections.subscribe((connection: MockConnection) => {
+ if (connection.request.url === 'http://www.test.com/recovery/id/fromerror') {
+ expect(connection.request.headers.get('recovered')).toBe('yes', 'did not execute onRequestError when failed');
+ } else {
+ expect(connection.request.headers.get('recovered'))
+ .toBeNull('did execute onRequestError when failed when it shouldnt');
+ }
+ connection.mockRespond(new Response(new ResponseOptions({
+ status: 200,
+ body: JSON.stringify('success')}
+ )));
+ });
+
+ service.patch('http://www.test.com/recovery/id/id2/fromerror', {})
+ .map((res: Response) => res.json()).subscribe((data: string) => {
+ expect(data).toBe('success', '/error/*/fromerror was intercepted');
+ });
+
+ service.patch('http://www.test.com/recovery/id/fromerror', {})
+ .map((res: Response) => res.json()).subscribe((data: string) => {
+ expect(data).toBe('recovered', '/error/*/fromerror was not intercepted');
+ });
+ })
+ ));
+
+ it('expect to intercept only the route with `/error` and fail',
+ async(inject([HttpInterceptorService, MockBackend], (service: HttpInterceptorService, mockBackend: MockBackend) => {
+ mockBackend.connections.subscribe((connection: MockConnection) => {
+ connection.mockRespond(new Response(new ResponseOptions({
+ status: 200,
+ body: JSON.stringify('success')}
+ )));
+ });
+
+ service.patch('http://www.test.com/error', {})
+ .map((res: Response) => res.json()).subscribe((data: string) => {
+ expect(data).toBeUndefined('/error was not intercepted so request didnt fail');
+ }, (error: any) => {
+ expect(error).toBe('error');
+ });
+ })
+ ));
+
+ it('expect to intercept all routes and add an `auth=test-auth` header',
+ async(inject([HttpInterceptorService, MockBackend], (service: HttpInterceptorService, mockBackend: MockBackend) => {
+ mockBackend.connections.subscribe((connection: MockConnection) => {
+ expect(connection.request.headers.get('auth')).toBe('test-auth', 'didnt add `auth` header on all routes');
+ connection.mockRespond(new Response(new ResponseOptions({
+ status: 200,
+ body: JSON.stringify('success')}
+ )));
+ });
+
+ service.post('http://www.test.com/url/with/any-path/another-path?query=1&query=2', {})
+ .map((res: Response) => res.json()).subscribe((data: string) => {
+ expect(data).toBeTruthy();
+ });
+
+ service.post('http://www.test.com/any_path?query=1&query=2', {})
+ .map((res: Response) => res.json()).subscribe((data: string) => {
+ expect(data).toBeTruthy();
+ });
+
+ service.get('http://www.test.com/url/any-path/111')
+ .map((res: Response) => res.json()).subscribe((data: string) => {
+ expect(data).toBeTruthy();
+ });
+
+ service.get('http://www.test.com/anypath/url')
+ .map((res: Response) => res.json()).subscribe((data: string) => {
+ expect(data).toBeTruthy();
+ });
+
+ service.delete('http://www.test.com/any_path?', {})
+ .map((res: Response) => res.json()).subscribe((data: string) => {
+ expect(data).toBeTruthy();
+ });
+
+ service.delete('http://www.test.com', {})
+ .map((res: Response) => res.json()).subscribe((data: string) => {
+ expect(data).toBeTruthy();
+ });
+
+ service.patch('http://www.test.com/any_path/111/url/another_path', {})
+ .map((res: Response) => res.json()).subscribe((data: string) => {
+ expect(data).toBeTruthy();
+ });
+
+ service.patch('http://www.test.com/any-path/111/another_path/', {})
+ .map((res: Response) => res.json()).subscribe((data: string) => {
+ expect(data).toBeTruthy();
+ });
+ })
+ ));
+
+ it('expect to intercept routes that contain `/url` in them and override responses body with `override`',
+ async(inject([HttpInterceptorService, MockBackend], (service: HttpInterceptorService, mockBackend: MockBackend) => {
+ mockBackend.connections.subscribe((connection: MockConnection) => {
+ connection.mockRespond(new Response(new ResponseOptions({
+ status: 200,
+ body: JSON.stringify('success')}
+ )));
+ });
+
+ service.post('http://www.test.com/url/with/any-path/another-path?query=1&query=2', {})
+ .map((res: Response) => res.json()).subscribe((data: string) => {
+ expect(data).toBe('override', 'didnt intercept url with `/url`');
+ });
+
+ service.post('http://www.test.com/any_path?query=1&query=2', {})
+ .map((res: Response) => res.json()).subscribe((data: string) => {
+ expect(data).toBe('success', 'intercepted url without `/url`');
+ });
+
+ service.get('http://www.test.com/url/any-path/111')
+ .map((res: Response) => res.json()).subscribe((data: string) => {
+ expect(data).toBe('override', 'didnt intercept url with `/url`');
+ });
+
+ service.get('http://www.test.com/anypath/url')
+ .map((res: Response) => res.json()).subscribe((data: string) => {
+ expect(data).toBe('override', 'didnt intercept url with `/url`');
+ });
+
+ service.delete('http://www.test.com/any_path?', {})
+ .map((res: Response) => res.json()).subscribe((data: string) => {
+ expect(data).toBe('success', 'intercepted url without `/url`');
+ });
+
+ service.delete('http://www.test.com', {})
+ .map((res: Response) => res.json()).subscribe((data: string) => {
+ expect(data).toBe('success', 'intercepted url without `/url`');
+ });
+
+ service.patch('http://www.test.com/any_path/111/url/another_path', {})
+ .map((res: Response) => res.json()).subscribe((data: string) => {
+ expect(data).toBe('override', 'didnt intercept url with `/url`');
+ });
+
+ service.patch('http://www.test.com/any-path/111/another_path/', {})
+ .map((res: Response) => res.json()).subscribe((data: string) => {
+ expect(data).toBe('success', 'intercepted url without `/url`');
+ });
+ })
+ ));
+
+});
+
+describe('Service: HttpInterceptor', () => {
+
+ beforeEach(async(() => {
+ TestBed.configureTestingModule({
+ imports: [
+ HttpModule,
+ ],
+ providers: [
+ MockBackend, {
+ provide: XHRBackend,
+ useExisting: MockBackend,
+ }, {
+ provide: HttpInterceptorService,
+ useFactory: (http: Http, injector: Injector): HttpInterceptorService => {
+ return new HttpInterceptorService(http, injector, new URLRegExpInterceptorMatcher(), []);
+ },
+ deps: [Http, Injector],
+ },
+ ],
+ });
+ }));
+
+ it('expect to do a forkJoin get succesfully with observables',
+ async(inject([HttpInterceptorService, MockBackend], (service: HttpInterceptorService, mockBackend: MockBackend) => {
+ mockBackend.connections.subscribe((connection: MockConnection) => {
+ connection.mockRespond(new Response(new ResponseOptions({
+ status: 200,
+ body: JSON.stringify('success')}
+ )));
+ });
+ let success: boolean = false;
+ let error: boolean = false;
+ let complete: boolean = false;
+
+ Observable.forkJoin(
+ service.get('testurl'),
+ service.get('testurl'))
+ .subscribe((response: Response[]) => {
+ success = true;
+ }, () => {
+ error = true;
+ }, () => {
+ complete = true;
+ });
+
+ expect(success).toBe(true, 'on success didnt execute with observables');
+ expect(error).toBe(false, 'on error executed when it shouldnt have with observables');
+ expect(complete).toBe(true, 'on complete didnt execute with observables');
+ })
+ ));
+
+ it('expect to do a post succesfully with observables',
+ async(inject([HttpInterceptorService, MockBackend], (service: HttpInterceptorService, mockBackend: MockBackend) => {
+ mockBackend.connections.subscribe((connection: MockConnection) => {
+ connection.mockRespond(new Response(new ResponseOptions({
+ status: 200,
+ body: JSON.stringify('success')}
+ )));
+ });
+ let success: boolean = false;
+ let error: boolean = false;
+ let complete: boolean = false;
+ service.post('testurl', {}).map((res: Response) => res.json()).subscribe((data: string) => {
+ expect(data).toBe('success');
+ success = true;
+ }, () => {
+ error = true;
+ }, () => {
+ complete = true;
+ });
+ expect(success).toBe(true, 'on success didnt execute with observables');
+ expect(error).toBe(false, 'on error executed when it shouldnt have with observables');
+ expect(complete).toBe(true, 'on complete didnt execute with observables');
+ })
+ ));
+
+ it('expect to do a post failure with observables',
+ async(inject([HttpInterceptorService, MockBackend], (service: HttpInterceptorService, mockBackend: MockBackend) => {
+ mockBackend.connections.subscribe((connection: MockConnection) => {
+ connection.mockError(new Error('error'));
+ });
+ let success: boolean = false;
+ let error: boolean = false;
+ let complete: boolean = false;
+ service.post('testurl', {}).map((res: Response) => res.json()).subscribe(() => {
+ success = true;
+ }, (err: Error) => {
+ expect(err.message).toBe('error');
+ error = true;
+ }, () => {
+ complete = true;
+ });
+ expect(success).toBe(false, 'on success execute when it shouldnt have with observables');
+ expect(error).toBe(true, 'on error didnt execute with observables');
+ expect(complete).toBe(false, 'on complete execute when it shouldnt have with observables');
+ })
+ ));
+
+ it('expect to do a post succesfully with promises',
+ async(inject([HttpInterceptorService, MockBackend], (service: HttpInterceptorService, mockBackend: MockBackend) => {
+ mockBackend.connections.subscribe((connection: MockConnection) => {
+ connection.mockRespond(new Response(new ResponseOptions({
+ status: 200,
+ body: JSON.stringify('success')}
+ )));
+ });
+ let success: boolean = false;
+ let error: boolean = false;
+ service.post('testurl', {}).map((res: Response) => res.json()).toPromise().then((data: string) => {
+ expect(data).toBe('success');
+ success = true;
+ }, () => {
+ error = true;
+ });
+ setTimeout(() => {
+ expect(success).toBe(true, 'on success didnt execute with promises');
+ expect(error).toBe(false, 'on error executed when it shouldnt have with promises');
+ });
+ })
+ ));
+
+ it('expect to do a post failure with promises',
+ async(inject([HttpInterceptorService, MockBackend], (service: HttpInterceptorService, mockBackend: MockBackend) => {
+ mockBackend.connections.subscribe((connection: MockConnection) => {
+ connection.mockError(new Error('error'));
+ });
+ let success: boolean = false;
+ let error: boolean = false;
+ service.post('testurl', {}).map((res: Response) => res.json()).toPromise().then(() => {
+ success = true;
+ }, (err: Error) => {
+ expect(err.message).toBe('error');
+ error = true;
+ });
+ setTimeout(() => {
+ expect(success).toBe(false, 'on success execute when it shouldnt have with promises');
+ expect(error).toBe(true, 'on error didnt execute with promises');
+ });
+ })
+ ));
+});
diff --git a/src/platform/http/interceptors/http-interceptor.service.ts b/src/platform/http/interceptors/http-interceptor.service.ts
new file mode 100644
index 0000000000..3cd4670260
--- /dev/null
+++ b/src/platform/http/interceptors/http-interceptor.service.ts
@@ -0,0 +1,151 @@
+import { Injectable, Type, Injector } from '@angular/core';
+import { Http, RequestOptionsArgs, Response, Request, RequestMethod } from '@angular/http';
+
+import { Observable } from 'rxjs/Observable';
+import { Subscriber } from 'rxjs/Subscriber';
+
+import { IHttpInterceptor } from './http-interceptor.interface';
+import { IHttpInterceptorMatcher } from './http-interceptor-matcher.interface';
+import { IHttpInterceptorMapping } from './http-interceptor-mapping.interface';
+
+export interface IHttpInterceptorConfig {
+ interceptor: Type;
+ paths: string[];
+}
+
+@Injectable()
+export class HttpInterceptorService {
+
+ private _requestInterceptors: IHttpInterceptorMapping[] = [];
+
+ constructor(private _http: Http,
+ private _injector: Injector,
+ private _httpInterceptorMatcher: IHttpInterceptorMatcher,
+ requestInterceptorConfigs: IHttpInterceptorConfig[]) {
+ requestInterceptorConfigs.forEach((config: IHttpInterceptorConfig) => {
+ this._requestInterceptors.push({
+ interceptor: _injector.get(config.interceptor),
+ paths: config.paths,
+ });
+ });
+ }
+
+ public delete(url: string, requestOptions: RequestOptionsArgs = {}): Observable {
+ requestOptions.url = url;
+ requestOptions.method = RequestMethod.Delete;
+ return this.request(url, requestOptions);
+ }
+
+ public get(url: string, requestOptions: RequestOptionsArgs = {}): Observable {
+ requestOptions.url = url;
+ requestOptions.method = RequestMethod.Get;
+ return this.request(url, requestOptions);
+ }
+
+ public head(url: string, requestOptions: RequestOptionsArgs = {}): Observable {
+ requestOptions.url = url;
+ requestOptions.method = RequestMethod.Head;
+ return this.request(url, requestOptions);
+ }
+
+ public patch(url: string, data: any, requestOptions: RequestOptionsArgs = {}): Observable {
+ requestOptions.url = url;
+ requestOptions.method = RequestMethod.Patch;
+ requestOptions.body = data;
+ return this.request(url, requestOptions);
+ }
+
+ public post(url: string, data: any, requestOptions: RequestOptionsArgs = {}): Observable {
+ requestOptions.url = url;
+ requestOptions.method = RequestMethod.Post;
+ requestOptions.body = data;
+ return this.request(url, requestOptions);
+ }
+
+ public put(url: string, data: any, requestOptions: RequestOptionsArgs = {}): Observable {
+ requestOptions.url = url;
+ requestOptions.method = RequestMethod.Put;
+ requestOptions.body = data;
+ return this.request(url, requestOptions);
+ }
+
+ public request(url: string | Request, requestOptions: RequestOptionsArgs = {}): Observable {
+ let requestUrl: string;
+ if (url instanceof Request) {
+ requestUrl = url.url ? url.url : requestOptions.url;
+ } else {
+ requestUrl = url;
+ }
+ if (!requestOptions.url) {
+ requestOptions.url = requestUrl;
+ }
+ let interceptors: IHttpInterceptor[] = this._requestInterceptors.filter((mapping: IHttpInterceptorMapping) => {
+ return this._httpInterceptorMatcher.matches(requestOptions, mapping);
+ }).map((mapping: IHttpInterceptorMapping) => {
+ return mapping.interceptor;
+ });
+ return this._setupRequest(url, requestOptions, interceptors);
+ }
+
+ private _setupRequest(url: string | Request,
+ requestOptions: RequestOptionsArgs,
+ interceptors: IHttpInterceptor[]): Observable {
+ try {
+ requestOptions = this._requestResolve(requestOptions, interceptors);
+ } catch (e) {
+ return new Observable((subscriber: Subscriber) => {
+ subscriber.error(e);
+ });
+ }
+ return new Observable((subscriber: Subscriber) => {
+ this._http.request(url, requestOptions)
+ .do((response: Response) => {
+ subscriber.next(this._responseResolve(response, interceptors));
+ subscriber.complete();
+ }).catch((error: Response) => {
+ return new Observable(() => {
+ subscriber.error(this._responseErrorResolve(error, interceptors));
+ });
+ }).subscribe();
+ });
+ }
+
+ private _requestResolve(requestOptions: RequestOptionsArgs, interceptors: IHttpInterceptor[]): RequestOptionsArgs {
+ interceptors.forEach((interceptor: IHttpInterceptor) => {
+ if (interceptor.onRequest) {
+ try {
+ requestOptions = interceptor.onRequest(requestOptions);
+ } catch (e) {
+ if (interceptor.onRequestError) {
+ requestOptions = interceptor.onRequestError(requestOptions);
+ if (!requestOptions) {
+ throw e;
+ }
+ } else {
+ throw e;
+ }
+ }
+ }
+ });
+ return requestOptions;
+ }
+
+ private _responseResolve(response: Response, interceptors: IHttpInterceptor[]): Response {
+ interceptors.forEach((interceptor: IHttpInterceptor) => {
+ if (interceptor.onResponse) {
+ response = interceptor.onResponse(response);
+ }
+ });
+ return response;
+ }
+
+ private _responseErrorResolve(error: Response, interceptors: IHttpInterceptor[]): Response {
+ interceptors.forEach((interceptor: IHttpInterceptor) => {
+ if (interceptor.onResponseError) {
+ error = interceptor.onResponseError(error);
+ }
+ });
+ return error;
+ }
+
+}
diff --git a/src/platform/http/interceptors/url-regexp-interceptor-matcher.class.spec.ts b/src/platform/http/interceptors/url-regexp-interceptor-matcher.class.spec.ts
new file mode 100644
index 0000000000..4487d44923
--- /dev/null
+++ b/src/platform/http/interceptors/url-regexp-interceptor-matcher.class.spec.ts
@@ -0,0 +1,147 @@
+import { URLRegExpInterceptorMatcher } from './url-regexp-interceptor-matcher.class';
+
+describe('Http: URLRegExpInterceptorMatcher', () => {
+ let matcher: URLRegExpInterceptorMatcher;
+
+ beforeEach(() => {
+ matcher = new URLRegExpInterceptorMatcher();
+ });
+
+ it('should match all URLs', () => {
+ expect(matcher.matches(
+ {url: 'www.google.com/path/1_1_-_1/ano111_ther/11-22?query=1&query=2'},
+ {interceptor: undefined, paths: ['**']}
+ )).toBeTruthy();
+ expect(matcher.matches(
+ {url: 'www.google.com/path/111/another/11-22'},
+ {interceptor: undefined, paths: ['**']}
+ )).toBeTruthy();
+ expect(matcher.matches(
+ {url: 'www.google.com/path'},
+ {interceptor: undefined, paths: ['**']}
+ )).toBeTruthy();
+ expect(matcher.matches(
+ {url: 'www.google.com?'},
+ {interceptor: undefined, paths: ['**']}
+ )).toBeTruthy();
+ expect(matcher.matches(
+ {url: 'www.google.com/path/1_1_-_1/?query=1&query=2'},
+ {interceptor: undefined, paths: ['**']}
+ )).toBeTruthy();
+ });
+
+ it('should match routes that contain with /apps or /sys', () => {
+ expect(matcher.matches(
+ {url: 'www.google.com/apps/1_1_-_1/ano111_ther/11-22?query=1&query=2'},
+ {interceptor: undefined, paths: ['/apps**', '/sys**']}
+ )).toBeTruthy();
+ expect(matcher.matches(
+ {url: 'www.google.com/path/111/sys/11-22'},
+ {interceptor: undefined, paths: ['/apps**', '/sys**']}
+ )).toBeTruthy();
+ expect(matcher.matches(
+ {url: 'www.google.com/apps'},
+ {interceptor: undefined, paths: ['/apps**', '/sys**']}
+ )).toBeTruthy();
+ expect(matcher.matches(
+ {url: 'www.google.com?'},
+ {interceptor: undefined, paths: ['/apps**', '/sys**']}
+ )).toBeFalsy();
+ expect(matcher.matches(
+ {url: 'www.google.com/path/1_1_-_1/?query=1&query=2'},
+ {interceptor: undefined, paths: ['/apps**', '/sys**']}
+ )).toBeFalsy();
+ });
+
+ it('should match routes that end with /apps', () => {
+ expect(matcher.matches(
+ {url: 'www.google.com/apps/1_1_-_1/ano111_ther/11-22?query=1&query=2'},
+ {interceptor: undefined, paths: ['/apps']}
+ )).toBeFalsy();
+ expect(matcher.matches(
+ {url: 'www.google.com/path/111/sys/11-22'},
+ {interceptor: undefined, paths: ['/apps']}
+ )).toBeFalsy();
+ expect(matcher.matches(
+ {url: 'www.google.com/apps'},
+ {interceptor: undefined, paths: ['/apps']}
+ )).toBeTruthy();
+ expect(matcher.matches(
+ {url: 'www.google.com?'},
+ {interceptor: undefined, paths: ['/apps']}
+ )).toBeFalsy();
+ expect(matcher.matches(
+ {url: 'www.google.com/path/1_1_-_1/?query=1&query=2'},
+ {interceptor: undefined, paths: ['/apps']}
+ )).toBeFalsy();
+ });
+
+ it('should match routes that end with /apps/* (only with extra path)', () => {
+ expect(matcher.matches(
+ {url: 'www.google.com/apps/1_1_-_1/ano111_ther/11-22?query=1&query=2'},
+ {interceptor: undefined, paths: ['/apps/*']}
+ )).toBeFalsy();
+ expect(matcher.matches(
+ {url: 'www.google.com/path/111/apps/11-22'},
+ {interceptor: undefined, paths: ['/apps/*']}
+ )).toBeTruthy();
+ expect(matcher.matches(
+ {url: 'www.google.com/apps'},
+ {interceptor: undefined, paths: ['/apps/*']}
+ )).toBeFalsy();
+ expect(matcher.matches(
+ {url: 'www.google.com?'},
+ {interceptor: undefined, paths: ['/apps/*']}
+ )).toBeFalsy();
+ expect(matcher.matches(
+ {url: 'www.google.com/path/1_1_-_1/?query=1&query=2'},
+ {interceptor: undefined, paths: ['/apps/*']}
+ )).toBeFalsy();
+ });
+
+ it('should match routes that end with /apps/*/path (only one path in the middle)', () => {
+ expect(matcher.matches(
+ {url: 'www.google.com/apps/1_1_-_1/path?query=1&query=2'},
+ {interceptor: undefined, paths: ['/apps/*/path']}
+ )).toBeTruthy();
+ expect(matcher.matches(
+ {url: 'www.google.com/apps/111/path/11-22'},
+ {interceptor: undefined, paths: ['/apps/*/path']}
+ )).toBeFalsy();
+ expect(matcher.matches(
+ {url: 'www.google.com/apps'},
+ {interceptor: undefined, paths: ['/apps/*/path']}
+ )).toBeFalsy();
+ expect(matcher.matches(
+ {url: 'www.google.com?'},
+ {interceptor: undefined, paths: ['/apps/*/path']}
+ )).toBeFalsy();
+ expect(matcher.matches(
+ {url: 'www.google.com/path/1_1_-_1/?query=1&query=2'},
+ {interceptor: undefined, paths: ['/apps/*/path']}
+ )).toBeFalsy();
+ });
+
+ it('should match routes that end with /apps/**/path (any number of paths in the middle)', () => {
+ expect(matcher.matches(
+ {url: 'www.google.com/apps/1_1_-_1/path?query=1&query=2'},
+ {interceptor: undefined, paths: ['/apps/**/path']}
+ )).toBeTruthy();
+ expect(matcher.matches(
+ {url: 'www.google.com/apps/111/122/path'},
+ {interceptor: undefined, paths: ['/apps/**/path']}
+ )).toBeTruthy();
+ expect(matcher.matches(
+ {url: 'www.google.com/apps'},
+ {interceptor: undefined, paths: ['/apps/**/path']}
+ )).toBeFalsy();
+ expect(matcher.matches(
+ {url: 'www.google.com?'},
+ {interceptor: undefined, paths: ['/apps/**/path']}
+ )).toBeFalsy();
+ expect(matcher.matches(
+ {url: 'www.google.com/path/1_1_-_1/?query=1&query=2'},
+ {interceptor: undefined, paths: ['/apps/**/path']}
+ )).toBeFalsy();
+ });
+});
diff --git a/src/platform/http/interceptors/url-regexp-interceptor-matcher.class.ts b/src/platform/http/interceptors/url-regexp-interceptor-matcher.class.ts
new file mode 100644
index 0000000000..1ef857a98e
--- /dev/null
+++ b/src/platform/http/interceptors/url-regexp-interceptor-matcher.class.ts
@@ -0,0 +1,25 @@
+import { RequestOptionsArgs } from '@angular/http';
+
+import { IHttpInterceptorMapping } from './http-interceptor-mapping.interface';
+import { IHttpInterceptorMatcher } from './http-interceptor-matcher.interface';
+
+/**
+ * Concrete implementation for http interceptor matchers.
+ * This implementation uses regex to check mapping paths vs request url.
+ */
+export class URLRegExpInterceptorMatcher implements IHttpInterceptorMatcher {
+
+ matches(options: RequestOptionsArgs, mapping: IHttpInterceptorMapping): boolean {
+ return mapping.paths.filter((path: string) => {
+ path = path.replace(/\*\*/gi, '<>')
+ .replace(/\*/gi, '[a-zA-Z0-9\\-_]+')
+ .replace(/<>/gi, '[a-zA-Z0-9\\-_\/]*');
+ if (path) {
+ path += '(\\?{1}.*)?$';
+ return new RegExp(path).test(options.url);
+ }
+ return false;
+ }).length > 0;
+ }
+
+}