MOBILE-2253 core: Implement HTTP interceptor for WS calls
parent
ab1d72780e
commit
a4adffe94d
|
@ -15,7 +15,7 @@
|
||||||
import { BrowserModule } from '@angular/platform-browser';
|
import { BrowserModule } from '@angular/platform-browser';
|
||||||
import { ErrorHandler, NgModule } from '@angular/core';
|
import { ErrorHandler, NgModule } from '@angular/core';
|
||||||
import { IonicApp, IonicErrorHandler, IonicModule, Platform } from 'ionic-angular';
|
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 { SplashScreen } from '@ionic-native/splash-screen';
|
||||||
import { StatusBar } from '@ionic-native/status-bar';
|
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 { TranslateHttpLoader } from '@ngx-translate/http-loader';
|
||||||
|
|
||||||
import { MyApp } from './app.component';
|
import { MyApp } from './app.component';
|
||||||
|
import { CoreInterceptor } from '../classes/interceptor';
|
||||||
import { CoreLoggerProvider } from '../providers/logger';
|
import { CoreLoggerProvider } from '../providers/logger';
|
||||||
import { CoreDbProvider } from '../providers/db';
|
import { CoreDbProvider } from '../providers/db';
|
||||||
import { CoreAppProvider } from '../providers/app';
|
import { CoreAppProvider } from '../providers/app';
|
||||||
|
@ -80,6 +81,11 @@ export function createTranslateLoader(http: HttpClient) {
|
||||||
MyApp
|
MyApp
|
||||||
],
|
],
|
||||||
providers: [
|
providers: [
|
||||||
|
{
|
||||||
|
provide: HTTP_INTERCEPTORS,
|
||||||
|
useClass: CoreInterceptor,
|
||||||
|
multi: true,
|
||||||
|
},
|
||||||
StatusBar,
|
StatusBar,
|
||||||
SplashScreen,
|
SplashScreen,
|
||||||
SQLite,
|
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;
|
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.:
|
* Stringify an object, sorting the properties. It doesn't sort arrays, only object properties. E.g.:
|
||||||
* {b: 2, a: 1} -> '{"a":1,"b":2}'
|
* {b: 2, a: 1} -> '{"a":1,"b":2}'
|
||||||
|
|
|
@ -24,6 +24,7 @@ import { CoreTextUtilsProvider } from './utils/text';
|
||||||
import { CoreUtilsProvider } from './utils/utils';
|
import { CoreUtilsProvider } from './utils/utils';
|
||||||
import { CoreConstants } from '../core/constants';
|
import { CoreConstants } from '../core/constants';
|
||||||
import { Md5 } from 'ts-md5/dist/md5';
|
import { Md5 } from 'ts-md5/dist/md5';
|
||||||
|
import { CoreInterceptor } from '../classes/interceptor';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Interface of the presets accepted by the WS call.
|
* 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 {
|
protected getQueueItemId(method: string, url: string, params?: any) : string {
|
||||||
if (params) {
|
if (params) {
|
||||||
url += '###' + this.utils.serialize(params);
|
url += '###' + CoreInterceptor.serialize(params);
|
||||||
}
|
}
|
||||||
return method + '#' + Md5.hashAsciiStr(url);
|
return method + '#' + Md5.hashAsciiStr(url);
|
||||||
}
|
}
|
||||||
|
@ -595,7 +596,7 @@ export class CoreWSProvider {
|
||||||
siteUrl = preSets.siteUrl + '/webservice/rest/server.php?moodlewsrestformat=json';
|
siteUrl = preSets.siteUrl + '/webservice/rest/server.php?moodlewsrestformat=json';
|
||||||
|
|
||||||
// Serialize data.
|
// Serialize data.
|
||||||
data = this.utils.serialize(data);
|
data = CoreInterceptor.serialize(data);
|
||||||
|
|
||||||
// Perform sync request using XMLHttpRequest.
|
// Perform sync request using XMLHttpRequest.
|
||||||
xhr = new (<any>window).XMLHttpRequest();
|
xhr = new (<any>window).XMLHttpRequest();
|
||||||
|
|
Loading…
Reference in New Issue