MOBILE-2253 core: Implement HTTP interceptor for WS calls
parent
ab1d72780e
commit
a4adffe94d
|
@ -15,7 +15,7 @@
|
|||
import { BrowserModule } from '@angular/platform-browser';
|
||||
import { ErrorHandler, NgModule } from '@angular/core';
|
||||
import { IonicApp, IonicErrorHandler, IonicModule, Platform } from 'ionic-angular';
|
||||
import { HttpClient, HttpClientModule } from '@angular/common/http';
|
||||
import { HttpClient, HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http';
|
||||
|
||||
import { SplashScreen } from '@ionic-native/splash-screen';
|
||||
import { StatusBar } from '@ionic-native/status-bar';
|
||||
|
@ -25,6 +25,7 @@ import { TranslateModule, TranslateLoader } from '@ngx-translate/core';
|
|||
import { TranslateHttpLoader } from '@ngx-translate/http-loader';
|
||||
|
||||
import { MyApp } from './app.component';
|
||||
import { CoreInterceptor } from '../classes/interceptor';
|
||||
import { CoreLoggerProvider } from '../providers/logger';
|
||||
import { CoreDbProvider } from '../providers/db';
|
||||
import { CoreAppProvider } from '../providers/app';
|
||||
|
@ -80,6 +81,11 @@ export function createTranslateLoader(http: HttpClient) {
|
|||
MyApp
|
||||
],
|
||||
providers: [
|
||||
{
|
||||
provide: HTTP_INTERCEPTORS,
|
||||
useClass: CoreInterceptor,
|
||||
multi: true,
|
||||
},
|
||||
StatusBar,
|
||||
SplashScreen,
|
||||
SQLite,
|
||||
|
|
|
@ -0,0 +1,79 @@
|
|||
// (C) Copyright 2015 Martin Dougiamas
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import { Injectable } from '@angular/core';
|
||||
import { HttpInterceptor, HttpHandler, HttpRequest } from '@angular/common/http';
|
||||
import { Observable } from 'rxjs';
|
||||
|
||||
/**
|
||||
* Interceptor for Http calls. Adds the header 'Content-Type'='application/x-www-form-urlencoded'
|
||||
* and serializes the parameters if needed.
|
||||
*/
|
||||
@Injectable()
|
||||
export class CoreInterceptor implements HttpInterceptor {
|
||||
|
||||
constructor() {}
|
||||
|
||||
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<any> {
|
||||
// Add the header and serialize the body if needed.
|
||||
const newReq = req.clone({
|
||||
headers: req.headers.set('Content-Type', 'application/x-www-form-urlencoded'),
|
||||
body: typeof req.body == 'object' && String(req.body) != '[object File]' ?
|
||||
CoreInterceptor.serialize(req.body) : req.body
|
||||
});
|
||||
|
||||
// Pass on the cloned request instead of the original request.
|
||||
return next.handle(newReq);
|
||||
}
|
||||
|
||||
/**
|
||||
* Serialize an object to be used in a request.
|
||||
*
|
||||
* @param {any} obj Object to serialize.
|
||||
* @param {boolean} [addNull] Add null values to the serialized as empty parameters.
|
||||
* @return {string} Serialization of the object.
|
||||
*/
|
||||
public static serialize(obj: any, addNull?: boolean) : string {
|
||||
let query = '',
|
||||
fullSubName,
|
||||
subValue,
|
||||
innerObj;
|
||||
|
||||
for (let name in obj) {
|
||||
let value = obj[name];
|
||||
|
||||
if (value instanceof Array) {
|
||||
for (let i = 0; i < value.length; ++i) {
|
||||
subValue = value[i];
|
||||
fullSubName = name + '[' + i + ']';
|
||||
innerObj = {};
|
||||
innerObj[fullSubName] = subValue;
|
||||
query += this.serialize(innerObj) + '&';
|
||||
}
|
||||
} else if (value instanceof Object) {
|
||||
for (let subName in value) {
|
||||
subValue = value[subName];
|
||||
fullSubName = name + '[' + subName + ']';
|
||||
innerObj = {};
|
||||
innerObj[fullSubName] = subValue;
|
||||
query += this.serialize(innerObj) + '&';
|
||||
}
|
||||
} else if (addNull || (typeof value != 'undefined' && value !== null)) {
|
||||
query += encodeURIComponent(name) + '=' + encodeURIComponent(value) + '&';
|
||||
}
|
||||
}
|
||||
|
||||
return query.length ? query.substr(0, query.length - 1) : query;
|
||||
}
|
||||
}
|
|
@ -1036,46 +1036,6 @@ export class CoreUtilsProvider {
|
|||
return value1 === value2;
|
||||
}
|
||||
|
||||
/**
|
||||
* Serialize an object to be used in a request.
|
||||
*
|
||||
* @param {any} obj Object to serialize.
|
||||
* @param {boolean} [addNull] Add null values to the serialized as empty parameters.
|
||||
* @return {string} Serialization of the object.
|
||||
*/
|
||||
serialize(obj: any, addNull?: boolean) : string {
|
||||
let query = '',
|
||||
fullSubName,
|
||||
subValue,
|
||||
innerObj;
|
||||
|
||||
for (let name in obj) {
|
||||
let value = obj[name];
|
||||
|
||||
if (value instanceof Array) {
|
||||
for (let i = 0; i < value.length; ++i) {
|
||||
subValue = value[i];
|
||||
fullSubName = name + '[' + i + ']';
|
||||
innerObj = {};
|
||||
innerObj[fullSubName] = subValue;
|
||||
query += this.serialize(innerObj) + '&';
|
||||
}
|
||||
} else if (value instanceof Object) {
|
||||
for (let subName in value) {
|
||||
subValue = value[subName];
|
||||
fullSubName = name + '[' + subName + ']';
|
||||
innerObj = {};
|
||||
innerObj[fullSubName] = subValue;
|
||||
query += this.serialize(innerObj) + '&';
|
||||
}
|
||||
} else if (addNull || (typeof value != 'undefined' && value !== null)) {
|
||||
query += encodeURIComponent(name) + '=' + encodeURIComponent(value) + '&';
|
||||
}
|
||||
}
|
||||
|
||||
return query.length ? query.substr(0, query.length - 1) : query;
|
||||
}
|
||||
|
||||
/**
|
||||
* Stringify an object, sorting the properties. It doesn't sort arrays, only object properties. E.g.:
|
||||
* {b: 2, a: 1} -> '{"a":1,"b":2}'
|
||||
|
|
|
@ -24,6 +24,7 @@ import { CoreTextUtilsProvider } from './utils/text';
|
|||
import { CoreUtilsProvider } from './utils/utils';
|
||||
import { CoreConstants } from '../core/constants';
|
||||
import { Md5 } from 'ts-md5/dist/md5';
|
||||
import { CoreInterceptor } from '../classes/interceptor';
|
||||
|
||||
/**
|
||||
* Interface of the presets accepted by the WS call.
|
||||
|
@ -416,7 +417,7 @@ export class CoreWSProvider {
|
|||
*/
|
||||
protected getQueueItemId(method: string, url: string, params?: any) : string {
|
||||
if (params) {
|
||||
url += '###' + this.utils.serialize(params);
|
||||
url += '###' + CoreInterceptor.serialize(params);
|
||||
}
|
||||
return method + '#' + Md5.hashAsciiStr(url);
|
||||
}
|
||||
|
@ -595,7 +596,7 @@ export class CoreWSProvider {
|
|||
siteUrl = preSets.siteUrl + '/webservice/rest/server.php?moodlewsrestformat=json';
|
||||
|
||||
// Serialize data.
|
||||
data = this.utils.serialize(data);
|
||||
data = CoreInterceptor.serialize(data);
|
||||
|
||||
// Perform sync request using XMLHttpRequest.
|
||||
xhr = new (<any>window).XMLHttpRequest();
|
||||
|
|
Loading…
Reference in New Issue