diff --git a/plugin.xml b/plugin.xml index 3b52b70..239893d 100644 --- a/plugin.xml +++ b/plugin.xml @@ -4,31 +4,31 @@ id="com.synconset.cordovaHTTP" version="1.0.0"> - SSL Pinning - - - Cordova / Phonegap plugin for communicating with HTTP servers using SSL pinning + SSL Pinning + + + Cordova / Phonegap plugin for communicating with HTTP servers using SSL pinning - - - - - + + + - - - + - - - - - - - - - + + + + + + + + + + + + + @@ -37,46 +37,49 @@ - - - - + + + + - + - + - + - + - + - + - + - - - - - - - - - - + + - - + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/android/com/synconset/CordovaHTTP/CordovaHTTP.java b/src/android/com/synconset/CordovaHTTP/CordovaHTTP.java new file mode 100644 index 0000000..d6273df --- /dev/null +++ b/src/android/com/synconset/CordovaHTTP/CordovaHTTP.java @@ -0,0 +1,74 @@ +/** + * A HTTP plugin for Cordova / Phonegap + */ +package com.synconset; + +import java.util.Iterator; + +import org.apache.cordova.CallbackContext; +import org.apache.cordova.CordovaInterface; +import org.apache.cordova.CordovaPlugin; +import org.apache.cordova.CordovaWebView; +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import android.util.Base64; + +public class CordovaHTTP extends CordovaPlugin { + private static final String TAG = "CordovaHTTP"; + + private JSONObject globalHeaders; + + @Override + public void initialize(CordovaInterface cordova, CordovaWebView webView) { + super.initialize(cordova, webView); + this.globalHeaders = new JSONObject(); + } + + @Override + public boolean execute(String action, final JSONArray args, final CallbackContext callbackContext) throws JSONException { + if (action.equals("get")) { + String urlString = args.getString(0); + JSONObject params = args.getJSONObject(1); + JSONObject headers = args.getJSONObject(2); + this.addToJSONObject(headers, this.globalHeaders); + HTTPGet get = new HTTPGet(urlString, params, headers, callbackContext); + cordova.getThreadPool().execute(get); + } else if (action.equals("post")) { + String urlString = args.getString(0); + JSONObject params = args.getJSONObject(1); + JSONObject headers = args.getJSONObject(2); + this.addToJSONObject(headers, this.globalHeaders); + HTTPPost post = new HTTPPost(urlString, params, headers, callbackContext); + cordova.getThreadPool().execute(post); + } else if (action.equals("setAuthorizationHeaderWithUsernameAndPassword")) { + String username = args.getString(0); + String password = args.getString(1); + this.setAuthorizationHeaderWithUsernameAndPassword(username, password); + callbackContext.success(); + } else if (action.equals("downloadFile")) { + + } else { + return false; + } + return true; + } + + private void setAuthorizationHeaderWithUsernameAndPassword(String username, String password) throws JSONException { + String loginInfo = username + ":" + password; + loginInfo = "Basic " + Base64.encodeToString(loginInfo.getBytes(), Base64.DEFAULT); + globalHeaders.put("Authorization", loginInfo); + } + + private void addToJSONObject(JSONObject object, JSONObject objectToAdd) throws JSONException { + Iterator i = objectToAdd.keys(); + + while (i.hasNext()) { + String key = (String)i.next(); + if (!object.has(key)) { + object.put(key, objectToAdd.getString(key)); + } + } + } +} diff --git a/src/android/com/synconset/CordovaHTTP/HTTP.java b/src/android/com/synconset/CordovaHTTP/HTTP.java new file mode 100644 index 0000000..e782da6 --- /dev/null +++ b/src/android/com/synconset/CordovaHTTP/HTTP.java @@ -0,0 +1,124 @@ +/** + * A HTTP plugin for Cordova / Phonegap + */ +package com.synconset; + +import org.apache.cordova.CallbackContext; + +import org.json.JSONException; +import org.json.JSONObject; + +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.BufferedReader; + +import java.net.URLConnection; + +import java.util.Iterator; + +import android.util.Log; + +public class HTTP { + protected static final String TAG = "CordovaHTTP"; + + protected String charset = "UTF-8"; + + private String urlString; + private JSONObject params; + private JSONObject headers; + private CallbackContext callbackContext; + + public HTTP(String urlString, JSONObject params, JSONObject headers, CallbackContext callbackContext) { + this.urlString = urlString; + this.params = params; + this.headers = headers; + this.callbackContext = callbackContext; + } + + protected String getUrlString() { + return this.urlString; + } + + protected void setUrlString(String urlString) { + this.urlString = urlString; + } + + protected JSONObject getParams() { + return this.params; + } + + protected void setParams(JSONObject params) { + this.params = params; + } + + protected JSONObject getHeaders() { + return this.headers; + } + + protected void setHeaders(JSONObject headers) { + this.headers = headers; + } + + protected CallbackContext getCallbackContext() { + return this.callbackContext; + } + + protected void addHeaders(URLConnection conn) throws JSONException { + Iterator i = this.headers.keys(); + + while (i.hasNext()) { + String key = (String)i.next(); + conn.setRequestProperty(key, this.headers.getString(key)); + } + } + + protected String getQueryString() throws JSONException { + Iterator i = this.params.keys(); + StringBuilder sb = new StringBuilder(); + boolean first = true; + + while (i.hasNext()) { + String key = (String)i.next(); + + if (!first) { + sb.append("&"); + } else { + first = false; + } + sb.append(key); + sb.append("="); + sb.append(this.params.getString(key)); + } + + return sb.toString(); + } + + protected String readInputStream(InputStream is) throws IOException { + BufferedReader reader = new BufferedReader(new InputStreamReader(is)); + StringBuilder sb = new StringBuilder(); + + try { + String line = reader.readLine(); + while (line != null) { + sb.append(line); + line = reader.readLine(); + } + + return sb.toString(); + } finally { + reader.close(); + } + } + + protected void respondWithError(CallbackContext callbackContext, String msg) { + try { + JSONObject response = new JSONObject(); + response.put("status", 500); + response.put("error", msg); + callbackContext.error(response); + } catch (JSONException e) { + callbackContext.error(msg); + } + } +} diff --git a/src/android/com/synconset/CordovaHTTP/HTTPGet.java b/src/android/com/synconset/CordovaHTTP/HTTPGet.java new file mode 100644 index 0000000..0df0358 --- /dev/null +++ b/src/android/com/synconset/CordovaHTTP/HTTPGet.java @@ -0,0 +1,68 @@ +/** + * A HTTP plugin for Cordova / Phonegap + */ +package com.synconset; + +import java.io.IOException; +import java.io.InputStream; +import java.net.MalformedURLException; +import java.net.URL; + +import javax.net.ssl.HttpsURLConnection; + +import org.apache.cordova.CallbackContext; +import org.json.JSONException; +import org.json.JSONObject; + +import android.util.Log; + +public class HTTPGet extends HTTP implements Runnable { + public HTTPGet(String urlString, JSONObject params, JSONObject headers, CallbackContext callbackContext) { + super(urlString, params, headers, callbackContext); + } + + @Override + public void run() { + JSONObject params = this.getParams(); + String urlString = this.getUrlString(); + CallbackContext callbackContext = this.getCallbackContext(); + JSONObject response = new JSONObject(); + + InputStream is = null; + HttpsURLConnection conn = null; + try { + if (params.length() > 0) { + urlString = urlString + "?" + this.getQueryString(); + } + URL url = new URL(urlString); + conn = (HttpsURLConnection)url.openConnection(); + conn.setRequestMethod("GET"); + conn.setDoInput(true); + conn.setRequestProperty("Accept-Charset", charset); + this.addHeaders(conn); + conn.connect(); + int status = conn.getResponseCode(); + Log.d(TAG, "The response is: " + status); + is = conn.getInputStream(); + String responseData = this.readInputStream(is); + response.put("status", status); + response.put("data", responseData); + callbackContext.success(response); + } catch (MalformedURLException e) { + this.respondWithError(callbackContext, "There is an error with the url"); + } catch (JSONException e) { + this.respondWithError(callbackContext, "There was an error with the params, headers or generating the response"); + } catch (IOException e) { + this.respondWithError(callbackContext, "There was an error with the request"); + } finally { + if (is != null) { + try { + is.close(); + } catch (IOException e) {} + } + if (conn != null) { + conn.disconnect(); + } + } + } +} \ No newline at end of file diff --git a/src/android/com/synconset/CordovaHTTP/HTTPPost.java b/src/android/com/synconset/CordovaHTTP/HTTPPost.java new file mode 100644 index 0000000..0740af7 --- /dev/null +++ b/src/android/com/synconset/CordovaHTTP/HTTPPost.java @@ -0,0 +1,77 @@ +/** + * A HTTP plugin for Cordova / Phonegap + */ +package com.synconset; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.net.MalformedURLException; + +import java.net.URL; + +import javax.net.ssl.HttpsURLConnection; + +import org.apache.cordova.CallbackContext; +import org.json.JSONException; +import org.json.JSONObject; + +import android.util.Log; + +public class HTTPPost extends HTTP implements Runnable { + public HTTPPost(String urlString, JSONObject params, JSONObject headers, CallbackContext callbackContext) { + super(urlString, params, headers, callbackContext); + } + + @Override + public void run() { + String urlString = this.getUrlString(); + CallbackContext callbackContext = this.getCallbackContext(); + + InputStream is = null; + HttpsURLConnection conn = null; + try { + URL url = new URL(urlString); + conn = (HttpsURLConnection)url.openConnection(); + conn.setRequestMethod("POST"); + conn.setDoInput(true); + conn.setDoOutput(true); + conn.setChunkedStreamingMode(0); + conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); + conn.setRequestProperty("Accept-Charset", charset); + this.addHeaders(conn); + + OutputStream out = conn.getOutputStream(); + OutputStreamWriter writer = new OutputStreamWriter(out, charset); + writer.write(this.getQueryString()); + writer.close(); + out.close(); + + conn.connect(); + int status = conn.getResponseCode(); + Log.d(TAG, "The response is: " + status); + is = conn.getInputStream(); + String responseData = this.readInputStream(is); + JSONObject response = new JSONObject(); + response.put("status", status); + response.put("data", responseData); + callbackContext.success(response); + } catch (MalformedURLException e) { + this.respondWithError(callbackContext, "There is an error with the url"); + } catch (JSONException e) { + this.respondWithError(callbackContext, "There was an error with the params, headers or generating the response"); + } catch (IOException e) { + this.respondWithError(callbackContext, "There was an error with the request"); + } finally { + if (is != null) { + try { + is.close(); + } catch (IOException e) {} + } + if (conn != null) { + conn.disconnect(); + } + } + } +} diff --git a/www/cordovaHTTP.js b/www/cordovaHTTP.js index 7375f2c..ebf364f 100644 --- a/www/cordovaHTTP.js +++ b/www/cordovaHTTP.js @@ -36,8 +36,8 @@ var http = { setAcceptableContentTypes: function(contentTypes, success, failure) { return exec(success, failure, "CordovaHTTP", "setAcceptableContentTypes", contentTypes); }, - post: function(url, params, success, failure) { - return exec(success, failure, "CordovaHTTP", "post", [url, params]); + post: function(url, params, headers, success, failure) { + return exec(success, failure, "CordovaHTTP", "post", [url, params, headers]); }, get: function(url, params, success, failure) { return exec(success, failure, "CordovaHTTP", "get", [url, params]); @@ -139,8 +139,8 @@ if (angular) { setAcceptableContentTypes: function(contentTypes) { return makePromise(http.setAcceptableContentTypes, [contentTypes]); }, - post: function(url, params) { - return makePromise(http.post, [url, params], true); + post: function(url, params, headers) { + return makePromise(http.post, [url, params, headers], true); }, get: function(url, params) { return makePromise(http.get, [url, params], true);