Compare commits

..
9 Commits
Author SHA1 Message Date
Sefa Ilkimen af239d3194 release v1.11.0 2018-03-02 01:09:23 +01:00
Sefa Ilkimen 291e8fe547 browser: fix content type header 2018-03-02 01:00:22 +01:00
Sefa Ilkimen 8b3466e3c3 - update readme
- update version number
2018-03-02 00:46:01 +01:00
Sefa Ilkimen 73e76f6333 feature #11: implement support for "browser" platform 2018-03-01 23:45:54 +01:00
Sefa Ilkimen 3fcac64597 update OkHttp dependency 2018-03-01 16:16:02 +01:00
Sefa Ilkimen 4a437f9435 fix docu for "disableRedirect" 2018-02-28 04:08:32 +01:00
Sefa Ilkimen 2d15b86cb5 add documentation for feature #77 2018-02-28 04:05:13 +01:00
Sefa Ilkimen 63d859ad54 - implement all HTTP operations as shorthand functions of "sendRequest"
- add some more type checking
2018-02-28 03:24:27 +01:00
Sefa Ilkimen 6b9ed72b9f WIP: new API which allows overriding global options 2018-02-28 01:31:35 +01:00
13 changed files with 482 additions and 270 deletions
+5
View File
@@ -1,5 +1,10 @@
# Changelog
## 1.11.0
- Feature #77: allow overriding global settings for each single request
- Feature #11: add support for "browser" platform
## 1.10.2
- Fixed #78: overriding header "Content-Type" not working on Android
+69 -16
View File
@@ -6,7 +6,8 @@ Cordova Advanced HTTP
[![Build Status](https://travis-ci.org/silkimen/cordova-plugin-advanced-http.svg?branch=master)](https://travis-ci.org/silkimen/cordova-plugin-advanced-http)
Cordova / Phonegap plugin for communicating with HTTP servers. Supports iOS and Android.
Cordova / Phonegap plugin for communicating with HTTP servers. Supports iOS, Android and [Browser](#browserSupport).
This is a fork of [Wymsee's Cordova-HTTP plugin](https://github.com/wymsee/cordova-HTTP).
## Advantages over Javascript requests
@@ -93,14 +94,7 @@ cordova.plugin.http.setHeader('www.example.com', 'Header', 'Value');
cordova.plugin.http.setHeader('www.example.com:8080', 'Header', 'Value');
```
### disableRedirect
If set to `true`, it won't follow redirects automatically. This is a global setting.
```js
cordova.plugin.http.disableRedirect(true);
```
### setDataSerializer
### setDataSerializer<a name="setDataSerializer"></a>
Set the data serializer which will be used for all future PATCH, POST and PUT requests. Takes a string representing the name of the serializer.
```js
@@ -173,6 +167,17 @@ cordova.plugin.http.acceptAllCerts(true, function() {
});
```
### disableRedirect
If set to `true`, it won't follow redirects automatically. This defaults to false.
```js
cordova.plugin.http.disableRedirect(true, function() {
console.log('success!');
}, function() {
console.log('error :(');
});
```
### validateDomainName
This function was removed in v1.6.2. Domain name validation is disabled automatically when you enable "acceptAllCerts".
@@ -183,6 +188,42 @@ Remove all cookies associated with a given URL.
cordova.plugin.http.removeCookies(url, callback);
```
### sendRequest
Execute a HTTP request. Takes a URL and an options object. This is the internally used implementation of the following shorthand functions ([post](#post), [get](#get), [put](#put), [patch](#patch), [delete](#delete), [head](#head), [uploadFile](#uploadFile) and [downloadFile](#downloadFile)). You can use this function, if you want to override global settings for each single request.
The options object contains following keys:
* `method`: HTTP method to be used, defaults to `get`, needs to be one of the following values:
* `get`, `post`, `put`, `patch`, `head`, `delete`, `upload`, `download`
* `data`: payload to be send to the server (only applicable on `post`, `put` or `patch` methods)
* `params`: query params to be appended to the URL (only applicable on `get`, `head`, `delete`, `upload` or `download` methods)
* `serializer`: data serializer to be used (only applicable on `post`, `put` or `patch` methods), defaults to global serializer value, see [setDataSerializer](#setDataSerializer) for supported values
* `timeout`: timeout value for the request in seconds, defaults to global timeout value
* `headers`: headers object (key value pair), will be merged with global values
* `filePath`: filePath to be used during upload and download see [uploadFile](#uploadFile) and [downloadFile](#downloadFile) for detailed information
* `name`: name to be used during upload see [uploadFile](#uploadFile) for detailed information
Here's a quick example:
```js
const options = {
method: 'post',
data: { id: 12, message: 'test' },
headers: { Authorization: 'OAuth2: token' }
};
cordova.plugin.http.sendRequest('https://google.com/', options, function(response) {
// prints 200
console.log(response.status);
}, function(response) {
// prints 403
console.log(response.status);
//prints Permission denied
console.log(response.error);
});
```
### post<a name="post"></a>
Execute a POST request. Takes a URL, data, and headers.
@@ -241,7 +282,7 @@ Here's a quick example:
}
```
### get
### get<a name="get"></a>
Execute a GET request. Takes a URL, parameters, and headers. See the [post](#post) documentation for details on what is returned on success and failure.
```js
@@ -255,19 +296,19 @@ cordova.plugin.http.get('https://google.com/', {
});
```
### put
### put<a name="put"></a>
Execute a PUT request. Takes a URL, data, and headers. See the [post](#post) documentation for details on what is returned on success and failure.
### patch
### patch<a name="patch"></a>
Execute a PATCH request. Takes a URL, data, and headers. See the [post](#post) documentation for details on what is returned on success and failure.
### delete
### delete<a name="delete"></a>
Execute a DELETE request. Takes a URL, parameters, and headers. See the [post](#post) documentation for details on what is returned on success and failure.
### head
### head<a name="head"></a>
Execute a HEAD request. Takes a URL, parameters, and headers. See the [post](#post) documentation for details on what is returned on success and failure.
### uploadFile
### uploadFile<a name="uploadFile"></a>
Uploads a file saved on the device. Takes a URL, parameters, headers, filePath, and the name of the parameter to pass the file along as. See the [post](#post) documentation for details on what is returned on success and failure.
```js
@@ -281,7 +322,7 @@ cordova.plugin.http.uploadFile("https://google.com/", {
});
```
### downloadFile
### downloadFile<a name="downloadFile"></a>
Downloads a file and saves it to the device. Takes a URL, parameters, headers, and a filePath. See [post](#post) documentation for details on what is returned on failure. On success this function returns a cordova [FileEntry object](http://cordova.apache.org/docs/en/3.3.0/cordova_file_file.md.html#FileEntry).
```js
@@ -299,6 +340,18 @@ cordova.plugin.http.downloadFile("https://google.com/", {
});
```
## Browser support<a name="browserSupport"></a>
This plugin supports a very restricted set of functions on the browser platform.
It's meant for testing purposes, not for production grade usage.
Following features are *not* supported:
* Manipulating Cookies
* Uploading and Downloading files
* Pinning SSL certificate
* Disabling SSL certificate check
* Disabling transparently following redirects (HTTP codes 3xx)
## Libraries
+2 -1
View File
@@ -1,8 +1,9 @@
{
"name": "cordova-plugin-advanced-http",
"version": "1.10.2",
"version": "1.11.0",
"description": "Cordova / Phonegap plugin for communicating with HTTP servers using SSL pinning",
"scripts": {
"buildbrowser": "./scripts/build-test-app.sh --browser",
"testandroid": "./scripts/build-test-app.sh --android --emulator && ./scripts/test-app.sh --android --emulator",
"testios": "./scripts/build-test-app.sh --ios --emulator && ./scripts/test-app.sh --ios --emulator",
"testapp": "npm run testandroid && npm run testios",
+12 -2
View File
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<plugin xmlns="http://www.phonegap.com/ns/plugins/1.0" xmlns:android="http://schemas.android.com/apk/res/android" id="cordova-plugin-advanced-http" version="1.10.2">
<plugin xmlns="http://www.phonegap.com/ns/plugins/1.0" xmlns:android="http://schemas.android.com/apk/res/android" id="cordova-plugin-advanced-http" version="1.11.0">
<name>Advanced HTTP plugin</name>
<description>
Cordova / Phonegap plugin for communicating with HTTP servers using SSL pinning
@@ -68,6 +68,16 @@
<source-file src="src/android/com/synconset/cordovahttp/CordovaHttpPut.java" target-dir="src/com/synconset/cordovahttp"/>
<source-file src="src/android/com/synconset/cordovahttp/CordovaHttpPatch.java" target-dir="src/com/synconset/cordovahttp"/>
<source-file src="src/android/com/synconset/cordovahttp/CordovaHttpUpload.java" target-dir="src/com/synconset/cordovahttp"/>
<framework src="com.squareup.okhttp3:okhttp-urlconnection:3.9.1"/>
<framework src="com.squareup.okhttp3:okhttp-urlconnection:3.10.0"/>
</platform>
<platform name="browser">
<config-file target="config.xml" parent="/*">
<feature name="CordovaHttpPlugin">
<param name="browser-package" value="CordovaHttpPlugin"/>
</feature>
</config-file>
<js-module src="src/browser/cordova-http-plugin.js" name="http-proxy">
<runs/>
</js-module>
</platform>
</plugin>
+30 -2
View File
@@ -1,11 +1,39 @@
#!/usr/bin/env bash
set -e
PLATFORM=$([[ "${@#--android}" = "$@" ]] && echo "ios" || echo "android")
TARGET=$([[ "${@#--device}" = "$@" ]] && echo "emulator" || echo "device")
ROOT="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"/..
CDV=$ROOT/node_modules/.bin/cordova
PLATFORM=ios
TARGET=emulator
while :; do
case $1 in
--android)
PLATFORM=android
;;
--browser)
PLATFORM=browser
;;
--ios)
PLATFORM=ios
;;
--device)
TARGET=device
;;
--emulator)
TARGET=emulator
;;
-?*)
printf 'WARN: Unknown option (ignored): %s\n' "$1" >&2
;;
*)
break
esac
shift
done
rm -rf $ROOT/temp
mkdir $ROOT/temp
cp -r $ROOT/test/app-template/ $ROOT/temp/
+166
View File
@@ -0,0 +1,166 @@
var pluginId = module.id.slice(0, module.id.lastIndexOf('.'));
var cordovaProxy = require('cordova/exec/proxy');
var helpers = require(pluginId + '.helpers');
function serializeJsonData(data) {
try {
return JSON.stringify(data);
} catch (err) {
return null;
}
}
function serializePrimitive(key, value) {
if (value === null || value === undefined) {
return encodeURIComponent(key) + '=';
}
return encodeURIComponent(key) + '=' + encodeURIComponent(value);
}
function serializeArray(key, values) {
return values.map(function(value) {
return encodeURIComponent(key) + '[]=' + encodeURIComponent(value);
}).join('&');
}
function serializeParams(params) {
if (params === null) return '';
return Object.keys(params).map(function(key) {
if (helpers.getTypeOf(params[key]) === 'Array') {
return serializeArray(key, params[key]);
}
return serializePrimitive(key, params[key]);
}).join('&');
}
function createXhrSuccessObject(xhr) {
return {
url: xhr.responseURL,
status: xhr.status,
data: helpers.getTypeOf(xhr.responseText) === 'String' ? xhr.responseText : xhr.response,
headers: xhr.getAllResponseHeaders()
};
}
function createXhrFailureObject(xhr) {
var obj = {};
obj.headers = xhr.getAllResponseHeaders();
obj.error = helpers.getTypeOf(xhr.responseText) === 'String' ? xhr.responseText : xhr.response;
obj.error = obj.error || 'advanced-http: please check browser console for error messages';
if (xhr.responseURL) obj.url = xhr.responseURL;
if (xhr.status) obj.status = xhr.status;
return obj;
}
function setHeaders(xhr, headers) {
Object.keys(headers).forEach(function(key) {
if (key === 'Cookie') return;
xhr.setRequestHeader(key, headers[key]);
});
}
function sendRequest(method, withData, opts, success, failure) {
var data = withData ? opts[1] : null;
var params = withData ? null : serializeParams(opts[1]);
var serializer = withData ? opts[2] : null;
var headers = withData ? opts[3] : opts[2];
var timeout = withData ? opts[4] : opts[3];
var url = params ? opts[0] + '?' + params : opts[0];
var processedData = null;
var xhr = new XMLHttpRequest();
xhr.open(method, url);
if (headers.Cookie && headers.Cookie.length > 0) {
return failure('advanced-http: custom cookies not supported on browser platform');
}
switch (serializer) {
case 'json':
xhr.setRequestHeader('Content-Type', 'application/json; charset=utf8');
processedData = serializeJsonData(data);
if (processedData === null) {
return failure('advanced-http: failed serializing data');
}
break;
case 'utf8':
xhr.setRequestHeader('Content-Type', 'text/plain; charset=utf8');
processedData = data.text;
break;
case 'urlencoded':
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
processedData = serializeParams(data);
break;
}
xhr.timeout = timeout * 1000;
setHeaders(xhr, headers);
xhr.onerror = xhr.ontimeout = function () {
return failure(createXhrFailureObject(xhr));
};
xhr.onload = function () {
if (xhr.readyState !== xhr.DONE) return;
if (xhr.status < 200 || xhr.status > 299) {
return failure(createXhrFailureObject(xhr));
}
return success(createXhrSuccessObject(xhr));
};
xhr.send(processedData);
}
var browserInterface = {
post: function (success, failure, opts) {
return sendRequest('post', true, opts, success, failure);
},
get: function (success, failure, opts) {
return sendRequest('get', false, opts, success, failure);
},
put: function (success, failure, opts) {
return sendRequest('put', true, opts, success, failure);
},
patch: function (success, failure, opts) {
return sendRequest('patch', true, opts, success, failure);
},
delete: function (success, failure, opts) {
return sendRequest('delete', false, opts, success, failure);
},
head: function (success, failure, opts) {
return sendRequest('head', false, opts, success, failure);
},
uploadFile: function (success, failure, opts) {
return failure('advanced-http: function "uploadFile" not supported on browser platform');
},
downloadFile: function (success, failure, opts) {
return failure('advanced-http: function "downloadFile" not supported on browser platform');
},
enableSSLPinning: function (success, failure, opts) {
return failure('advanced-http: function "enableSSLPinning" not supported on browser platform');
},
acceptAllCerts: function (success, failure, opts) {
return failure('advanced-http: function "acceptAllCerts" not supported on browser platform');
},
disableRedirect: function (success, failure, opts) {
return failure('advanced-http: function "disableRedirect" not supported on browser platform');
}
};
module.exports = browserInterface;
cordovaProxy.add('CordovaHttpPlugin', browserInterface);
+1
View File
@@ -23,6 +23,7 @@
<allow-intent href="itms-apps:*" />
</platform>
<engine name="android" spec="6.2.3" />
<engine name="browser" spec="5.0.0" />
<engine name="ios" spec="4.4.0" />
<plugin name="cordova-plugin-file" spec="4.3.3" />
</widget>
+1 -1
View File
@@ -1,7 +1,7 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Security-Policy" content="default-src 'self' data: gap: https://ssl.gstatic.com 'unsafe-eval'; style-src 'self' 'unsafe-inline'; media-src *; img-src 'self' data: content:;">
<meta http-equiv="Content-Security-Policy" content="default-src 'self' data: gap: https://ssl.gstatic.com https://self-signed.badssl.com http://httpbin.org http://www.columbia.edu 'unsafe-eval'; style-src 'self' 'unsafe-inline'; media-src *; img-src 'self' data: content:;">
<meta name="format-detection" content="telephone=no">
<meta name="msapplication-tap-highlight" content="no">
<meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width">
+4 -4
View File
@@ -288,14 +288,14 @@ const tests = [
.should.be.equal('http://httpbin.org/get?myArray[]=val1&myArray[]=val2&myArray[]=val3&myString=testString');
}
},{
description: 'should reject non-string values in local header object #54',
expected: 'rejected: {"status": 0, "error": "advanced-http: header values must be strings" ...',
description: 'should throw on non-string values in local header object #54',
expected: 'throwed: {"message": "advanced-http: header values must be strings"}',
func: function(resolve, reject) {
cordova.plugin.http.get('http://httpbin.org/get', {}, { myTestHeader: 1 }, resolve, reject);
},
validationFunc: function(driver, result) {
result.type.should.be.equal('rejected');
result.data.error.should.be.equal('advanced-http: header values must be strings');
result.type.should.be.equal('throwed');
result.message.should.be.equal('advanced-http: header values must be strings');
}
},{
description: 'should throw an error while setting non-string value as global header #54',
-1
View File
@@ -27,7 +27,6 @@ describe('Advanced HTTP www interface', function() {
mock('cordova/exec', noop);
mock(`${PLUGIN_ID}.cookie-handler`, {});
mock(`${HELPERS_ID}.cookie-handler`, {});
mock(`${PLUGIN_ID}.messages`, require('../www/messages'));
mock(`${HELPERS_ID}.messages`, require('../www/messages'));
mock(`${PLUGIN_ID}.angular-integration`, { registerService: noop });
+111 -218
View File
@@ -1,30 +1,5 @@
/*global angular*/
/*
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.
*
* Modified by Andrew Stephan for Sync OnSet
* Modified by Sefa Ilkimen
*/
/*
* An HTTP Plugin for PhoneGap.
* A native HTTP Plugin for Cordova / PhoneGap.
*/
var pluginId = module.id.slice(0, module.id.lastIndexOf('.'));
@@ -33,206 +8,124 @@ var exec = require('cordova/exec');
var angularIntegration = require(pluginId +'.angular-integration');
var cookieHandler = require(pluginId + '.cookie-handler');
var helpers = require(pluginId + '.helpers');
var messages = require(pluginId + '.messages');
var internals = {
var globalConfigs = {
headers: {},
dataSerializer: 'urlencoded',
timeoutInSeconds: 60.0,
serializer: 'urlencoded',
timeout: 60.0,
};
var publicInterface = {
getBasicAuthHeader: function (username, password) {
return {'Authorization': 'Basic ' + helpers.b64EncodeUnicode(username + ':' + password)};
},
useBasicAuth: function (username, password) {
this.setHeader('*', 'Authorization', 'Basic ' + helpers.b64EncodeUnicode(username + ':' + password));
},
getHeaders: function (host) {
return internals.headers[host || '*'] || null;
},
setHeader: function () {
// this one is for being backward compatible
var host = '*';
var header = arguments[0];
var value = arguments[1];
getBasicAuthHeader: function (username, password) {
return {'Authorization': 'Basic ' + helpers.b64EncodeUnicode(username + ':' + password)};
},
useBasicAuth: function (username, password) {
this.setHeader('*', 'Authorization', 'Basic ' + helpers.b64EncodeUnicode(username + ':' + password));
},
getHeaders: function (host) {
return globalConfigs.headers[host || '*'] || null;
},
setHeader: function () {
// this one is for being backward compatible
var host = '*';
var header = arguments[0];
var value = arguments[1];
if (arguments.length === 3) {
host = arguments[0];
header = arguments[1];
value = arguments[2];
}
if (header.toLowerCase() === 'cookie') {
throw new Error(messages.ADDING_COOKIES_NOT_SUPPORTED);
}
if (helpers.getTypeOf(value) !== 'String') {
throw new Error(messages.HEADER_VALUE_MUST_BE_STRING);
}
internals.headers[host] = internals.headers[host] || {};
internals.headers[host][header] = value;
},
getDataSerializer: function () {
return internals.dataSerializer;
},
setDataSerializer: function (serializer) {
internals.dataSerializer = helpers.checkSerializer(serializer);
},
setCookie: function (url, cookie, options) {
cookieHandler.setCookie(url, cookie, options);
},
clearCookies: function () {
cookieHandler.clearCookies();
},
removeCookies: function (url, callback) {
cookieHandler.removeCookies(url, callback);
},
getCookieString: function (url) {
return cookieHandler.getCookieString(url);
},
getRequestTimeout: function () {
return internals.timeoutInSeconds;
},
setRequestTimeout: function (timeout) {
internals.timeoutInSeconds = timeout;
},
enableSSLPinning: function (enable, success, failure) {
return exec(success, failure, 'CordovaHttpPlugin', 'enableSSLPinning', [enable]);
},
acceptAllCerts: function (allow, success, failure) {
return exec(success, failure, 'CordovaHttpPlugin', 'acceptAllCerts', [allow]);
},
disableRedirect: function (disable, success, failure) {
return exec(success, failure, 'CordovaHttpPlugin', 'disableRedirect', [disable]);
},
validateDomainName: function (validate, success, failure) {
failure(messages.DEPRECATED_VDN);
},
post: function (url, data, headers, success, failure) {
helpers.handleMissingCallbacks(success, failure);
data = helpers.getProcessedData(data, internals.dataSerializer);
headers = helpers.getMergedHeaders(url, headers, internals.headers);
if (!helpers.checkHeaders(headers)) {
return helpers.onInvalidHeader(failure);
}
var onSuccess = helpers.injectCookieHandler(url, success);
var onFail = helpers.injectCookieHandler(url, failure);
return exec(onSuccess, onFail, 'CordovaHttpPlugin', 'post', [url, data, internals.dataSerializer, headers, internals.timeoutInSeconds]);
},
get: function (url, params, headers, success, failure) {
helpers.handleMissingCallbacks(success, failure);
params = params || {};
headers = helpers.getMergedHeaders(url, headers, internals.headers);
if (!helpers.checkHeaders(headers)) {
return helpers.onInvalidHeader(failure);
}
var onSuccess = helpers.injectCookieHandler(url, success);
var onFail = helpers.injectCookieHandler(url, failure);
return exec(onSuccess, onFail, 'CordovaHttpPlugin', 'get', [url, params, headers, internals.timeoutInSeconds]);
},
put: function (url, data, headers, success, failure) {
helpers.handleMissingCallbacks(success, failure);
data = helpers.getProcessedData(data, internals.dataSerializer);
headers = helpers.getMergedHeaders(url, headers, internals.headers);
if (!helpers.checkHeaders(headers)) {
return helpers.onInvalidHeader(failure);
}
var onSuccess = helpers.injectCookieHandler(url, success);
var onFail = helpers.injectCookieHandler(url, failure);
return exec(onSuccess, onFail, 'CordovaHttpPlugin', 'put', [url, data, internals.dataSerializer, headers, internals.timeoutInSeconds]);
},
patch: function (url, data, headers, success, failure) {
helpers.handleMissingCallbacks(success, failure);
data = helpers.getProcessedData(data, internals.dataSerializer);
headers = helpers.getMergedHeaders(url, headers, internals.headers);
if (!helpers.checkHeaders(headers)) {
return helpers.onInvalidHeader(failure);
}
var onSuccess = helpers.injectCookieHandler(url, success);
var onFail = helpers.injectCookieHandler(url, failure);
return exec(onSuccess, onFail, 'CordovaHttpPlugin', 'patch', [url, data, internals.dataSerializer, headers, internals.timeoutInSeconds]);
},
delete: function (url, params, headers, success, failure) {
helpers.handleMissingCallbacks(success, failure);
params = params || {};
headers = helpers.getMergedHeaders(url, headers, internals.headers);
if (!helpers.checkHeaders(headers)) {
return helpers.onInvalidHeader(failure);
}
var onSuccess = helpers.injectCookieHandler(url, success);
var onFail = helpers.injectCookieHandler(url, failure);
return exec(onSuccess, onFail, 'CordovaHttpPlugin', 'delete', [url, params, headers, internals.timeoutInSeconds]);
},
head: function (url, params, headers, success, failure) {
helpers.handleMissingCallbacks(success, failure);
params = params || {};
headers = helpers.getMergedHeaders(url, headers, internals.headers);
if (!helpers.checkHeaders(headers)) {
return helpers.onInvalidHeader(failure);
}
var onSuccess = helpers.injectCookieHandler(url, success);
var onFail = helpers.injectCookieHandler(url, failure);
return exec(onSuccess, onFail, 'CordovaHttpPlugin', 'head', [url, params, headers, internals.timeoutInSeconds]);
},
uploadFile: function (url, params, headers, filePath, name, success, failure) {
helpers.handleMissingCallbacks(success, failure);
params = params || {};
headers = helpers.getMergedHeaders(url, headers, internals.headers);
if (!helpers.checkHeaders(headers)) {
return helpers.onInvalidHeader(failure);
}
var onSuccess = helpers.injectCookieHandler(url, success);
var onFail = helpers.injectCookieHandler(url, failure);
return exec(onSuccess, onFail, 'CordovaHttpPlugin', 'uploadFile', [url, params, headers, filePath, name, internals.timeoutInSeconds]);
},
downloadFile: function (url, params, headers, filePath, success, failure) {
helpers.handleMissingCallbacks(success, failure);
params = params || {};
headers = helpers.getMergedHeaders(url, headers, internals.headers);
if (!helpers.checkHeaders(headers)) {
return helpers.onInvalidHeader(failure);
}
var onSuccess = helpers.injectCookieHandler(url, helpers.injectFileEntryHandler(success));
var onFail = helpers.injectCookieHandler(url, failure);
return exec(onSuccess, onFail, 'CordovaHttpPlugin', 'downloadFile', [url, params, headers, filePath, internals.timeoutInSeconds]);
if (arguments.length === 3) {
host = arguments[0];
header = arguments[1];
value = arguments[2];
}
helpers.checkForBlacklistedHeaderKey(header);
helpers.checkForInvalidHeaderValue(value);
globalConfigs.headers[host] = globalConfigs.headers[host] || {};
globalConfigs.headers[host][header] = value;
},
getDataSerializer: function () {
return globalConfigs.serializer;
},
setDataSerializer: function (serializer) {
globalConfigs.serializer = helpers.checkSerializer(serializer);
},
setCookie: function (url, cookie, options) {
cookieHandler.setCookie(url, cookie, options);
},
clearCookies: function () {
cookieHandler.clearCookies();
},
removeCookies: function (url, callback) {
cookieHandler.removeCookies(url, callback);
},
getCookieString: function (url) {
return cookieHandler.getCookieString(url);
},
getRequestTimeout: function () {
return globalConfigs.timeout;
},
setRequestTimeout: function (timeout) {
globalConfigs.timeout = timeout;
},
enableSSLPinning: function (enable, success, failure) {
return exec(success, failure, 'CordovaHttpPlugin', 'enableSSLPinning', [ enable ]);
},
acceptAllCerts: function (allow, success, failure) {
return exec(success, failure, 'CordovaHttpPlugin', 'acceptAllCerts', [ allow ]);
},
disableRedirect: function (disable, success, failure) {
return exec(success, failure, 'CordovaHttpPlugin', 'disableRedirect', [ disable ]);
},
sendRequest: function (url, options, success, failure) {
helpers.handleMissingCallbacks(success, failure);
options = helpers.handleMissingOptions(options, globalConfigs);
var headers = helpers.getMergedHeaders(url, options.headers, globalConfigs.headers);
var onSuccess = helpers.injectCookieHandler(url, success);
var onFail = helpers.injectCookieHandler(url, failure);
switch(options.method) {
case 'post':
case 'put':
case 'patch':
var data = helpers.getProcessedData(options.data, options.serializer);
return exec(onSuccess, onFail, 'CordovaHttpPlugin', options.method, [ url, data, options.serializer, headers, options.timeout ]);
case 'upload':
return exec(onSuccess, onFail, 'CordovaHttpPlugin', 'uploadFile', [ url, options.params, headers, options.filePath, options.name, options.timeout ]);
case 'download':
var onDownloadSuccess = helpers.injectCookieHandler(url, helpers.injectFileEntryHandler(success));
return exec(onDownloadSuccess, onFail, 'CordovaHttpPlugin', 'downloadFile', [ url, options.params, headers, options.filePath, options.timeout ]);
default:
return exec(onSuccess, onFail, 'CordovaHttpPlugin', options.method, [ url, options.params, headers, options.timeout ]);
}
},
post: function (url, data, headers, success, failure) {
return publicInterface.sendRequest(url, { method: 'post', data: data, headers: headers }, success, failure);
},
get: function (url, params, headers, success, failure) {
return publicInterface.sendRequest(url, { method: 'get', params: params, headers: headers }, success, failure);
},
put: function (url, data, headers, success, failure) {
return publicInterface.sendRequest(url, { method: 'put', data: data, headers: headers }, success, failure);
},
patch: function (url, data, headers, success, failure) {
return publicInterface.sendRequest(url, { method: 'patch', data: data, headers: headers }, success, failure);
},
delete: function (url, params, headers, success, failure) {
return publicInterface.sendRequest(url, { method: 'delete', params: params, headers: headers }, success, failure);
},
head: function (url, params, headers, success, failure) {
return publicInterface.sendRequest(url, { method: 'head', params: params, headers: headers }, success, failure);
},
uploadFile: function (url, params, headers, filePath, name, success, failure) {
return publicInterface.sendRequest(url, { method: 'upload', params: params, headers: headers, filePath: filePath, name: name }, success, failure);
},
downloadFile: function (url, params, headers, filePath, success, failure) {
return publicInterface.sendRequest(url, { method: 'download', params: params, headers: headers, filePath: filePath }, success, failure);
}
};
// angular service is deprecated and will be removed anytime soon
angularIntegration.registerService(publicInterface);
module.exports = publicInterface;
+75 -22
View File
@@ -3,18 +3,20 @@ var cookieHandler = require(pluginId + '.cookie-handler');
var messages = require(pluginId + '.messages');
var validSerializers = [ 'urlencoded', 'json', 'utf8' ];
var validHttpMethods = [ 'get', 'put', 'post', 'patch', 'head', 'delete', 'upload', 'download' ];
module.exports = {
b64EncodeUnicode: b64EncodeUnicode,
getTypeOf: getTypeOf,
checkHeaders: checkHeaders,
onInvalidHeader: onInvalidHeader,
checkSerializer: checkSerializer,
checkForBlacklistedHeaderKey: checkForBlacklistedHeaderKey,
checkForInvalidHeaderValue: checkForInvalidHeaderValue,
injectCookieHandler: injectCookieHandler,
injectFileEntryHandler: injectFileEntryHandler,
getMergedHeaders: getMergedHeaders,
getProcessedData: getProcessedData,
handleMissingCallbacks: handleMissingCallbacks
handleMissingCallbacks: handleMissingCallbacks,
handleMissingOptions: handleMissingOptions
};
// Thanks Mozilla: https://developer.mozilla.org/en-US/docs/Web/API/WindowBase64/Base64_encoding_and_decoding#The_.22Unicode_Problem.22
@@ -39,38 +41,74 @@ function mergeHeaders(globalHeaders, localHeaders) {
return localHeaders;
}
function checkHeaders(headers) {
var keys = Object.keys(headers);
var key;
function checkForValidStringValue(list, value, onInvalidValueMessage) {
if (getTypeOf(value) !== 'String') {
throw new Error(onInvalidValueMessage + ' ' + list.join(', '));
}
value = value.trim().toLowerCase();
if (list.indexOf(value) === -1) {
throw new Error(onInvalidValueMessage + ' ' + list.join(', '));
}
return value;
}
function checkKeyValuePairObject(obj, allowedChildren, onInvalidValueMessage) {
if (getTypeOf(obj) !== 'Object') {
throw new Error(onInvalidValueMessage);
}
var keys = Object.keys(obj);
for (var i = 0; i < keys.length; i++) {
key = keys[i];
if (getTypeOf(headers[key]) !== 'String') {
return false;
if (allowedChildren.indexOf(getTypeOf(obj[keys[i]])) === -1) {
throw new Error(onInvalidValueMessage);
}
}
return true;
return obj;
}
function onInvalidHeader(handler) {
handler({
status: 0,
error: messages.HEADER_VALUE_MUST_BE_STRING,
headers: {}
});
function checkHttpMethod(method) {
return checkForValidStringValue(validHttpMethods, method, messages.INVALID_HTTP_METHOD);
}
function checkSerializer(serializer) {
serializer = serializer || '';
serializer = serializer.trim().toLowerCase();
return checkForValidStringValue(validSerializers, serializer, messages.INVALID_DATA_SERIALIZER);
}
if (validSerializers.indexOf(serializer) > -1) {
return serializer;
function checkForBlacklistedHeaderKey(key) {
if (key.toLowerCase() === 'cookie') {
throw new Error(messages.ADDING_COOKIES_NOT_SUPPORTED);
}
return serializer[0];
return key;
}
function checkForInvalidHeaderValue(value) {
if (getTypeOf(value) !== 'String') {
throw new Error(messages.INVALID_HEADERS_VALUE);
}
return value;
}
function checkTimeoutValue(timeout) {
if (getTypeOf(timeout) !== 'Number' || timeout < 0) {
throw new Error(messages.INVALID_TIMEOUT_VALUE);
}
return timeout;
}
function checkHeadersObject(headers) {
return checkKeyValuePairObject(headers, [ 'String' ], messages.INVALID_HEADERS_VALUE);
}
function checkParamsObject(params) {
return checkKeyValuePairObject(params, [ 'String', 'Array' ], messages.INVALID_PARAMS_VALUE);
}
function resolveCookieString(headers) {
@@ -194,3 +232,18 @@ function handleMissingCallbacks(successFn, failFn) {
throw new Error(messages.MANDATORY_FAIL);
}
}
function handleMissingOptions(options, globals) {
options = options || {};
return {
method: checkHttpMethod(options.method || validHttpMethods[0]),
serializer: checkSerializer(options.serializer || globals.serializer),
timeout: checkTimeoutValue(options.timeout || globals.timeout),
headers: checkHeadersObject(options.headers || {}),
params: checkParamsObject(options.params || {}),
data: options.data || null,
filePath: options.filePath || '',
name: options.name || ''
};
}
+6 -3
View File
@@ -1,8 +1,11 @@
module.exports = {
ADDING_COOKIES_NOT_SUPPORTED: 'advanced-http: "setHeader" does not support adding cookies, please use "setCookie" function instead',
DATA_TYPE_MISMATCH: 'advanced-http: "data" argument supports only following data types:',
DEPRECATED_VDN: 'advanced-http: "validateDomainName" is no more supported, please see change log for further info',
HEADER_VALUE_MUST_BE_STRING: 'advanced-http: header values must be strings',
MANDATORY_SUCCESS: 'advanced-http: missing mandatory "onSuccess" callback function',
MANDATORY_FAIL: 'advanced-http: missing mandatory "onFail" callback function'
MANDATORY_FAIL: 'advanced-http: missing mandatory "onFail" callback function',
INVALID_HTTP_METHOD: 'advanced-http: invalid HTTP method, supported methods are:',
INVALID_DATA_SERIALIZER: 'advanced-http: invalid serializer, supported serializers are:',
INVALID_HEADERS_VALUE: 'advanced-http: header values must be strings',
INVALID_TIMEOUT_VALUE: 'advanced-http: invalid timeout value, needs to be a positive numeric value',
INVALID_PARAMS_VALUE: 'advanced-http: invalid params object, needs to be an object with strings'
};