mirror of
https://github.com/silkimen/cordova-plugin-advanced-http.git
synced 2026-01-31 00:00:03 +08:00
WIP:
- some refactoring for future features - move params serializer into JS code
This commit is contained in:
11
plugin.xml
11
plugin.xml
@@ -8,12 +8,15 @@
|
||||
<engine name="cordova" version=">=4.0.0"/>
|
||||
</engines>
|
||||
<dependency id="cordova-plugin-file" version=">=2.0.0"/>
|
||||
<js-module src="www/lodash.js" name="lodash"/>
|
||||
<js-module src="www/umd-tough-cookie.js" name="tough-cookie"/>
|
||||
<js-module src="www/messages.js" name="messages"/>
|
||||
<js-module src="www/local-storage-store.js" name="local-storage-store"/>
|
||||
<js-module src="www/cookie-handler.js" name="cookie-handler"/>
|
||||
<js-module src="www/global-configs.js" name="global-configs"/>
|
||||
<js-module src="www/helpers.js" name="helpers"/>
|
||||
<js-module src="www/local-storage-store.js" name="local-storage-store"/>
|
||||
<js-module src="www/lodash.js" name="lodash"/>
|
||||
<js-module src="www/messages.js" name="messages"/>
|
||||
<js-module src="www/public-interface.js" name="public-interface"/>
|
||||
<js-module src="www/umd-tough-cookie.js" name="tough-cookie"/>
|
||||
<js-module src="www/url-util.js" name="url-util"/>
|
||||
<js-module src="www/advanced-http.js" name="http">
|
||||
<clobbers target="cordova.plugin.http"/>
|
||||
</js-module>
|
||||
|
||||
@@ -31,7 +31,6 @@ abstract class CordovaHttpBase implements Runnable {
|
||||
protected String url;
|
||||
protected String serializer = "none";
|
||||
protected Object data;
|
||||
protected JSONObject params;
|
||||
protected JSONObject headers;
|
||||
protected int timeout;
|
||||
protected boolean followRedirects;
|
||||
@@ -55,13 +54,12 @@ abstract class CordovaHttpBase implements Runnable {
|
||||
this.callbackContext = callbackContext;
|
||||
}
|
||||
|
||||
public CordovaHttpBase(String method, String url, JSONObject params, JSONObject headers, int timeout,
|
||||
public CordovaHttpBase(String method, String url, JSONObject headers, int timeout,
|
||||
boolean followRedirects, SSLSocketFactory customSSLSocketFactory, HostnameVerifier customHostnameVerifier,
|
||||
CallbackContext callbackContext) {
|
||||
|
||||
this.method = method;
|
||||
this.url = url;
|
||||
this.params = params;
|
||||
this.headers = headers;
|
||||
this.timeout = timeout;
|
||||
this.followRedirects = followRedirects;
|
||||
@@ -115,10 +113,7 @@ abstract class CordovaHttpBase implements Runnable {
|
||||
}
|
||||
|
||||
protected HttpRequest createRequest() throws JSONException {
|
||||
String processedUrl = HttpRequest.encode(HttpRequest.append(this.url, JsonUtils.getObjectMap(this.params)));
|
||||
HttpRequest request = new HttpRequest(processedUrl, this.method);
|
||||
|
||||
return request;
|
||||
return new HttpRequest(this.url, this.method);
|
||||
}
|
||||
|
||||
protected void prepareRequest(HttpRequest request) throws JSONException {
|
||||
|
||||
@@ -15,11 +15,11 @@ import org.json.JSONObject;
|
||||
class CordovaHttpDownload extends CordovaHttpBase {
|
||||
private String filePath;
|
||||
|
||||
public CordovaHttpDownload(String url, JSONObject params, JSONObject headers, String filePath, int timeout,
|
||||
public CordovaHttpDownload(String url, JSONObject headers, String filePath, int timeout,
|
||||
boolean followRedirects, SSLSocketFactory customSSLSocketFactory, HostnameVerifier customHostnameVerifier,
|
||||
CallbackContext callbackContext) {
|
||||
|
||||
super("GET", url, params, headers, timeout, followRedirects, customSSLSocketFactory, customHostnameVerifier,
|
||||
super("GET", url, headers, timeout, followRedirects, customSSLSocketFactory, customHostnameVerifier,
|
||||
callbackContext);
|
||||
this.filePath = filePath;
|
||||
}
|
||||
|
||||
@@ -15,11 +15,11 @@ class CordovaHttpOperation extends CordovaHttpBase {
|
||||
customHostnameVerifier, callbackContext);
|
||||
}
|
||||
|
||||
public CordovaHttpOperation(String method, String url, JSONObject params, JSONObject headers, int timeout,
|
||||
boolean followRedirects, SSLSocketFactory customSSLSocketFactory, HostnameVerifier customHostnameVerifier,
|
||||
public CordovaHttpOperation(String method, String url, JSONObject headers, int timeout, boolean followRedirects,
|
||||
SSLSocketFactory customSSLSocketFactory, HostnameVerifier customHostnameVerifier,
|
||||
CallbackContext callbackContext) {
|
||||
|
||||
super(method, url, params, headers, timeout, followRedirects, customSSLSocketFactory, customHostnameVerifier,
|
||||
super(method, url, headers, timeout, followRedirects, customSSLSocketFactory, customHostnameVerifier,
|
||||
callbackContext);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -66,7 +66,7 @@ public class CordovaHttpPlugin extends CordovaPlugin {
|
||||
|
||||
switch (action) {
|
||||
case "get":
|
||||
return this.executeHttpRequestWithParams(action, args, callbackContext);
|
||||
return this.executeHttpRequestWithoutData(action, args, callbackContext);
|
||||
case "post":
|
||||
return this.executeHttpRequestWithData(action, args, callbackContext);
|
||||
case "put":
|
||||
@@ -74,9 +74,9 @@ public class CordovaHttpPlugin extends CordovaPlugin {
|
||||
case "patch":
|
||||
return this.executeHttpRequestWithData(action, args, callbackContext);
|
||||
case "head":
|
||||
return this.executeHttpRequestWithParams(action, args, callbackContext);
|
||||
return this.executeHttpRequestWithoutData(action, args, callbackContext);
|
||||
case "delete":
|
||||
return this.executeHttpRequestWithParams(action, args, callbackContext);
|
||||
return this.executeHttpRequestWithoutData(action, args, callbackContext);
|
||||
case "uploadFile":
|
||||
return this.uploadFile(args, callbackContext);
|
||||
case "downloadFile":
|
||||
@@ -90,15 +90,14 @@ public class CordovaHttpPlugin extends CordovaPlugin {
|
||||
}
|
||||
}
|
||||
|
||||
private boolean executeHttpRequestWithParams(final String method, final JSONArray args,
|
||||
private boolean executeHttpRequestWithoutData(final String method, final JSONArray args,
|
||||
final CallbackContext callbackContext) throws JSONException {
|
||||
|
||||
String url = args.getString(0);
|
||||
JSONObject params = args.getJSONObject(1);
|
||||
JSONObject headers = args.getJSONObject(2);
|
||||
int timeout = args.getInt(3) * 1000;
|
||||
JSONObject headers = args.getJSONObject(1);
|
||||
int timeout = args.getInt(2) * 1000;
|
||||
|
||||
CordovaHttpOperation request = new CordovaHttpOperation(method.toUpperCase(), url, params, headers, timeout,
|
||||
CordovaHttpOperation request = new CordovaHttpOperation(method.toUpperCase(), url, headers, timeout,
|
||||
this.followRedirects, this.customSSLSocketFactory, this.customHostnameVerifier, callbackContext);
|
||||
|
||||
cordova.getThreadPool().execute(request);
|
||||
@@ -125,13 +124,12 @@ public class CordovaHttpPlugin extends CordovaPlugin {
|
||||
|
||||
private boolean uploadFile(final JSONArray args, final CallbackContext callbackContext) throws JSONException {
|
||||
String url = args.getString(0);
|
||||
JSONObject params = args.getJSONObject(1);
|
||||
JSONObject headers = args.getJSONObject(2);
|
||||
String filePath = args.getString(3);
|
||||
String uploadName = args.getString(4);
|
||||
int timeout = args.getInt(5) * 1000;
|
||||
JSONObject headers = args.getJSONObject(1);
|
||||
String filePath = args.getString(2);
|
||||
String uploadName = args.getString(3);
|
||||
int timeout = args.getInt(4) * 1000;
|
||||
|
||||
CordovaHttpUpload upload = new CordovaHttpUpload(url, params, headers, filePath, uploadName, timeout,
|
||||
CordovaHttpUpload upload = new CordovaHttpUpload(url, headers, filePath, uploadName, timeout,
|
||||
this.followRedirects, this.customSSLSocketFactory, this.customHostnameVerifier, callbackContext);
|
||||
|
||||
cordova.getThreadPool().execute(upload);
|
||||
@@ -141,12 +139,11 @@ public class CordovaHttpPlugin extends CordovaPlugin {
|
||||
|
||||
private boolean downloadFile(final JSONArray args, final CallbackContext callbackContext) throws JSONException {
|
||||
String url = args.getString(0);
|
||||
JSONObject params = args.getJSONObject(1);
|
||||
JSONObject headers = args.getJSONObject(2);
|
||||
String filePath = args.getString(3);
|
||||
int timeout = args.getInt(4) * 1000;
|
||||
JSONObject headers = args.getJSONObject(1);
|
||||
String filePath = args.getString(2);
|
||||
int timeout = args.getInt(3) * 1000;
|
||||
|
||||
CordovaHttpDownload download = new CordovaHttpDownload(url, params, headers, filePath, timeout,
|
||||
CordovaHttpDownload download = new CordovaHttpDownload(url, headers, filePath, timeout,
|
||||
this.followRedirects, this.customSSLSocketFactory, this.customHostnameVerifier, callbackContext);
|
||||
|
||||
cordova.getThreadPool().execute(download);
|
||||
|
||||
@@ -17,11 +17,11 @@ class CordovaHttpUpload extends CordovaHttpBase {
|
||||
private String filePath;
|
||||
private String uploadName;
|
||||
|
||||
public CordovaHttpUpload(String url, JSONObject params, JSONObject headers, String filePath, String uploadName,
|
||||
public CordovaHttpUpload(String url, JSONObject headers, String filePath, String uploadName,
|
||||
int timeout, boolean followRedirects, SSLSocketFactory customSSLSocketFactory,
|
||||
HostnameVerifier customHostnameVerifier, CallbackContext callbackContext) {
|
||||
|
||||
super("POST", url, params, headers, timeout, followRedirects, customSSLSocketFactory, customHostnameVerifier,
|
||||
super("POST", url, headers, timeout, followRedirects, customSSLSocketFactory, customHostnameVerifier,
|
||||
callbackContext);
|
||||
this.filePath = filePath;
|
||||
this.uploadName = uploadName;
|
||||
|
||||
@@ -51,7 +51,8 @@ const tests = [
|
||||
result.type.should.be.equal('rejected');
|
||||
result.data.should.be.eql({ status: -2, error: targetInfo.isAndroid ? messageFactory.sslTrustAnchor() : messageFactory.invalidCertificate('self-signed.badssl.com') });
|
||||
}
|
||||
},{
|
||||
},
|
||||
{
|
||||
description: 'should reject self signed cert (PUT)',
|
||||
expected: 'rejected: {"status":-2, ...',
|
||||
func: function(resolve, reject) { cordova.plugin.http.put('https://self-signed.badssl.com/', { test: 'testString' }, {}, resolve, reject); },
|
||||
@@ -59,7 +60,8 @@ const tests = [
|
||||
result.type.should.be.equal('rejected');
|
||||
result.data.should.be.eql({ status: -2, error: targetInfo.isAndroid ? messageFactory.sslTrustAnchor() : messageFactory.invalidCertificate('self-signed.badssl.com') });
|
||||
}
|
||||
},{
|
||||
},
|
||||
{
|
||||
description: 'should reject self signed cert (POST)',
|
||||
expected: 'rejected: {"status":-2, ...',
|
||||
func: function(resolve, reject) { cordova.plugin.http.post('https://self-signed.badssl.com/', { test: 'testString' }, {}, resolve, reject); },
|
||||
@@ -67,7 +69,8 @@ const tests = [
|
||||
result.type.should.be.equal('rejected');
|
||||
result.data.should.be.eql({ status: -2, error: targetInfo.isAndroid ? messageFactory.sslTrustAnchor() : messageFactory.invalidCertificate('self-signed.badssl.com') });
|
||||
}
|
||||
},{
|
||||
},
|
||||
{
|
||||
description: 'should reject self signed cert (PATCH)',
|
||||
expected: 'rejected: {"status":-2, ...',
|
||||
func: function(resolve, reject) { cordova.plugin.http.patch('https://self-signed.badssl.com/', { test: 'testString' }, {}, resolve, reject); },
|
||||
@@ -75,7 +78,8 @@ const tests = [
|
||||
result.type.should.be.equal('rejected');
|
||||
result.data.should.be.eql({ status: -2, error: targetInfo.isAndroid ? messageFactory.sslTrustAnchor() : messageFactory.invalidCertificate('self-signed.badssl.com') });
|
||||
}
|
||||
},{
|
||||
},
|
||||
{
|
||||
description: 'should reject self signed cert (DELETE)',
|
||||
expected: 'rejected: {"status":-2, ...',
|
||||
func: function(resolve, reject) { cordova.plugin.http.delete('https://self-signed.badssl.com/', {}, {}, resolve, reject); },
|
||||
@@ -83,7 +87,8 @@ const tests = [
|
||||
result.type.should.be.equal('rejected');
|
||||
result.data.should.be.eql({ status: -2, error: targetInfo.isAndroid ? messageFactory.sslTrustAnchor() : messageFactory.invalidCertificate('self-signed.badssl.com') });
|
||||
}
|
||||
},{
|
||||
},
|
||||
{
|
||||
description: 'should accept bad cert (GET)',
|
||||
expected: 'resolved: {"status":200, ...',
|
||||
before: helpers.setNoCheckCertMode,
|
||||
@@ -92,7 +97,8 @@ const tests = [
|
||||
result.type.should.be.equal('resolved');
|
||||
result.data.should.include({ status: 200 });
|
||||
}
|
||||
},{
|
||||
},
|
||||
{
|
||||
description: 'should accept bad cert (PUT)',
|
||||
expected: 'rejected: {"status":405, ... // will be rejected because PUT is not allowed',
|
||||
before: helpers.setNoCheckCertMode,
|
||||
@@ -101,7 +107,8 @@ const tests = [
|
||||
result.type.should.be.equal('rejected');
|
||||
result.data.should.include({ status: 405 });
|
||||
}
|
||||
},{
|
||||
},
|
||||
{
|
||||
description: 'should accept bad cert (POST)',
|
||||
expected: 'rejected: {"status":405, ... // will be rejected because POST is not allowed',
|
||||
before: helpers.setNoCheckCertMode,
|
||||
@@ -110,7 +117,8 @@ const tests = [
|
||||
result.type.should.be.equal('rejected');
|
||||
result.data.should.include({ status: 405 });
|
||||
}
|
||||
},{
|
||||
},
|
||||
{
|
||||
description: 'should accept bad cert (PATCH)',
|
||||
expected: 'rejected: {"status":405, ... // will be rejected because PATCH is not allowed',
|
||||
before: helpers.setNoCheckCertMode,
|
||||
@@ -119,7 +127,8 @@ const tests = [
|
||||
result.type.should.be.equal('rejected');
|
||||
result.data.should.include({ status: 405 });
|
||||
}
|
||||
},{
|
||||
},
|
||||
{
|
||||
description: 'should accept bad cert (DELETE)',
|
||||
expected: 'rejected: {"status":405, ... // will be rejected because DELETE is not allowed',
|
||||
before: helpers.setNoCheckCertMode,
|
||||
@@ -128,7 +137,8 @@ const tests = [
|
||||
result.type.should.be.equal('rejected');
|
||||
result.data.should.include({ status: 405 });
|
||||
}
|
||||
},{
|
||||
},
|
||||
{
|
||||
description: 'should fetch data from http://httpbin.org/ (GET)',
|
||||
expected: 'resolved: {"status":200, ...',
|
||||
before: helpers.setNoCheckCertMode,
|
||||
@@ -137,7 +147,8 @@ const tests = [
|
||||
result.type.should.be.equal('resolved');
|
||||
result.data.should.include({ status: 200 });
|
||||
}
|
||||
},{
|
||||
},
|
||||
{
|
||||
description: 'should send JSON object correctly (POST)',
|
||||
expected: 'resolved: {"status": 200, "data": "{\\"json\\":\\"test\\": \\"testString\\"}\" ...',
|
||||
before: helpers.setJsonSerializer,
|
||||
@@ -146,7 +157,8 @@ const tests = [
|
||||
result.type.should.be.equal('resolved');
|
||||
JSON.parse(result.data.data).json.should.eql({ test: 'testString' });
|
||||
}
|
||||
},{
|
||||
},
|
||||
{
|
||||
description: 'should send JSON object correctly (PUT)',
|
||||
expected: 'resolved: {"status": 200, "data": "{\\"json\\":\\"test\\": \\"testString\\"}\" ...',
|
||||
before: helpers.setJsonSerializer,
|
||||
@@ -155,7 +167,8 @@ const tests = [
|
||||
result.type.should.be.equal('resolved');
|
||||
JSON.parse(result.data.data).json.should.eql({ test: 'testString' });
|
||||
}
|
||||
},{
|
||||
},
|
||||
{
|
||||
description: 'should send JSON object correctly (PATCH)',
|
||||
expected: 'resolved: {"status": 200, "data": "{\\"json\\":\\"test\\": \\"testString\\"}\" ...',
|
||||
before: helpers.setJsonSerializer,
|
||||
@@ -164,7 +177,8 @@ const tests = [
|
||||
result.type.should.be.equal('resolved');
|
||||
JSON.parse(result.data.data).json.should.eql({ test: 'testString' });
|
||||
}
|
||||
},{
|
||||
},
|
||||
{
|
||||
description: 'should send JSON array correctly (POST) #26',
|
||||
expected: 'resolved: {"status": 200, "data": "[ 1, 2, 3 ]\" ...',
|
||||
before: helpers.setJsonSerializer,
|
||||
@@ -173,7 +187,8 @@ const tests = [
|
||||
result.type.should.be.equal('resolved');
|
||||
JSON.parse(result.data.data).json.should.eql([ 1, 2, 3 ]);
|
||||
}
|
||||
},{
|
||||
},
|
||||
{
|
||||
description: 'should send JSON array correctly (PUT) #26',
|
||||
expected: 'resolved: {"status": 200, "data": "[ 1, 2, 3 ]\" ...',
|
||||
before: helpers.setJsonSerializer,
|
||||
@@ -182,7 +197,8 @@ const tests = [
|
||||
result.type.should.be.equal('resolved');
|
||||
JSON.parse(result.data.data).json.should.eql([ 1, 2, 3 ]);
|
||||
}
|
||||
},{
|
||||
},
|
||||
{
|
||||
description: 'should send JSON array correctly (PATCH) #26',
|
||||
expected: 'resolved: {"status": 200, "data": "[ 1, 2, 3 ]\" ...',
|
||||
before: helpers.setJsonSerializer,
|
||||
@@ -192,7 +208,8 @@ const tests = [
|
||||
result.data.data.should.be.a('string');
|
||||
JSON.parse(result.data.data).json.should.eql([ 1, 2, 3 ]);
|
||||
}
|
||||
},{
|
||||
},
|
||||
{
|
||||
description: 'should send url encoded data correctly (POST) #41',
|
||||
expected: 'resolved: {"status": 200, "data": "{\\"form\\":\\"test\\": \\"testString\\"}\" ...',
|
||||
before: helpers.setUrlEncodedSerializer,
|
||||
@@ -201,7 +218,8 @@ const tests = [
|
||||
result.type.should.be.equal('resolved');
|
||||
JSON.parse(result.data.data).form.should.eql({ test: 'testString' });
|
||||
}
|
||||
},{
|
||||
},
|
||||
{
|
||||
description: 'should send url encoded data correctly (PUT)',
|
||||
expected: 'resolved: {"status": 200, "data": "{\\"form\\":\\"test\\": \\"testString\\"}\" ...',
|
||||
before: helpers.setUrlEncodedSerializer,
|
||||
@@ -210,7 +228,8 @@ const tests = [
|
||||
result.type.should.be.equal('resolved');
|
||||
JSON.parse(result.data.data).form.should.eql({ test: 'testString' });
|
||||
}
|
||||
},{
|
||||
},
|
||||
{
|
||||
description: 'should send url encoded data correctly (PATCH)',
|
||||
expected: 'resolved: {"status": 200, "data": "{\\"form\\":\\"test\\": \\"testString\\"}\" ...',
|
||||
before: helpers.setUrlEncodedSerializer,
|
||||
@@ -219,7 +238,8 @@ const tests = [
|
||||
result.type.should.be.equal('resolved');
|
||||
JSON.parse(result.data.data).form.should.eql({ test: 'testString' });
|
||||
}
|
||||
},{
|
||||
},
|
||||
{
|
||||
description: 'should resolve correct URL after redirect (GET) #33',
|
||||
expected: 'resolved: {"status": 200, url: "http://httpbin.org/anything", ...',
|
||||
func: function(resolve, reject) { cordova.plugin.http.get('http://httpbin.org/redirect-to?url=http://httpbin.org/anything', {}, {}, resolve, reject); },
|
||||
@@ -227,7 +247,8 @@ const tests = [
|
||||
result.type.should.be.equal('resolved');
|
||||
result.data.url.should.be.equal('http://httpbin.org/anything');
|
||||
}
|
||||
},{
|
||||
},
|
||||
{
|
||||
description: 'should download a file from given URL to given path in local filesystem',
|
||||
expected: 'resolved: {"content": "<?xml version=\'1.0\' encoding=\'us-ascii\'?>\\n\\n<!-- A SAMPLE set of slides -->" ...',
|
||||
func: function(resolve, reject) {
|
||||
@@ -251,7 +272,8 @@ const tests = [
|
||||
result.data.name.should.be.equal('test.xml');
|
||||
result.data.content.should.be.equal("<?xml version='1.0' encoding='us-ascii'?>\n\n<!-- A SAMPLE set of slides -->\n\n<slideshow \n title=\"Sample Slide Show\"\n date=\"Date of publication\"\n author=\"Yours Truly\"\n >\n\n <!-- TITLE SLIDE -->\n <slide type=\"all\">\n <title>Wake up to WonderWidgets!</title>\n </slide>\n\n <!-- OVERVIEW -->\n <slide type=\"all\">\n <title>Overview</title>\n <item>Why <em>WonderWidgets</em> are great</item>\n <item/>\n <item>Who <em>buys</em> WonderWidgets</item>\n </slide>\n\n</slideshow>");
|
||||
}
|
||||
},{
|
||||
},
|
||||
{
|
||||
description: 'should upload a file from given path in local filesystem to given URL #27',
|
||||
expected: 'resolved: {"status": 200, "data": "files": {"test-file.txt": "I am a dummy file. I am used ...',
|
||||
func: function(resolve, reject) {
|
||||
@@ -276,7 +298,8 @@ const tests = [
|
||||
.files[fileName]
|
||||
.should.be.equal(fileContent);
|
||||
}
|
||||
},{
|
||||
},
|
||||
{
|
||||
description: 'should encode HTTP array params correctly (GET) #45',
|
||||
expected: 'resolved: {"status": 200, "data": "{\\"url\\":\\"http://httpbin.org/get?myArray[]=val1&myArray[]=val2&myArray[]=val3\\"}\" ...',
|
||||
func: function(resolve, reject) {
|
||||
@@ -291,7 +314,8 @@ const tests = [
|
||||
.url
|
||||
.should.include('httpbin.org/get?myArray[]=val1&myArray[]=val2&myArray[]=val3&myString=testString');
|
||||
}
|
||||
},{
|
||||
},
|
||||
{
|
||||
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) {
|
||||
@@ -301,7 +325,8 @@ const tests = [
|
||||
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',
|
||||
expected: 'throwed: "advanced-http: header values must be strings"',
|
||||
func: function(resolve, reject) {
|
||||
@@ -311,7 +336,8 @@ const tests = [
|
||||
result.type.should.be.equal('throwed');
|
||||
result.message.should.be.equal('advanced-http: header values must be strings');
|
||||
}
|
||||
},{
|
||||
},
|
||||
{
|
||||
description: 'should accept content-type "application/xml" #58',
|
||||
expected: 'resolved: {"status": 200, ...',
|
||||
func: function(resolve, reject) {
|
||||
@@ -321,7 +347,8 @@ const tests = [
|
||||
result.type.should.be.equal('resolved');
|
||||
result.data.status.should.be.equal(200);
|
||||
}
|
||||
},{
|
||||
},
|
||||
{
|
||||
description: 'should send programmatically set cookies correctly (GET)',
|
||||
expected: 'resolved: {"status": 200, ...',
|
||||
func: function(resolve, reject) {
|
||||
@@ -339,7 +366,8 @@ const tests = [
|
||||
.Cookie
|
||||
.should.be.equal('myCookie=myValue; mySecondCookie=mySecondValue');
|
||||
}
|
||||
},{
|
||||
},
|
||||
{
|
||||
description: 'should not send any cookies after running "clearCookies" (GET) #59',
|
||||
expected: 'resolved: {"status": 200, "data": "{\"headers\": {\"Cookie\": \"\"...',
|
||||
func: function(resolve, reject) {
|
||||
@@ -358,7 +386,8 @@ const tests = [
|
||||
.Cookie
|
||||
.should.be.equal('');
|
||||
}
|
||||
},{
|
||||
},
|
||||
{
|
||||
description: 'should send programmatically set cookies correctly (DOWNLOAD) #57',
|
||||
expected: 'resolved: {"content":{"cookies":{"myCookie":"myValue ...',
|
||||
func: function(resolve, reject) {
|
||||
@@ -390,7 +419,8 @@ const tests = [
|
||||
cookies.myCookie.should.be.equal('myValue');
|
||||
cookies.mySecondCookie.should.be.equal('mySecondValue');
|
||||
}
|
||||
},{
|
||||
},
|
||||
{
|
||||
description: 'should send UTF-8 encoded raw string correctly (POST) #34',
|
||||
expected: 'resolved: {"status": 200, "data": "{\\"data\\": \\"this is a test string\\"...',
|
||||
before: helpers.setUtf8StringSerializer,
|
||||
@@ -401,7 +431,8 @@ const tests = [
|
||||
result.type.should.be.equal('resolved');
|
||||
JSON.parse(result.data.data).data.should.be.equal('this is a test string');
|
||||
}
|
||||
},{
|
||||
},
|
||||
{
|
||||
description: 'should encode spaces in query string (params object) correctly (GET) #71',
|
||||
expected: 'resolved: {"status": 200, "data": "{\\"args\\": \\"query param\\": \\"and value with spaces\\"...',
|
||||
func: function(resolve, reject) {
|
||||
@@ -411,7 +442,8 @@ const tests = [
|
||||
result.type.should.be.equal('resolved');
|
||||
JSON.parse(result.data.data).args['query param'].should.be.equal('and value with spaces');
|
||||
}
|
||||
},{
|
||||
},
|
||||
{
|
||||
description: 'should decode latin1 (iso-8859-1) encoded body correctly (GET) #72',
|
||||
expected: 'resolved: {"status": 200, "data": "<!DOCTYPE HTML PUBLIC \\"-//W3C//DTD HTML 4.01 Transitional//EN\\"> ...',
|
||||
func: function(resolve, reject) {
|
||||
@@ -421,7 +453,8 @@ const tests = [
|
||||
result.type.should.be.equal('resolved');
|
||||
result.data.data.should.include('[¡] 161 10/01 241 A1 INVERTED EXCLAMATION MARK\n[¢] 162 10/02 242 A2 CENT SIGN');
|
||||
}
|
||||
},{
|
||||
},
|
||||
{
|
||||
description: 'should return empty body string correctly (GET)',
|
||||
expected: 'resolved: {"status": 200, "data": "" ...',
|
||||
func: function(resolve, reject) {
|
||||
@@ -431,7 +464,8 @@ const tests = [
|
||||
result.type.should.be.equal('resolved');
|
||||
result.data.data.should.be.equal('');
|
||||
}
|
||||
},{
|
||||
},
|
||||
{
|
||||
description: 'should pin SSL cert correctly (GET)',
|
||||
expected: 'resolved: {"status": 200 ...',
|
||||
before: helpers.setPinnedCertMode,
|
||||
@@ -442,7 +476,8 @@ const tests = [
|
||||
result.type.should.be.equal('resolved');
|
||||
result.data.status.should.be.equal(200);
|
||||
}
|
||||
},{
|
||||
},
|
||||
{
|
||||
description: 'should reject when pinned cert does not match received server cert (GET)',
|
||||
expected: 'rejected: {"status": -2 ...',
|
||||
before: helpers.setPinnedCertMode,
|
||||
@@ -453,7 +488,8 @@ const tests = [
|
||||
result.type.should.be.equal('rejected');
|
||||
result.data.should.be.eql({ status: -2, error: targetInfo.isAndroid ? messageFactory.sslTrustAnchor() : messageFactory.invalidCertificate('sha512.badssl.com') });
|
||||
}
|
||||
},{
|
||||
},
|
||||
{
|
||||
description: 'should send deeply structured JSON object correctly (POST) #65',
|
||||
expected: 'resolved: {"status": 200, "data": "{\\"data\\": \\"{\\\\"outerObj\\\\":{\\\\"innerStr\\\\":\\\\"testString\\\\",\\\\"innerArr\\\\":[1,2,3]}}\\" ...',
|
||||
before: helpers.setJsonSerializer,
|
||||
@@ -462,7 +498,8 @@ const tests = [
|
||||
result.type.should.be.equal('resolved');
|
||||
JSON.parse(result.data.data).json.should.eql({ outerObj: { innerStr: 'testString', innerArr: [1, 2, 3] }});
|
||||
}
|
||||
},{
|
||||
},
|
||||
{
|
||||
description: 'should override header "content-type" correctly (POST) #78',
|
||||
expected: 'resolved: {"status": 200, "headers": "{\\"Content-Type\\": \\"text/plain\\" ...',
|
||||
before: helpers.setJsonSerializer,
|
||||
@@ -471,7 +508,8 @@ const tests = [
|
||||
result.type.should.be.equal('resolved');
|
||||
JSON.parse(result.data.data).headers['Content-Type'].should.be.equal('text/plain');
|
||||
}
|
||||
},{
|
||||
},
|
||||
{
|
||||
description: 'should handle error during file download correctly (DOWNLOAD) #83',
|
||||
expected: 'rejected: {"status": 403, "error": "There was an error downloading the file" ...',
|
||||
func: function(resolve, reject) { cordova.plugin.http.downloadFile('http://httpbin.org/status/403', {}, {}, cordova.file.tempDirectory + 'testfile.txt', resolve, reject); },
|
||||
@@ -480,7 +518,8 @@ const tests = [
|
||||
result.data.status.should.be.equal(403);
|
||||
result.data.error.should.be.equal('There was an error downloading the file');
|
||||
}
|
||||
},{
|
||||
},
|
||||
{
|
||||
description: 'should handle gzip encoded response correctly',
|
||||
expected: 'resolved: {"status": 200, "headers": "{\\"Content-Encoding\\": \\"gzip\\" ...',
|
||||
func: function(resolve, reject) { cordova.plugin.http.get('http://httpbin.org/gzip', {}, {}, resolve, reject); },
|
||||
@@ -489,7 +528,8 @@ const tests = [
|
||||
result.data.status.should.be.equal(200);
|
||||
JSON.parse(result.data.data).gzipped.should.be.equal(true);
|
||||
}
|
||||
},{
|
||||
},
|
||||
{
|
||||
description: 'should send empty string correctly',
|
||||
expected: 'resolved: {"status": 200, "data": "{\\"json\\":\\"\\" ...',
|
||||
before: helpers.setUtf8StringSerializer,
|
||||
@@ -498,16 +538,34 @@ const tests = [
|
||||
result.type.should.be.equal('resolved');
|
||||
JSON.parse(result.data.data).data.should.be.equal('');
|
||||
}
|
||||
},{
|
||||
},
|
||||
{
|
||||
description: 'shouldn\'t escape forward slashes #184',
|
||||
expected: 'resolved: {"status": 200, "data": "{\\"json\\":\\"/\\" ...',
|
||||
before: helpers.setJsonSerializer,
|
||||
func: function(resolve, reject) { cordova.plugin.http.post('http://httpbin.org/anything', { testString: '/' }, {}, resolve, reject); },
|
||||
validationFunc: function(driver, result) {
|
||||
result.type.should.be.equal('resolved');
|
||||
console.log(result.data.data);
|
||||
JSON.parse(result.data.data).json.testString.should.be.equal('/');
|
||||
}
|
||||
},
|
||||
{
|
||||
description: 'should not double encode spaces in url path #195',
|
||||
expected: '',
|
||||
func: function(resolve, reject) { cordova.plugin.http.get('https://httpbin.org/anything/containing%20spaces%20in%20url', {}, {}, resolve, reject); },
|
||||
validationFunc: function(driver, result) {
|
||||
result.type.should.be.equal('resolved');
|
||||
JSON.parse(result.data.data).url.should.be.equal('https://httpbin.org/anything/containing spaces in url');
|
||||
}
|
||||
},
|
||||
{
|
||||
description: 'should encode spaces in url query correctly',
|
||||
expected: '',
|
||||
func: function(resolve, reject) { cordova.plugin.http.get('https://httpbin.org/anything', { 'query key': 'very long query value with spaces' }, {}, resolve, reject); },
|
||||
validationFunc: function(driver, result) {
|
||||
result.type.should.be.equal('resolved');
|
||||
JSON.parse(result.data.data).url.should.be.equal('https://httpbin.org/anything?query key=very long query value with spaces');
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
|
||||
@@ -1,21 +1,27 @@
|
||||
const chai = require('chai');
|
||||
const mock = require('mock-require');
|
||||
const path = require('path');
|
||||
|
||||
const should = chai.should();
|
||||
|
||||
const HELPERS_ID = path.resolve(__dirname, '..', 'www', 'helpers');
|
||||
const PLUGIN_ID = path.resolve(__dirname, '..', 'www', 'advanced-http');
|
||||
|
||||
describe('Advanced HTTP www interface', function() {
|
||||
describe('Advanced HTTP public interface', function () {
|
||||
let http = {};
|
||||
let helpers = {};
|
||||
|
||||
const noop = () => { /* intentionally doing nothing */ };
|
||||
|
||||
const loadHttp = () => {
|
||||
mock(`${PLUGIN_ID}.helpers`, mock.reRequire('../www/helpers'));
|
||||
http = mock.reRequire('../www/advanced-http');
|
||||
const getDependenciesBlueprint = () => {
|
||||
const messages = require('../www/messages');
|
||||
const globalConfigs = require('../www/global-configs');
|
||||
const ToughCookie = require('../www/umd-tough-cookie');
|
||||
const lodash = require('../www/lodash');
|
||||
const WebStorageCookieStore = require('../www/local-storage-store')(ToughCookie, lodash);
|
||||
const cookieHandler = require('../www/cookie-handler')(null, ToughCookie, WebStorageCookieStore);
|
||||
const helpers = require('../www/helpers')(cookieHandler, messages);
|
||||
const urlUtil = require('../www/url-util')(helpers);
|
||||
|
||||
return { exec: noop, cookieHandler, urlUtil: urlUtil, helpers, globalConfigs };
|
||||
};
|
||||
|
||||
const loadHttp = (deps) => {
|
||||
http = require('../www/public-interface')(deps.exec, deps.cookieHandler, deps.urlUtil, deps.helpers, deps.globalConfigs);
|
||||
};
|
||||
|
||||
this.timeout(900000);
|
||||
@@ -23,13 +29,7 @@ describe('Advanced HTTP www interface', function() {
|
||||
beforeEach(() => {
|
||||
// mocked btoa function (base 64 encoding strings)
|
||||
global.btoa = decoded => new Buffer(decoded).toString('base64');
|
||||
|
||||
mock('cordova/exec', noop);
|
||||
mock(`${PLUGIN_ID}.cookie-handler`, {});
|
||||
mock(`${HELPERS_ID}.cookie-handler`, {});
|
||||
mock(`${HELPERS_ID}.messages`, require('../www/messages'));
|
||||
|
||||
loadHttp();
|
||||
loadHttp(getDependenciesBlueprint());
|
||||
});
|
||||
|
||||
it('sets global headers correctly with two args (old interface)', () => {
|
||||
@@ -48,76 +48,76 @@ describe('Advanced HTTP www interface', function() {
|
||||
});
|
||||
|
||||
it('resolves global headers correctly #24', () => {
|
||||
mock(`${HELPERS_ID}.cookie-handler`, {
|
||||
getCookieString: () => 'fakeCookieString'
|
||||
});
|
||||
const deps = getDependenciesBlueprint();
|
||||
|
||||
mock('cordova/exec', (onSuccess, onFail, namespace, method, params) => {
|
||||
const headers = params[2];
|
||||
deps.cookieHandler.getCookieString = () => 'fakeCookieString';
|
||||
|
||||
deps.exec = (onSuccess, onFail, namespace, method, params) => {
|
||||
const headers = params[1];
|
||||
headers.should.eql({
|
||||
Cookie: 'fakeCookieString',
|
||||
myKey: 'myValue'
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
loadHttp();
|
||||
loadHttp(deps);
|
||||
|
||||
http.setHeader('*', 'myKey', 'myValue');
|
||||
http.get('url', {}, {}, noop, noop);
|
||||
});
|
||||
|
||||
it('resolves host headers correctly (set without port number) #37', () => {
|
||||
mock(`${HELPERS_ID}.cookie-handler`, {
|
||||
getCookieString: () => 'fakeCookieString'
|
||||
});
|
||||
const deps = getDependenciesBlueprint();
|
||||
|
||||
mock('cordova/exec', (onSuccess, onFail, namespace, method, params) => {
|
||||
const headers = params[2];
|
||||
deps.cookieHandler.getCookieString = () => 'fakeCookieString';
|
||||
|
||||
deps.exec = (onSuccess, onFail, namespace, method, params) => {
|
||||
const headers = params[1];
|
||||
headers.should.eql({
|
||||
Cookie: 'fakeCookieString',
|
||||
myKey: 'myValue'
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
loadHttp();
|
||||
loadHttp(deps);
|
||||
|
||||
http.setHeader('www.google.de', 'myKey', 'myValue');
|
||||
http.get('https://www.google.de/?gws_rd=ssl', {}, {}, noop, noop);
|
||||
});
|
||||
|
||||
it('resolves host headers correctly (set with port number) #37', () => {
|
||||
mock(`${HELPERS_ID}.cookie-handler`, {
|
||||
getCookieString: () => 'fakeCookieString'
|
||||
});
|
||||
const deps = getDependenciesBlueprint();
|
||||
|
||||
mock('cordova/exec', (onSuccess, onFail, namespace, method, params) => {
|
||||
const headers = params[2];
|
||||
deps.cookieHandler.getCookieString = () => 'fakeCookieString';
|
||||
|
||||
deps.exec = (onSuccess, onFail, namespace, method, params) => {
|
||||
const headers = params[1];
|
||||
headers.should.eql({
|
||||
Cookie: 'fakeCookieString',
|
||||
myKey: 'myValue'
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
loadHttp();
|
||||
loadHttp(deps);
|
||||
|
||||
http.setHeader('www.google.de:8080', 'myKey', 'myValue');
|
||||
http.get('https://www.google.de:8080/?gws_rd=ssl', {}, {}, noop, noop);
|
||||
});
|
||||
|
||||
it('resolves request headers correctly', () => {
|
||||
mock(`${HELPERS_ID}.cookie-handler`, {
|
||||
getCookieString: () => 'fakeCookieString'
|
||||
});
|
||||
const deps = getDependenciesBlueprint();
|
||||
|
||||
mock('cordova/exec', (onSuccess, onFail, namespace, method, params) => {
|
||||
const headers = params[2];
|
||||
deps.cookieHandler.getCookieString = () => 'fakeCookieString';
|
||||
|
||||
deps.exec = (onSuccess, onFail, namespace, method, params) => {
|
||||
const headers = params[1];
|
||||
headers.should.eql({
|
||||
Cookie: 'fakeCookieString',
|
||||
myKey: 'myValue'
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
loadHttp();
|
||||
loadHttp(deps);
|
||||
|
||||
http.get('https://www.google.de/?gws_rd=ssl', {}, { myKey: 'myValue' }, noop, noop);
|
||||
});
|
||||
@@ -128,6 +128,95 @@ describe('Advanced HTTP www interface', function() {
|
||||
});
|
||||
|
||||
it('throws an Error when you try to add a cookie by using "setHeader" #46', () => {
|
||||
(function() { http.setHeader('*', 'cookie', 'value') }).should.throw();
|
||||
(function () { http.setHeader('*', 'cookie', 'value') }).should.throw();
|
||||
});
|
||||
});
|
||||
|
||||
describe('URL handler', function () {
|
||||
const helpers = require('../www/helpers')(null, null);
|
||||
const handler = require('../www/url-util')(helpers);
|
||||
|
||||
it('parses URL with protocol, hostname and path correctly', () => {
|
||||
handler.parseUrl('http://ilkimen.net/test').should.include({
|
||||
protocol: 'http:',
|
||||
host: 'ilkimen.net',
|
||||
hostname: 'ilkimen.net',
|
||||
pathname: '/test',
|
||||
port: '',
|
||||
search: '',
|
||||
hash: ''
|
||||
});
|
||||
});
|
||||
|
||||
it('parses URL with protocol, hostname, port and path correctly', () => {
|
||||
handler.parseUrl('http://ilkimen.net:8080/test').should.include({
|
||||
protocol: 'http:',
|
||||
host: 'ilkimen.net:8080',
|
||||
hostname: 'ilkimen.net',
|
||||
pathname: '/test',
|
||||
port: '8080',
|
||||
search: '',
|
||||
hash: ''
|
||||
});
|
||||
});
|
||||
|
||||
it('parses URL with protocol, hostname, port, path and query string correctly', () => {
|
||||
handler.parseUrl('http://ilkimen.net:8080/test?param=value').should.include({
|
||||
protocol: 'http:',
|
||||
host: 'ilkimen.net:8080',
|
||||
hostname: 'ilkimen.net',
|
||||
pathname: '/test',
|
||||
port: '8080',
|
||||
search: '?param=value',
|
||||
hash: ''
|
||||
});
|
||||
});
|
||||
|
||||
it('parses URL with protocol, hostname, port, path, query string and hash param correctly', () => {
|
||||
handler.parseUrl('http://ilkimen.net:8080/test?param=value#myHash').should.include({
|
||||
protocol: 'http:',
|
||||
host: 'ilkimen.net:8080',
|
||||
hostname: 'ilkimen.net',
|
||||
pathname: '/test',
|
||||
port: '8080',
|
||||
search: '?param=value',
|
||||
hash: '#myHash'
|
||||
});
|
||||
});
|
||||
|
||||
it('serializes query params correctly without URL encoding', () => {
|
||||
handler.serializeQueryParams({
|
||||
param1: 'value with spaces',
|
||||
param2: 'value with special character äöü%'
|
||||
}, false).should.equal('param1=value with spaces¶m2=value with special character äöü%');
|
||||
});
|
||||
|
||||
it('serializes array of query params correctly without URL encoding', () => {
|
||||
handler.serializeQueryParams({
|
||||
myArray: ['val1', 'val2', 'val3'],
|
||||
myString: 'testString'
|
||||
}, false).should.equal('myArray[]=val1&myArray[]=val2&myArray[]=val3&myString=testString');
|
||||
});
|
||||
|
||||
it('serializes query params correctly with URL encoding enabled', () => {
|
||||
handler.serializeQueryParams({
|
||||
param1: 'value with spaces',
|
||||
param2: 'value with special character äöü%&'
|
||||
}, true).should.equal('param1=value%20with%20spaces¶m2=value%20with%20special%20character%20%C3%A4%C3%B6%C3%BC%25%26');
|
||||
});
|
||||
|
||||
it('appends query params string correctly to given URL without query parameters', () => {
|
||||
handler.appendQueryParamsString('http://ilkimen.net/', 'param1=value1')
|
||||
.should.equal('http://ilkimen.net/?param1=value1');
|
||||
});
|
||||
|
||||
it('appends query params string correctly to given URL with existing query parameters', () => {
|
||||
handler.appendQueryParamsString('http://ilkimen.net/?myParam=myValue', 'param1=value1')
|
||||
.should.equal('http://ilkimen.net/?myParam=myValue¶m1=value1');
|
||||
});
|
||||
|
||||
it('appends query params string correctly to given URL with existing query parameters and hash value', () => {
|
||||
handler.appendQueryParamsString('http://ilkimen.net/?myParam=myValue#myHash', 'param1=value1')
|
||||
.should.equal('http://ilkimen.net/?myParam=myValue¶m1=value1#myHash');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -5,121 +5,14 @@
|
||||
var pluginId = module.id.slice(0, module.id.lastIndexOf('.'));
|
||||
|
||||
var exec = require('cordova/exec');
|
||||
var cookieHandler = require(pluginId + '.cookie-handler');
|
||||
var helpers = require(pluginId + '.helpers');
|
||||
|
||||
var globalConfigs = {
|
||||
headers: {},
|
||||
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 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];
|
||||
}
|
||||
|
||||
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;
|
||||
},
|
||||
setSSLCertMode: function (mode, success, failure) {
|
||||
return exec(success, failure, 'CordovaHttpPlugin', 'setSSLCertMode', [ helpers.checkSSLCertMode(mode) ]);
|
||||
},
|
||||
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);
|
||||
}
|
||||
};
|
||||
var messages = require(pluginId + '.messages');
|
||||
var globalConfigs = require(pluginId + '.global-configs');
|
||||
var ToughCookie = require(pluginId + '.tough-cookie');
|
||||
var lodash = require(pluginId + '.lodash');
|
||||
var WebStorageCookieStore = require(pluginId + '.local-storage-store')(ToughCookie, lodash);
|
||||
var cookieHandler = require(pluginId + '.cookie-handler')(window.localStorage, ToughCookie, WebStorageCookieStore);
|
||||
var helpers = require(pluginId + '.helpers')(cookieHandler, messages);
|
||||
var urlUtil = require(pluginId + '.url-util')(helpers);
|
||||
var publicInterface = require(pluginId + '.public-interface')(exec, cookieHandler, urlUtil, helpers, globalConfigs);
|
||||
|
||||
module.exports = publicInterface;
|
||||
|
||||
@@ -1,73 +1,70 @@
|
||||
var pluginId = module.id.slice(0, module.id.lastIndexOf('.'));
|
||||
var ToughCookie = require(pluginId + '.tough-cookie');
|
||||
var WebStorageCookieStore = require(pluginId + '.local-storage-store');
|
||||
module.exports = function init(storage, ToughCookie, WebStorageCookieStore) {
|
||||
var storeKey = '__advancedHttpCookieStore__';
|
||||
|
||||
var storage = window.localStorage;
|
||||
var storeKey = '__advancedHttpCookieStore__';
|
||||
var store = new WebStorageCookieStore(storage, storeKey);
|
||||
var cookieJar = new ToughCookie.CookieJar(store);
|
||||
|
||||
var store = new WebStorageCookieStore(storage, storeKey);
|
||||
var cookieJar = new ToughCookie.CookieJar(store);
|
||||
|
||||
module.exports = {
|
||||
return {
|
||||
setCookieFromString: setCookieFromString,
|
||||
setCookie: setCookie,
|
||||
getCookieString: getCookieString,
|
||||
clearCookies: clearCookies,
|
||||
removeCookies: removeCookies
|
||||
}
|
||||
};
|
||||
|
||||
function splitCookieString(cookieStr) {
|
||||
function splitCookieString(cookieStr) {
|
||||
var cookieParts = cookieStr.split(',');
|
||||
var splitCookies = [];
|
||||
var processedCookie = null;
|
||||
|
||||
for (var i = 0; i < cookieParts.length; ++i) {
|
||||
if (cookieParts[i].substr(-11, 8).toLowerCase() === 'expires=') {
|
||||
processedCookie = cookieParts[i] + ',' + cookieParts[i + 1];
|
||||
i++;
|
||||
} else {
|
||||
processedCookie = cookieParts[i];
|
||||
}
|
||||
if (cookieParts[i].substr(-11, 8).toLowerCase() === 'expires=') {
|
||||
processedCookie = cookieParts[i] + ',' + cookieParts[i + 1];
|
||||
i++;
|
||||
} else {
|
||||
processedCookie = cookieParts[i];
|
||||
}
|
||||
|
||||
processedCookie = processedCookie.trim();
|
||||
splitCookies.push(processedCookie);
|
||||
processedCookie = processedCookie.trim();
|
||||
splitCookies.push(processedCookie);
|
||||
}
|
||||
|
||||
return splitCookies;
|
||||
}
|
||||
}
|
||||
|
||||
function setCookieFromString(url, cookieStr) {
|
||||
function setCookieFromString(url, cookieStr) {
|
||||
if (!cookieStr) return;
|
||||
|
||||
var cookies = splitCookieString(cookieStr);
|
||||
|
||||
for (var i = 0; i < cookies.length; ++i) {
|
||||
cookieJar.setCookieSync(cookies[i], url, { ignoreError: true });
|
||||
cookieJar.setCookieSync(cookies[i], url, { ignoreError: true });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function setCookie(url, cookie, options) {
|
||||
options = options || {};
|
||||
options.ignoreError = false;
|
||||
cookieJar.setCookieSync(cookie, url, options);
|
||||
}
|
||||
function setCookie(url, cookie, options) {
|
||||
options = options || {};
|
||||
options.ignoreError = false;
|
||||
cookieJar.setCookieSync(cookie, url, options);
|
||||
}
|
||||
|
||||
function getCookieString(url) {
|
||||
function getCookieString(url) {
|
||||
return cookieJar.getCookieStringSync(url);
|
||||
}
|
||||
}
|
||||
|
||||
function clearCookies() {
|
||||
function clearCookies() {
|
||||
window.localStorage.removeItem(storeKey);
|
||||
}
|
||||
}
|
||||
|
||||
function removeCookies(url, cb) {
|
||||
cookieJar.getCookies(url, function(error, cookies) {
|
||||
if (!cookies || cookies.length === 0) {
|
||||
function removeCookies(url, cb) {
|
||||
cookieJar.getCookies(url, function (error, cookies) {
|
||||
if (!cookies || cookies.length === 0) {
|
||||
return cb(null, []);
|
||||
}
|
||||
}
|
||||
|
||||
var domain = cookies[0].domain;
|
||||
var domain = cookies[0].domain;
|
||||
|
||||
cookieJar.store.removeCookies(domain, null, cb);
|
||||
cookieJar.store.removeCookies(domain, null, cb);
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
7
www/global-configs.js
Normal file
7
www/global-configs.js
Normal file
@@ -0,0 +1,7 @@
|
||||
var globalConfigs = {
|
||||
headers: {},
|
||||
serializer: 'urlencoded',
|
||||
timeout: 60.0,
|
||||
};
|
||||
|
||||
module.exports = globalConfigs;
|
||||
498
www/helpers.js
498
www/helpers.js
@@ -1,253 +1,251 @@
|
||||
var pluginId = module.id.slice(0, module.id.lastIndexOf('.'));
|
||||
var cookieHandler = require(pluginId + '.cookie-handler');
|
||||
var messages = require(pluginId + '.messages');
|
||||
|
||||
var validSerializers = [ 'urlencoded', 'json', 'utf8' ];
|
||||
var validCertModes = [ 'default', 'nocheck', 'pinned', 'legacy' ];
|
||||
var validHttpMethods = [ 'get', 'put', 'post', 'patch', 'head', 'delete', 'upload', 'download' ];
|
||||
|
||||
module.exports = {
|
||||
b64EncodeUnicode: b64EncodeUnicode,
|
||||
getTypeOf: getTypeOf,
|
||||
checkSerializer: checkSerializer,
|
||||
checkSSLCertMode: checkSSLCertMode,
|
||||
checkForBlacklistedHeaderKey: checkForBlacklistedHeaderKey,
|
||||
checkForInvalidHeaderValue: checkForInvalidHeaderValue,
|
||||
injectCookieHandler: injectCookieHandler,
|
||||
injectFileEntryHandler: injectFileEntryHandler,
|
||||
getMergedHeaders: getMergedHeaders,
|
||||
getProcessedData: getProcessedData,
|
||||
handleMissingCallbacks: handleMissingCallbacks,
|
||||
handleMissingOptions: handleMissingOptions
|
||||
};
|
||||
|
||||
// Thanks Mozilla: https://developer.mozilla.org/en-US/docs/Web/API/WindowBase64/Base64_encoding_and_decoding#The_.22Unicode_Problem.22
|
||||
function b64EncodeUnicode(str) {
|
||||
return btoa(encodeURIComponent(str).replace(/%([0-9A-F]{2})/g, function (match, p1) {
|
||||
return String.fromCharCode('0x' + p1);
|
||||
}));
|
||||
}
|
||||
|
||||
function mergeHeaders(globalHeaders, localHeaders) {
|
||||
var globalKeys = Object.keys(globalHeaders);
|
||||
var key;
|
||||
|
||||
for (var i = 0; i < globalKeys.length; i++) {
|
||||
key = globalKeys[i];
|
||||
|
||||
if (!localHeaders.hasOwnProperty(key)) {
|
||||
localHeaders[key] = globalHeaders[key];
|
||||
}
|
||||
}
|
||||
|
||||
return localHeaders;
|
||||
}
|
||||
|
||||
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++) {
|
||||
if (allowedChildren.indexOf(getTypeOf(obj[keys[i]])) === -1) {
|
||||
throw new Error(onInvalidValueMessage);
|
||||
}
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
function checkHttpMethod(method) {
|
||||
return checkForValidStringValue(validHttpMethods, method, messages.INVALID_HTTP_METHOD);
|
||||
}
|
||||
|
||||
function checkSerializer(serializer) {
|
||||
return checkForValidStringValue(validSerializers, serializer, messages.INVALID_DATA_SERIALIZER);
|
||||
}
|
||||
|
||||
function checkSSLCertMode(mode) {
|
||||
return checkForValidStringValue(validCertModes, mode, messages.INVALID_SSL_CERT_MODE);
|
||||
}
|
||||
|
||||
function checkForBlacklistedHeaderKey(key) {
|
||||
if (key.toLowerCase() === 'cookie') {
|
||||
throw new Error(messages.ADDING_COOKIES_NOT_SUPPORTED);
|
||||
}
|
||||
|
||||
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) {
|
||||
var keys = Object.keys(headers || {});
|
||||
|
||||
for (var i = 0; i < keys.length; ++i) {
|
||||
if (keys[i].match(/^set-cookie$/i)) {
|
||||
return headers[keys[i]];
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
function createFileEntry(rawEntry) {
|
||||
var entry = new (require('cordova-plugin-file.FileEntry'))();
|
||||
|
||||
entry.isDirectory = rawEntry.isDirectory;
|
||||
entry.isFile = rawEntry.isFile;
|
||||
entry.name = rawEntry.name;
|
||||
entry.fullPath = rawEntry.fullPath;
|
||||
entry.filesystem = new FileSystem(rawEntry.filesystemName || (rawEntry.filesystem == window.PERSISTENT ? 'persistent' : 'temporary'));
|
||||
entry.nativeURL = rawEntry.nativeURL;
|
||||
|
||||
return entry;
|
||||
}
|
||||
|
||||
function injectCookieHandler(url, cb) {
|
||||
return function(response) {
|
||||
cookieHandler.setCookieFromString(url, resolveCookieString(response.headers));
|
||||
cb(response);
|
||||
}
|
||||
}
|
||||
|
||||
function injectFileEntryHandler(cb) {
|
||||
return function(response) {
|
||||
cb(createFileEntry(response.file));
|
||||
}
|
||||
}
|
||||
|
||||
function getCookieHeader(url) {
|
||||
return { Cookie: cookieHandler.getCookieString(url) };
|
||||
}
|
||||
|
||||
function getMatchingHostHeaders(url, headersList) {
|
||||
var matches = url.match(/^https?\:\/\/([^\/?#]+)(?:[\/?#]|$)/i);
|
||||
var domain = matches && matches[1];
|
||||
|
||||
return headersList[domain] || null;
|
||||
}
|
||||
|
||||
function getMergedHeaders(url, requestHeaders, predefinedHeaders) {
|
||||
var globalHeaders = predefinedHeaders['*'] || {};
|
||||
var hostHeaders = getMatchingHostHeaders(url, predefinedHeaders) || {};
|
||||
var mergedHeaders = mergeHeaders(globalHeaders, hostHeaders);
|
||||
|
||||
mergedHeaders = mergeHeaders(mergedHeaders, requestHeaders);
|
||||
mergedHeaders = mergeHeaders(mergedHeaders, getCookieHeader(url));
|
||||
|
||||
return mergedHeaders;
|
||||
}
|
||||
|
||||
// typeof is not working reliably in JS
|
||||
function getTypeOf(object) {
|
||||
switch (Object.prototype.toString.call(object)) {
|
||||
case '[object Array]':
|
||||
return 'Array';
|
||||
case '[object Boolean]':
|
||||
return 'Boolean';
|
||||
case '[object Function]':
|
||||
return 'Function';
|
||||
case '[object Null]':
|
||||
return 'Null';
|
||||
case '[object Number]':
|
||||
return 'Number';
|
||||
case '[object Object]':
|
||||
return 'Object';
|
||||
case '[object String]':
|
||||
return 'String';
|
||||
case '[object Undefined]':
|
||||
return 'Undefined';
|
||||
default:
|
||||
return 'Unknown';
|
||||
}
|
||||
}
|
||||
|
||||
function getAllowedDataTypes(dataSerializer) {
|
||||
switch (dataSerializer) {
|
||||
case 'utf8':
|
||||
return ['String'];
|
||||
case 'urlencoded':
|
||||
return ['Object'];
|
||||
default:
|
||||
return ['Array', 'Object'];
|
||||
}
|
||||
}
|
||||
|
||||
function getProcessedData(data, dataSerializer) {
|
||||
var currentDataType = getTypeOf(data);
|
||||
var allowedDataTypes = getAllowedDataTypes(dataSerializer);
|
||||
|
||||
if (allowedDataTypes.indexOf(currentDataType) === -1) {
|
||||
throw new Error(messages.DATA_TYPE_MISMATCH + ' ' + allowedDataTypes.join(', '));
|
||||
}
|
||||
|
||||
if (dataSerializer === 'utf8') {
|
||||
data = { text: data };
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
function handleMissingCallbacks(successFn, failFn) {
|
||||
if (getTypeOf(successFn) !== 'Function') {
|
||||
throw new Error(messages.MANDATORY_SUCCESS);
|
||||
}
|
||||
|
||||
if (getTypeOf(failFn) !== 'Function') {
|
||||
throw new Error(messages.MANDATORY_FAIL);
|
||||
}
|
||||
}
|
||||
|
||||
function handleMissingOptions(options, globals) {
|
||||
options = options || {};
|
||||
module.exports = function init(cookieHandler, messages) {
|
||||
var validSerializers = ['urlencoded', 'json', 'utf8'];
|
||||
var validCertModes = ['default', 'nocheck', 'pinned', 'legacy'];
|
||||
var validHttpMethods = ['get', 'put', 'post', 'patch', 'head', 'delete', 'upload', 'download'];
|
||||
|
||||
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: getTypeOf(options.data) === 'Undefined' ? null : options.data,
|
||||
filePath: options.filePath || '',
|
||||
name: options.name || ''
|
||||
b64EncodeUnicode: b64EncodeUnicode,
|
||||
getTypeOf: getTypeOf,
|
||||
checkSerializer: checkSerializer,
|
||||
checkSSLCertMode: checkSSLCertMode,
|
||||
checkForBlacklistedHeaderKey: checkForBlacklistedHeaderKey,
|
||||
checkForInvalidHeaderValue: checkForInvalidHeaderValue,
|
||||
injectCookieHandler: injectCookieHandler,
|
||||
injectFileEntryHandler: injectFileEntryHandler,
|
||||
getMergedHeaders: getMergedHeaders,
|
||||
getProcessedData: getProcessedData,
|
||||
handleMissingCallbacks: handleMissingCallbacks,
|
||||
handleMissingOptions: handleMissingOptions
|
||||
};
|
||||
}
|
||||
|
||||
// Thanks Mozilla: https://developer.mozilla.org/en-US/docs/Web/API/WindowBase64/Base64_encoding_and_decoding#The_.22Unicode_Problem.22
|
||||
function b64EncodeUnicode(str) {
|
||||
return btoa(encodeURIComponent(str).replace(/%([0-9A-F]{2})/g, function (match, p1) {
|
||||
return String.fromCharCode('0x' + p1);
|
||||
}));
|
||||
}
|
||||
|
||||
function mergeHeaders(globalHeaders, localHeaders) {
|
||||
var globalKeys = Object.keys(globalHeaders);
|
||||
var key;
|
||||
|
||||
for (var i = 0; i < globalKeys.length; i++) {
|
||||
key = globalKeys[i];
|
||||
|
||||
if (!localHeaders.hasOwnProperty(key)) {
|
||||
localHeaders[key] = globalHeaders[key];
|
||||
}
|
||||
}
|
||||
|
||||
return localHeaders;
|
||||
}
|
||||
|
||||
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++) {
|
||||
if (allowedChildren.indexOf(getTypeOf(obj[keys[i]])) === -1) {
|
||||
throw new Error(onInvalidValueMessage);
|
||||
}
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
function checkHttpMethod(method) {
|
||||
return checkForValidStringValue(validHttpMethods, method, messages.INVALID_HTTP_METHOD);
|
||||
}
|
||||
|
||||
function checkSerializer(serializer) {
|
||||
return checkForValidStringValue(validSerializers, serializer, messages.INVALID_DATA_SERIALIZER);
|
||||
}
|
||||
|
||||
function checkSSLCertMode(mode) {
|
||||
return checkForValidStringValue(validCertModes, mode, messages.INVALID_SSL_CERT_MODE);
|
||||
}
|
||||
|
||||
function checkForBlacklistedHeaderKey(key) {
|
||||
if (key.toLowerCase() === 'cookie') {
|
||||
throw new Error(messages.ADDING_COOKIES_NOT_SUPPORTED);
|
||||
}
|
||||
|
||||
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) {
|
||||
var keys = Object.keys(headers || {});
|
||||
|
||||
for (var i = 0; i < keys.length; ++i) {
|
||||
if (keys[i].match(/^set-cookie$/i)) {
|
||||
return headers[keys[i]];
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
function createFileEntry(rawEntry) {
|
||||
var entry = new (require('cordova-plugin-file.FileEntry'))();
|
||||
|
||||
entry.isDirectory = rawEntry.isDirectory;
|
||||
entry.isFile = rawEntry.isFile;
|
||||
entry.name = rawEntry.name;
|
||||
entry.fullPath = rawEntry.fullPath;
|
||||
entry.filesystem = new FileSystem(rawEntry.filesystemName || (rawEntry.filesystem == window.PERSISTENT ? 'persistent' : 'temporary'));
|
||||
entry.nativeURL = rawEntry.nativeURL;
|
||||
|
||||
return entry;
|
||||
}
|
||||
|
||||
function injectCookieHandler(url, cb) {
|
||||
return function (response) {
|
||||
cookieHandler.setCookieFromString(url, resolveCookieString(response.headers));
|
||||
cb(response);
|
||||
}
|
||||
}
|
||||
|
||||
function injectFileEntryHandler(cb) {
|
||||
return function (response) {
|
||||
cb(createFileEntry(response.file));
|
||||
}
|
||||
}
|
||||
|
||||
function getCookieHeader(url) {
|
||||
return { Cookie: cookieHandler.getCookieString(url) };
|
||||
}
|
||||
|
||||
function getMatchingHostHeaders(url, headersList) {
|
||||
var matches = url.match(/^https?\:\/\/([^\/?#]+)(?:[\/?#]|$)/i);
|
||||
var domain = matches && matches[1];
|
||||
|
||||
return headersList[domain] || null;
|
||||
}
|
||||
|
||||
function getMergedHeaders(url, requestHeaders, predefinedHeaders) {
|
||||
var globalHeaders = predefinedHeaders['*'] || {};
|
||||
var hostHeaders = getMatchingHostHeaders(url, predefinedHeaders) || {};
|
||||
var mergedHeaders = mergeHeaders(globalHeaders, hostHeaders);
|
||||
|
||||
mergedHeaders = mergeHeaders(mergedHeaders, requestHeaders);
|
||||
mergedHeaders = mergeHeaders(mergedHeaders, getCookieHeader(url));
|
||||
|
||||
return mergedHeaders;
|
||||
}
|
||||
|
||||
// typeof is not working reliably in JS
|
||||
function getTypeOf(object) {
|
||||
switch (Object.prototype.toString.call(object)) {
|
||||
case '[object Array]':
|
||||
return 'Array';
|
||||
case '[object Boolean]':
|
||||
return 'Boolean';
|
||||
case '[object Function]':
|
||||
return 'Function';
|
||||
case '[object Null]':
|
||||
return 'Null';
|
||||
case '[object Number]':
|
||||
return 'Number';
|
||||
case '[object Object]':
|
||||
return 'Object';
|
||||
case '[object String]':
|
||||
return 'String';
|
||||
case '[object Undefined]':
|
||||
return 'Undefined';
|
||||
default:
|
||||
return 'Unknown';
|
||||
}
|
||||
}
|
||||
|
||||
function getAllowedDataTypes(dataSerializer) {
|
||||
switch (dataSerializer) {
|
||||
case 'utf8':
|
||||
return ['String'];
|
||||
case 'urlencoded':
|
||||
return ['Object'];
|
||||
default:
|
||||
return ['Array', 'Object'];
|
||||
}
|
||||
}
|
||||
|
||||
function getProcessedData(data, dataSerializer) {
|
||||
var currentDataType = getTypeOf(data);
|
||||
var allowedDataTypes = getAllowedDataTypes(dataSerializer);
|
||||
|
||||
if (allowedDataTypes.indexOf(currentDataType) === -1) {
|
||||
throw new Error(messages.DATA_TYPE_MISMATCH + ' ' + allowedDataTypes.join(', '));
|
||||
}
|
||||
|
||||
if (dataSerializer === 'utf8') {
|
||||
data = { text: data };
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
function handleMissingCallbacks(successFn, failFn) {
|
||||
if (getTypeOf(successFn) !== 'Function') {
|
||||
throw new Error(messages.MANDATORY_SUCCESS);
|
||||
}
|
||||
|
||||
if (getTypeOf(failFn) !== 'Function') {
|
||||
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: getTypeOf(options.data) === 'Undefined' ? null : options.data,
|
||||
filePath: options.filePath || '',
|
||||
name: options.name || ''
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
@@ -30,30 +30,27 @@
|
||||
|
||||
'use strict';
|
||||
|
||||
var pluginId = module.id.slice(0, module.id.lastIndexOf('.'));
|
||||
var ToughCookie = require(pluginId + '.tough-cookie');
|
||||
var _ = require(pluginId + '.lodash');
|
||||
|
||||
function WebStorageCookieStore(storage, storeKey) {
|
||||
module.exports = function init(ToughCookie, _) {
|
||||
function WebStorageCookieStore(storage, storeKey) {
|
||||
ToughCookie.Store.call(this);
|
||||
this._storage = storage || window.localStorage;
|
||||
this._storage = storage;
|
||||
this._storeKey = storeKey || '__cookieStore__';
|
||||
this.synchronous = true;
|
||||
}
|
||||
}
|
||||
|
||||
WebStorageCookieStore.prototype = Object.create(ToughCookie.Store);
|
||||
WebStorageCookieStore.prototype = Object.create(ToughCookie.Store);
|
||||
|
||||
WebStorageCookieStore.prototype.findCookie = function(domain, path, key, callback) {
|
||||
WebStorageCookieStore.prototype.findCookie = function (domain, path, key, callback) {
|
||||
var store = this._readStore();
|
||||
var cookie = _.get(store, [domain, path, key], null);
|
||||
|
||||
callback(null, ToughCookie.Cookie.fromJSON(cookie));
|
||||
};
|
||||
};
|
||||
|
||||
WebStorageCookieStore.prototype.findCookies = function(domain, path, callback) {
|
||||
WebStorageCookieStore.prototype.findCookies = function (domain, path, callback) {
|
||||
if (!domain) {
|
||||
callback(null, []);
|
||||
return;
|
||||
callback(null, []);
|
||||
return;
|
||||
}
|
||||
|
||||
var that = this;
|
||||
@@ -61,123 +58,124 @@ WebStorageCookieStore.prototype.findCookies = function(domain, path, callback) {
|
||||
var store = this._readStore();
|
||||
var domains = ToughCookie.permuteDomain(domain) || [domain];
|
||||
|
||||
domains.forEach(function(domain) {
|
||||
if (!store[domain]) {
|
||||
return;
|
||||
}
|
||||
domains.forEach(function (domain) {
|
||||
if (!store[domain]) {
|
||||
return;
|
||||
}
|
||||
|
||||
var matchingPaths = Object.keys(store[domain]);
|
||||
var matchingPaths = Object.keys(store[domain]);
|
||||
|
||||
if (path != null) {
|
||||
matchingPaths = matchingPaths.filter(function(cookiePath) {
|
||||
return that._isOnPath(cookiePath, path);
|
||||
});
|
||||
}
|
||||
|
||||
matchingPaths.forEach(function(path) {
|
||||
Array.prototype.push.apply(cookies, _.values(store[domain][path]));
|
||||
if (path != null) {
|
||||
matchingPaths = matchingPaths.filter(function (cookiePath) {
|
||||
return that._isOnPath(cookiePath, path);
|
||||
});
|
||||
}
|
||||
|
||||
matchingPaths.forEach(function (path) {
|
||||
Array.prototype.push.apply(cookies, _.values(store[domain][path]));
|
||||
});
|
||||
});
|
||||
|
||||
cookies = cookies.map(function(cookie) {
|
||||
return ToughCookie.Cookie.fromJSON(cookie);
|
||||
cookies = cookies.map(function (cookie) {
|
||||
return ToughCookie.Cookie.fromJSON(cookie);
|
||||
});
|
||||
|
||||
callback(null, cookies);
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns whether `cookiePath` is on the given `urlPath`
|
||||
*/
|
||||
WebStorageCookieStore.prototype._isOnPath = function(cookiePath, urlPath) {
|
||||
/**
|
||||
* Returns whether `cookiePath` is on the given `urlPath`
|
||||
*/
|
||||
WebStorageCookieStore.prototype._isOnPath = function (cookiePath, urlPath) {
|
||||
if (!cookiePath) {
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (cookiePath === urlPath) {
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (urlPath.indexOf(cookiePath) !== 0) {
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (cookiePath[cookiePath.length - 1] !== '/' && urlPath[cookiePath.length] !== '/') {
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
};
|
||||
|
||||
WebStorageCookieStore.prototype.putCookie = function(cookie, callback) {
|
||||
var store = this._readStore();
|
||||
WebStorageCookieStore.prototype.putCookie = function (cookie, callback) {
|
||||
var store = this._readStore();
|
||||
|
||||
_.set(store, [cookie.domain, cookie.path, cookie.key], cookie);
|
||||
this._writeStore(store);
|
||||
callback(null);
|
||||
};
|
||||
_.set(store, [cookie.domain, cookie.path, cookie.key], cookie);
|
||||
this._writeStore(store);
|
||||
callback(null);
|
||||
};
|
||||
|
||||
WebStorageCookieStore.prototype.updateCookie = function(oldCookie, newCookie, callback) {
|
||||
WebStorageCookieStore.prototype.updateCookie = function (oldCookie, newCookie, callback) {
|
||||
this.putCookie(newCookie, callback);
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
WebStorageCookieStore.prototype.removeCookie = function(domain, path, key, callback) {
|
||||
WebStorageCookieStore.prototype.removeCookie = function (domain, path, key, callback) {
|
||||
var store = this._readStore();
|
||||
|
||||
_.unset(store, [domain, path, key]);
|
||||
this._writeStore(store);
|
||||
callback(null);
|
||||
};
|
||||
};
|
||||
|
||||
WebStorageCookieStore.prototype.removeCookies = function(domain, path, callback) {
|
||||
WebStorageCookieStore.prototype.removeCookies = function (domain, path, callback) {
|
||||
var store = this._readStore();
|
||||
|
||||
if (path == null) {
|
||||
_.unset(store, [domain]);
|
||||
_.unset(store, [domain]);
|
||||
} else {
|
||||
_.unset(store, [domain, path]);
|
||||
_.unset(store, [domain, path]);
|
||||
}
|
||||
|
||||
this._writeStore(store);
|
||||
callback(null);
|
||||
};
|
||||
};
|
||||
|
||||
WebStorageCookieStore.prototype.getAllCookies = function(callback) {
|
||||
WebStorageCookieStore.prototype.getAllCookies = function (callback) {
|
||||
var cookies = [];
|
||||
var store = this._readStore();
|
||||
|
||||
Object.keys(store).forEach(function(domain) {
|
||||
Object.keys(store[domain]).forEach(function(path) {
|
||||
Array.protype.push.apply(cookies, _.values(store[domain][path]));
|
||||
});
|
||||
Object.keys(store).forEach(function (domain) {
|
||||
Object.keys(store[domain]).forEach(function (path) {
|
||||
Array.protype.push.apply(cookies, _.values(store[domain][path]));
|
||||
});
|
||||
});
|
||||
|
||||
cookies = cookies.map(function(cookie) {
|
||||
return ToughCookie.Cookie.fromJSON(cookie);
|
||||
cookies = cookies.map(function (cookie) {
|
||||
return ToughCookie.Cookie.fromJSON(cookie);
|
||||
});
|
||||
|
||||
cookies.sort(function(c1, c2) {
|
||||
return (c1.creationIndex || 0) - (c2.creationIndex || 0);
|
||||
cookies.sort(function (c1, c2) {
|
||||
return (c1.creationIndex || 0) - (c2.creationIndex || 0);
|
||||
});
|
||||
|
||||
callback(null, cookies);
|
||||
};
|
||||
};
|
||||
|
||||
WebStorageCookieStore.prototype._readStore = function() {
|
||||
WebStorageCookieStore.prototype._readStore = function () {
|
||||
var json = this._storage.getItem(this._storeKey);
|
||||
|
||||
if (json !== null) {
|
||||
try {
|
||||
return JSON.parse(json);
|
||||
} catch (e) { }
|
||||
try {
|
||||
return JSON.parse(json);
|
||||
} catch (e) { }
|
||||
}
|
||||
|
||||
return {};
|
||||
};
|
||||
};
|
||||
|
||||
WebStorageCookieStore.prototype._writeStore = function(store) {
|
||||
WebStorageCookieStore.prototype._writeStore = function (store) {
|
||||
this._storage.setItem(this._storeKey, JSON.stringify(store));
|
||||
};
|
||||
};
|
||||
|
||||
module.exports = WebStorageCookieStore;
|
||||
return WebStorageCookieStore;
|
||||
};
|
||||
|
||||
158
www/public-interface.js
Normal file
158
www/public-interface.js
Normal file
@@ -0,0 +1,158 @@
|
||||
module.exports = function init(exec, cookieHandler, urlUtil, helpers, globalConfigs) {
|
||||
const publicInterface = {
|
||||
getBasicAuthHeader: getBasicAuthHeader,
|
||||
useBasicAuth: useBasicAuth,
|
||||
getHeaders: getHeaders,
|
||||
setHeader: setHeader,
|
||||
getDataSerializer: getDataSerializer,
|
||||
setDataSerializer: setDataSerializer,
|
||||
setCookie: setCookie,
|
||||
clearCookies: clearCookies,
|
||||
removeCookies: removeCookies,
|
||||
getCookieString: getCookieString,
|
||||
getRequestTimeout: getRequestTimeout,
|
||||
setRequestTimeout: setRequestTimeout,
|
||||
setSSLCertMode: setSSLCertMode,
|
||||
disableRedirect: disableRedirect,
|
||||
sendRequest: sendRequest,
|
||||
post: post,
|
||||
get: get,
|
||||
put: put,
|
||||
patch: patch,
|
||||
delete: del,
|
||||
head: head,
|
||||
uploadFile: uploadFile,
|
||||
downloadFile: downloadFile
|
||||
};
|
||||
|
||||
function getBasicAuthHeader(username, password) {
|
||||
return { 'Authorization': 'Basic ' + helpers.b64EncodeUnicode(username + ':' + password) };
|
||||
}
|
||||
|
||||
function useBasicAuth(username, password) {
|
||||
this.setHeader('*', 'Authorization', 'Basic ' + helpers.b64EncodeUnicode(username + ':' + password));
|
||||
}
|
||||
|
||||
function getHeaders(host) {
|
||||
return globalConfigs.headers[host || '*'] || null;
|
||||
}
|
||||
|
||||
function setHeader() {
|
||||
// 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];
|
||||
}
|
||||
|
||||
helpers.checkForBlacklistedHeaderKey(header);
|
||||
helpers.checkForInvalidHeaderValue(value);
|
||||
|
||||
globalConfigs.headers[host] = globalConfigs.headers[host] || {};
|
||||
globalConfigs.headers[host][header] = value;
|
||||
}
|
||||
|
||||
function getDataSerializer() {
|
||||
return globalConfigs.serializer;
|
||||
}
|
||||
|
||||
function setDataSerializer(serializer) {
|
||||
globalConfigs.serializer = helpers.checkSerializer(serializer);
|
||||
}
|
||||
|
||||
function setCookie(url, cookie, options) {
|
||||
cookieHandler.setCookie(url, cookie, options);
|
||||
}
|
||||
|
||||
function clearCookies() {
|
||||
cookieHandler.clearCookies();
|
||||
}
|
||||
|
||||
function removeCookies(url, callback) {
|
||||
cookieHandler.removeCookies(url, callback);
|
||||
}
|
||||
|
||||
function getCookieString(url) {
|
||||
return cookieHandler.getCookieString(url);
|
||||
}
|
||||
|
||||
function getRequestTimeout() {
|
||||
return globalConfigs.timeout;
|
||||
}
|
||||
|
||||
function setRequestTimeout(timeout) {
|
||||
globalConfigs.timeout = timeout;
|
||||
}
|
||||
|
||||
function setSSLCertMode(mode, success, failure) {
|
||||
return exec(success, failure, 'CordovaHttpPlugin', 'setSSLCertMode', [helpers.checkSSLCertMode(mode)]);
|
||||
}
|
||||
|
||||
function disableRedirect(disable, success, failure) {
|
||||
return exec(success, failure, 'CordovaHttpPlugin', 'disableRedirect', [!!disable]);
|
||||
}
|
||||
|
||||
function sendRequest(url, options, success, failure) {
|
||||
helpers.handleMissingCallbacks(success, failure);
|
||||
|
||||
options = helpers.handleMissingOptions(options, globalConfigs);
|
||||
url = urlUtil.appendQueryParamsString(url, urlUtil.serializeQueryParams(options.params, true));
|
||||
|
||||
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, headers, options.filePath, options.name, options.timeout]);
|
||||
case 'download':
|
||||
var onDownloadSuccess = helpers.injectCookieHandler(url, helpers.injectFileEntryHandler(success));
|
||||
return exec(onDownloadSuccess, onFail, 'CordovaHttpPlugin', 'downloadFile', [url, headers, options.filePath, options.timeout]);
|
||||
default:
|
||||
return exec(onSuccess, onFail, 'CordovaHttpPlugin', options.method, [url, headers, options.timeout]);
|
||||
}
|
||||
}
|
||||
|
||||
function post(url, data, headers, success, failure) {
|
||||
return publicInterface.sendRequest(url, { method: 'post', data: data, headers: headers }, success, failure);
|
||||
};
|
||||
|
||||
function get(url, params, headers, success, failure) {
|
||||
return publicInterface.sendRequest(url, { method: 'get', params: params, headers: headers }, success, failure);
|
||||
};
|
||||
|
||||
function put(url, data, headers, success, failure) {
|
||||
return publicInterface.sendRequest(url, { method: 'put', data: data, headers: headers }, success, failure);
|
||||
}
|
||||
|
||||
function patch(url, data, headers, success, failure) {
|
||||
return publicInterface.sendRequest(url, { method: 'patch', data: data, headers: headers }, success, failure);
|
||||
}
|
||||
|
||||
function del(url, params, headers, success, failure) {
|
||||
return publicInterface.sendRequest(url, { method: 'delete', params: params, headers: headers }, success, failure);
|
||||
}
|
||||
|
||||
function head(url, params, headers, success, failure) {
|
||||
return publicInterface.sendRequest(url, { method: 'head', params: params, headers: headers }, success, failure);
|
||||
}
|
||||
|
||||
function uploadFile(url, params, headers, filePath, name, success, failure) {
|
||||
return publicInterface.sendRequest(url, { method: 'upload', params: params, headers: headers, filePath: filePath, name: name }, success, failure);
|
||||
}
|
||||
|
||||
function downloadFile(url, params, headers, filePath, success, failure) {
|
||||
return publicInterface.sendRequest(url, { method: 'download', params: params, headers: headers, filePath: filePath }, success, failure);
|
||||
}
|
||||
|
||||
return publicInterface;
|
||||
}
|
||||
71
www/url-util.js
Normal file
71
www/url-util.js
Normal file
@@ -0,0 +1,71 @@
|
||||
module.exports = function init(helpers) {
|
||||
return {
|
||||
parseUrl: parseUrl,
|
||||
serializeQueryParams: serializeQueryParams,
|
||||
appendQueryParamsString: appendQueryParamsString
|
||||
}
|
||||
|
||||
function parseUrl(url) {
|
||||
var match = url.match(/^(https?\:)\/\/(([^:\/?#]*)(?:\:([0-9]+))?)([\/]{0,1}[^?#]*)(\?[^#]*|)(#.*|)$/);
|
||||
|
||||
return match && {
|
||||
protocol: match[1],
|
||||
host: match[2],
|
||||
hostname: match[3],
|
||||
port: match[4] || '',
|
||||
pathname: match[5],
|
||||
search: match[6],
|
||||
hash: match[7]
|
||||
}
|
||||
}
|
||||
|
||||
function serializeQueryParams(params, encode) {
|
||||
return serializeObject(params, encode);
|
||||
}
|
||||
|
||||
function serializeObject(object, encode) {
|
||||
var fragments = [];
|
||||
|
||||
for (var key in object) {
|
||||
if (!object.hasOwnProperty(key)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (helpers.getTypeOf(object[key]) === 'Array') {
|
||||
fragments.push(serializeArray(object[key], encode));
|
||||
continue;
|
||||
} else if (helpers.getTypeOf(object[key]) === 'Object') {
|
||||
fragments.push(serializeObject(object[key], encode));
|
||||
continue;
|
||||
}
|
||||
|
||||
if (encode) {
|
||||
fragments.push(encodeURIComponent(key) + '=' + encodeURIComponent(object[key]));
|
||||
} else {
|
||||
fragments.push(key + '=' + object[key]);
|
||||
}
|
||||
}
|
||||
|
||||
return fragments.join('&');
|
||||
}
|
||||
|
||||
function serializeArray(array, encode) {
|
||||
|
||||
}
|
||||
|
||||
function appendQueryParamsString(url, params) {
|
||||
if (!url.length || !params.length) {
|
||||
return url;
|
||||
}
|
||||
|
||||
var parsed = parseUrl(url);
|
||||
|
||||
return parsed.protocol
|
||||
+ '//'
|
||||
+ parsed.host
|
||||
+ parsed.pathname
|
||||
+ (parsed.search.length ? parsed.search + '&' + params : '?' + params)
|
||||
+ parsed.hash;
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user