mirror of
https://github.com/silkimen/cordova-plugin-advanced-http.git
synced 2026-01-31 00:00:03 +08:00
WIP: started refactoring
- one HTTP request class implementing Runnable for all request methods - broken SSL cert handling
This commit is contained in:
12
plugin.xml
12
plugin.xml
@@ -56,19 +56,23 @@
|
||||
<config-file target="AndroidManifest.xml" parent="/manifest">
|
||||
<uses-permission android:name="android.permission.INTERNET"/>
|
||||
</config-file>
|
||||
<!--
|
||||
<source-file src="src/android/com/github/kevinsawicki/http/HttpRequest.java" target-dir="src/com/github/kevinsawicki/http"/>
|
||||
<source-file src="src/android/com/github/kevinsawicki/http/OkConnectionFactory.java" target-dir="src/com/github/kevinsawicki/http"/>
|
||||
<source-file src="src/android/com/github/kevinsawicki/http/TLSSocketFactory.java" target-dir="src/com/github/kevinsawicki/http"/>
|
||||
-->
|
||||
<source-file src="src/android/com/synconset/cordovahttp/CordovaHttp.java" target-dir="src/com/synconset/cordovahttp"/>
|
||||
<source-file src="src/android/com/synconset/cordovahttp/CordovaHttpDelete.java" target-dir="src/com/synconset/cordovahttp"/>
|
||||
<source-file src="src/android/com/synconset/cordovahttp/CordovaHttpDownload.java" target-dir="src/com/synconset/cordovahttp"/>
|
||||
<source-file src="src/android/com/synconset/cordovahttp/CordovaHttpGet.java" target-dir="src/com/synconset/cordovahttp"/>
|
||||
<source-file src="src/android/com/synconset/cordovahttp/CordovaHttpHead.java" target-dir="src/com/synconset/cordovahttp"/>
|
||||
<source-file src="src/android/com/silkimen/cordovahttp/CordovaHttpRequest.java" target-dir="src/com/silkimen/cordovahttp"/>
|
||||
<source-file src="src/android/com/synconset/cordovahttp/CordovaHttpPlugin.java" target-dir="src/com/synconset/cordovahttp"/>
|
||||
<source-file src="src/android/com/synconset/cordovahttp/CordovaHttpPost.java" target-dir="src/com/synconset/cordovahttp"/>
|
||||
<source-file src="src/android/com/synconset/cordovahttp/CordovaHttpPut.java" target-dir="src/com/synconset/cordovahttp"/>
|
||||
<source-file src="src/android/com/synconset/cordovahttp/CordovaHttpPatch.java" target-dir="src/com/synconset/cordovahttp"/>
|
||||
<source-file src="src/android/com/synconset/cordovahttp/CordovaHttpUpload.java" target-dir="src/com/synconset/cordovahttp"/>
|
||||
<source-file src="src/android/com/silkimen/http/HttpBodyDecoder.java" target-dir="src/com/silkimen/http"/>
|
||||
<source-file src="src/android/com/silkimen/http/HttpRequest.java" target-dir="src/com/silkimen/http"/>
|
||||
<source-file src="src/android/com/silkimen/http/HttpResponse.java" target-dir="src/com/silkimen/http"/>
|
||||
<source-file src="src/android/com/silkimen/http/JsonUtils.java" target-dir="src/com/silkimen/http"/>
|
||||
<framework src="com.squareup.okhttp3:okhttp-urlconnection:3.10.0"/>
|
||||
</platform>
|
||||
<platform name="browser">
|
||||
@@ -81,4 +85,4 @@
|
||||
<runs/>
|
||||
</js-module>
|
||||
</platform>
|
||||
</plugin>
|
||||
</plugin>
|
||||
|
||||
@@ -88,6 +88,7 @@ import javax.net.ssl.HttpsURLConnection;
|
||||
import javax.net.ssl.SSLContext;
|
||||
import javax.net.ssl.SSLSession;
|
||||
import javax.net.ssl.SSLSocketFactory;
|
||||
import javax.net.ssl.KeyManager;
|
||||
import javax.net.ssl.TrustManager;
|
||||
import javax.net.ssl.TrustManagerFactory;
|
||||
import javax.net.ssl.X509TrustManager;
|
||||
@@ -364,7 +365,7 @@ public class HttpRequest {
|
||||
throws HttpRequestException {
|
||||
try {
|
||||
SSLContext context = SSLContext.getInstance("TLS");
|
||||
context.init(null, trustManagers, new SecureRandom());
|
||||
context.init(keyManagers, trustManagers, new SecureRandom());
|
||||
|
||||
if (android.os.Build.VERSION.SDK_INT < 20) {
|
||||
return new TLSSocketFactory(context);
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
package com.github.kevinsawicki.http;
|
||||
|
||||
import okhttp3.OkUrlFactory;
|
||||
import okhttp3.OkHttpClient;
|
||||
|
||||
import java.net.URL;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URLStreamHandler;
|
||||
import java.net.Proxy;
|
||||
|
||||
|
||||
public class OkConnectionFactory implements HttpRequest.ConnectionFactory {
|
||||
|
||||
protected OkHttpClient okHttpClient = new OkHttpClient();
|
||||
|
||||
public HttpURLConnection create(URL url) {
|
||||
OkUrlFactory okUrlFactory = new OkUrlFactory(okHttpClient);
|
||||
return (HttpURLConnection) okUrlFactory.open(url);
|
||||
}
|
||||
|
||||
public HttpURLConnection create(URL url, Proxy proxy) {
|
||||
OkHttpClient okHttpClientWithProxy = okHttpClient.newBuilder().proxy(proxy).build();
|
||||
OkUrlFactory okUrlFactory = new OkUrlFactory(okHttpClientWithProxy);
|
||||
return (HttpURLConnection) okUrlFactory.open(url);
|
||||
}
|
||||
}
|
||||
154
src/android/com/silkimen/cordovahttp/CordovaHttpRequest.java
Normal file
154
src/android/com/silkimen/cordovahttp/CordovaHttpRequest.java
Normal file
@@ -0,0 +1,154 @@
|
||||
package com.silkimen.cordovahttp;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.net.SocketTimeoutException;
|
||||
import java.net.UnknownHostException;
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import javax.net.ssl.SSLHandshakeException;
|
||||
|
||||
import com.silkimen.http.HttpBodyDecoder;
|
||||
import com.silkimen.http.HttpRequest;
|
||||
import com.silkimen.http.HttpRequest.HttpRequestException;
|
||||
import com.silkimen.http.HttpResponse;
|
||||
import com.silkimen.http.JsonUtils;
|
||||
|
||||
import org.apache.cordova.CallbackContext;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
public class CordovaHttpRequest implements Runnable {
|
||||
private String method;
|
||||
private String url;
|
||||
private String serializer = "none";
|
||||
private Object data;
|
||||
private JSONObject params;
|
||||
private JSONObject headers;
|
||||
private int timeout;
|
||||
private CallbackContext callbackContext;
|
||||
|
||||
public CordovaHttpRequest(String method, String url, String serializer, Object data, JSONObject headers,
|
||||
int timeout, CallbackContext callbackContext) {
|
||||
|
||||
this.method = method;
|
||||
this.url = url;
|
||||
this.serializer = serializer;
|
||||
this.data = data;
|
||||
this.headers = headers;
|
||||
this.timeout = timeout;
|
||||
this.callbackContext = callbackContext;
|
||||
}
|
||||
|
||||
public CordovaHttpRequest(String method, String url, JSONObject params, JSONObject headers, int timeout,
|
||||
CallbackContext callbackContext) {
|
||||
|
||||
this.method = method;
|
||||
this.url = url;
|
||||
this.params = params;
|
||||
this.headers = headers;
|
||||
this.timeout = timeout;
|
||||
this.callbackContext = callbackContext;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
HttpResponse response = new HttpResponse();
|
||||
|
||||
try {
|
||||
String processedUrl = HttpRequest.encode(HttpRequest.append(this.url, JsonUtils.getObjectMap(this.params)));
|
||||
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
||||
|
||||
HttpRequest request = new HttpRequest(processedUrl, this.method)
|
||||
.followRedirects(true /* @TODO */)
|
||||
.readTimeout(this.timeout)
|
||||
.acceptCharset("UTF-8")
|
||||
.uncompress(true);
|
||||
|
||||
// setup content type before applying headers, so user can override it
|
||||
this.setContentType(request)
|
||||
.headers(JsonUtils.getStringMap(this.headers));
|
||||
|
||||
this.sendBody(request)
|
||||
.receive(outputStream);
|
||||
|
||||
ByteBuffer rawOutput = ByteBuffer.wrap(outputStream.toByteArray());
|
||||
String decodedBody = HttpBodyDecoder.decodeBody(rawOutput, request.charset());
|
||||
|
||||
response.setStatus(request.code());
|
||||
response.setUrl(request.url().toString());
|
||||
response.setHeaders(request.headers());
|
||||
|
||||
if (request.code() >= 200 && request.code() < 300) {
|
||||
response.setBody(decodedBody);
|
||||
this.callbackContext.success(response.toJSON());
|
||||
} else {
|
||||
response.setErrorMessage(decodedBody);
|
||||
this.callbackContext.error(response.toJSON());
|
||||
}
|
||||
} catch (HttpRequestException e) {
|
||||
if (e.getCause() instanceof SSLHandshakeException) {
|
||||
response.setStatus(-2);
|
||||
response.setErrorMessage("SSL handshake failed: " + e.getMessage());
|
||||
Log.w("Cordova-Plugin-HTTP", "SSL handshake failed", e);
|
||||
} else if (e.getCause() instanceof UnknownHostException) {
|
||||
response.setStatus(-3);
|
||||
response.setErrorMessage("Host could not be resolved: " + e.getMessage());
|
||||
Log.w("Cordova-Plugin-HTTP", "Host could not be resolved", e);
|
||||
} else if (e.getCause() instanceof SocketTimeoutException) {
|
||||
response.setStatus(-4);
|
||||
response.setErrorMessage("Request timed out: " + e.getMessage());
|
||||
Log.w("Cordova-Plugin-HTTP", "Request timed out", e);
|
||||
} else {
|
||||
response.setStatus(-1);
|
||||
response.setErrorMessage("There was an error with the request: " + e.getCause().getMessage());
|
||||
Log.w("Cordova-Plugin-HTTP", "Generic request error", e);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
response.setStatus(-1);
|
||||
response.setErrorMessage(e.getMessage());
|
||||
Log.e("Cordova-Plugin-HTTP", "An unexpected error occured", e);
|
||||
}
|
||||
|
||||
try {
|
||||
if (response.hasFailed()) {
|
||||
this.callbackContext.error(response.toJSON());
|
||||
} else {
|
||||
this.callbackContext.success(response.toJSON());
|
||||
}
|
||||
} catch (JSONException e) {
|
||||
Log.e("Cordova-Plugin-HTTP", "An unexpected error occured while processing HTTP response", e);
|
||||
}
|
||||
}
|
||||
|
||||
private HttpRequest setContentType(HttpRequest request) {
|
||||
switch(this.serializer) {
|
||||
case "json":
|
||||
return request.contentType("application/json", "UTF-8");
|
||||
case "utf8":
|
||||
return request.contentType("text/plain", "UTF-8");
|
||||
case "urlencoded":
|
||||
// intentionally left blank, because content type is set in HttpRequest.form()
|
||||
}
|
||||
|
||||
return request;
|
||||
}
|
||||
|
||||
private HttpRequest sendBody(HttpRequest request) throws JSONException {
|
||||
if (this.data == null) {
|
||||
return request;
|
||||
}
|
||||
|
||||
switch (this.serializer) {
|
||||
case "json":
|
||||
return request.send(this.data.toString());
|
||||
case "utf8":
|
||||
return request.send(((JSONObject) this.data).getString("text"));
|
||||
case "urlencoded":
|
||||
return request.form(JsonUtils.getObjectMap((JSONObject) this.data));
|
||||
}
|
||||
|
||||
return request;
|
||||
}
|
||||
}
|
||||
19
src/android/com/silkimen/http/HostnameVerifierFactory.java
Normal file
19
src/android/com/silkimen/http/HostnameVerifierFactory.java
Normal file
@@ -0,0 +1,19 @@
|
||||
package com.silkimen.http;
|
||||
|
||||
import javax.net.ssl.HostnameVerifier;
|
||||
|
||||
public class HostnameVerfifierFactory {
|
||||
private final HostnameVerifier noOpVerififer;
|
||||
|
||||
public HostnameVerifierFactory() {
|
||||
this.noOpVerififer = new HostnameVerifier() {
|
||||
public boolean verify(String hostname, SSLSession session) {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public HostnameVerifier getNoOpVerifier() {
|
||||
return this.noOpVerififer;
|
||||
}
|
||||
}
|
||||
48
src/android/com/silkimen/http/HttpBodyDecoder.java
Normal file
48
src/android/com/silkimen/http/HttpBodyDecoder.java
Normal file
@@ -0,0 +1,48 @@
|
||||
package com.silkimen.http;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.charset.CharacterCodingException;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.CharsetDecoder;
|
||||
import java.nio.charset.CodingErrorAction;
|
||||
import java.nio.charset.MalformedInputException;
|
||||
|
||||
public class HttpBodyDecoder {
|
||||
private static final String[] ACCEPTED_CHARSETS = new String[] { "UTF-8", "ISO-8859-1" };
|
||||
|
||||
public static String decodeBody(ByteBuffer rawOutput, String charsetName)
|
||||
throws CharacterCodingException, MalformedInputException {
|
||||
|
||||
if (charsetName == null) {
|
||||
return tryDecodeByteBuffer(rawOutput);
|
||||
}
|
||||
|
||||
return decodeByteBuffer(rawOutput, charsetName);
|
||||
}
|
||||
|
||||
private static String tryDecodeByteBuffer(ByteBuffer rawOutput) throws CharacterCodingException, MalformedInputException {
|
||||
|
||||
for (int i = 0; i < ACCEPTED_CHARSETS.length - 1; i++) {
|
||||
try {
|
||||
return decodeByteBuffer(rawOutput, ACCEPTED_CHARSETS[i]);
|
||||
} catch (MalformedInputException e) {
|
||||
continue;
|
||||
} catch (CharacterCodingException e) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
return decodeBody(rawOutput, ACCEPTED_CHARSETS[ACCEPTED_CHARSETS.length - 1]);
|
||||
}
|
||||
|
||||
private static String decodeByteBuffer(ByteBuffer rawOutput, String charsetName)
|
||||
throws CharacterCodingException, MalformedInputException {
|
||||
|
||||
return createCharsetDecoder(charsetName).decode(rawOutput).toString();
|
||||
}
|
||||
|
||||
private static CharsetDecoder createCharsetDecoder(String charsetName) {
|
||||
return Charset.forName(charsetName).newDecoder().onMalformedInput(CodingErrorAction.REPORT)
|
||||
.onUnmappableCharacter(CodingErrorAction.REPORT);
|
||||
}
|
||||
}
|
||||
3095
src/android/com/silkimen/http/HttpRequest.java
Normal file
3095
src/android/com/silkimen/http/HttpRequest.java
Normal file
File diff suppressed because it is too large
Load Diff
80
src/android/com/silkimen/http/HttpResponse.java
Normal file
80
src/android/com/silkimen/http/HttpResponse.java
Normal file
@@ -0,0 +1,80 @@
|
||||
package com.silkimen.http;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
|
||||
public class HttpResponse {
|
||||
private int status;
|
||||
private String url;
|
||||
private Map<String, List<String>> headers;
|
||||
private String body;
|
||||
private boolean failed;
|
||||
private String error;
|
||||
|
||||
public void setStatus(int status) {
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
public void setUrl(String url) {
|
||||
this.url = url;
|
||||
}
|
||||
|
||||
public void setHeaders(Map<String, List<String>> headers) {
|
||||
this.headers = headers;
|
||||
}
|
||||
|
||||
public void setBody(String body) {
|
||||
this.body = body;
|
||||
}
|
||||
|
||||
public void setErrorMessage(String message) {
|
||||
this.failed = true;
|
||||
this.error = message;
|
||||
}
|
||||
|
||||
public boolean hasFailed() {
|
||||
return this.failed;
|
||||
}
|
||||
|
||||
public JSONObject toJSON() throws JSONException {
|
||||
JSONObject json = new JSONObject();
|
||||
|
||||
json.put("status", this.status);
|
||||
json.put("url", this.url);
|
||||
|
||||
if (this.failed) {
|
||||
json.put("error", this.error);
|
||||
} else {
|
||||
json.put("headers", new JSONObject(getFilteredHeaders()));
|
||||
json.put("data", this.body);
|
||||
}
|
||||
|
||||
return json;
|
||||
}
|
||||
|
||||
private Map<String, String> getFilteredHeaders() throws JSONException {
|
||||
Map<String, String> filteredHeaders = new HashMap<String, String>();
|
||||
|
||||
if (this.headers == null || this.headers.isEmpty()) {
|
||||
return filteredHeaders;
|
||||
}
|
||||
|
||||
for (Map.Entry<String, List<String>> entry : this.headers.entrySet()) {
|
||||
String key = entry.getKey();
|
||||
List<String> value = entry.getValue();
|
||||
|
||||
if ((key != null) && (!value.isEmpty())) {
|
||||
filteredHeaders.put(key.toLowerCase(), TextUtils.join(", ", value));
|
||||
}
|
||||
}
|
||||
|
||||
return filteredHeaders;
|
||||
}
|
||||
}
|
||||
58
src/android/com/silkimen/http/JsonUtils.java
Normal file
58
src/android/com/silkimen/http/JsonUtils.java
Normal file
@@ -0,0 +1,58 @@
|
||||
package com.silkimen.http;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
public class JsonUtils {
|
||||
public static HashMap<String, String> getStringMap(JSONObject object) throws JSONException {
|
||||
HashMap<String, String> map = new HashMap<String, String>();
|
||||
|
||||
if (object == null) {
|
||||
return map;
|
||||
}
|
||||
|
||||
Iterator<?> i = object.keys();
|
||||
|
||||
while (i.hasNext()) {
|
||||
String key = (String) i.next();
|
||||
map.put(key, object.getString(key));
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
public static HashMap<String, Object> getObjectMap(JSONObject object) throws JSONException {
|
||||
HashMap<String, Object> map = new HashMap<String, Object>();
|
||||
|
||||
if (object == null) {
|
||||
return map;
|
||||
}
|
||||
|
||||
Iterator<?> i = object.keys();
|
||||
|
||||
while (i.hasNext()) {
|
||||
String key = (String) i.next();
|
||||
Object value = object.get(key);
|
||||
|
||||
if (value instanceof JSONArray) {
|
||||
map.put(key, getObjectList((JSONArray) value));
|
||||
} else {
|
||||
map.put(key, object.get(key));
|
||||
}
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
public static ArrayList<Object> getObjectList(JSONArray array) throws JSONException {
|
||||
ArrayList<Object> list = new ArrayList<Object>();
|
||||
|
||||
for (int i = 0; i < array.length(); i++) {
|
||||
list.add(array.get(i));
|
||||
}
|
||||
return list;
|
||||
}
|
||||
}
|
||||
34
src/android/com/silkimen/http/OkConnectionFactory.java
Normal file
34
src/android/com/silkimen/http/OkConnectionFactory.java
Normal file
@@ -0,0 +1,34 @@
|
||||
package com.silkimen.http;
|
||||
|
||||
import okhttp3.OkUrlFactory;
|
||||
import okhttp3.OkHttpClient;
|
||||
|
||||
/**
|
||||
* A {@link HttpRequest.ConnectionFactory connection factory} which uses OkHttp.
|
||||
* <p/>
|
||||
* Call {@link HttpRequest#setConnectionFactory(HttpRequest.ConnectionFactory)}
|
||||
* with an instance of this class to enable.
|
||||
*/
|
||||
public class OkConnectionFactory implements HttpRequest.ConnectionFactory {
|
||||
private final OkHttpClient client;
|
||||
|
||||
public OkConnectionFactory() {
|
||||
this(new OkHttpClient());
|
||||
}
|
||||
|
||||
public OkConnectionFactory(OkHttpClient client) {
|
||||
if (client == null) {
|
||||
throw new NullPointerException("Client must not be null.");
|
||||
}
|
||||
this.client = client;
|
||||
}
|
||||
|
||||
public HttpURLConnection create(URL url) throws IOException {
|
||||
return client.open(url);
|
||||
}
|
||||
|
||||
public HttpURLConnection create(URL url, Proxy proxy) throws IOException {
|
||||
throw new UnsupportedOperationException(
|
||||
"Per-connection proxy is not supported. Use OkHttpClient's setProxy instead.");
|
||||
}
|
||||
}
|
||||
25
src/android/com/silkimen/http/OkConnectionFactory_chax.java
Normal file
25
src/android/com/silkimen/http/OkConnectionFactory_chax.java
Normal file
@@ -0,0 +1,25 @@
|
||||
package com.github.kevinsawicki.http;
|
||||
|
||||
import okhttp3.OkUrlFactory;
|
||||
import okhttp3.OkHttpClient;
|
||||
|
||||
import java.net.URL;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URLStreamHandler;
|
||||
import java.net.Proxy;
|
||||
|
||||
public class OkConnectionFactory implements HttpRequest.ConnectionFactory {
|
||||
|
||||
protected OkHttpClient okHttpClient = new OkHttpClient();
|
||||
|
||||
public HttpURLConnection create(URL url) {
|
||||
OkUrlFactory okUrlFactory = new OkUrlFactory(okHttpClient);
|
||||
return (HttpURLConnection) okUrlFactory.open(url);
|
||||
}
|
||||
|
||||
public HttpURLConnection create(URL url, Proxy proxy) {
|
||||
OkHttpClient okHttpClientWithProxy = okHttpClient.newBuilder().proxy(proxy).build();
|
||||
OkUrlFactory okUrlFactory = new OkUrlFactory(okHttpClientWithProxy);
|
||||
return (HttpURLConnection) okUrlFactory.open(url);
|
||||
}
|
||||
}
|
||||
63
src/android/com/silkimen/http/TLSSocketFactory.java
Normal file
63
src/android/com/silkimen/http/TLSSocketFactory.java
Normal file
@@ -0,0 +1,63 @@
|
||||
package com.silkimen.http;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.InetAddress;
|
||||
import java.net.Socket;
|
||||
import java.net.UnknownHostException;
|
||||
|
||||
import javax.net.ssl.SSLContext;
|
||||
import javax.net.ssl.SSLSocket;
|
||||
import javax.net.ssl.SSLSocketFactory;
|
||||
|
||||
public class TLSSocketFactory extends SSLSocketFactory {
|
||||
|
||||
private SSLSocketFactory delegate;
|
||||
|
||||
public TLSSocketFactory(SSLContext context) {
|
||||
delegate = context.getSocketFactory();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getDefaultCipherSuites() {
|
||||
return delegate.getDefaultCipherSuites();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getSupportedCipherSuites() {
|
||||
return delegate.getSupportedCipherSuites();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Socket createSocket(Socket s, String host, int port, boolean autoClose) throws IOException {
|
||||
return enableTLSOnSocket(delegate.createSocket(s, host, port, autoClose));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Socket createSocket(String host, int port) throws IOException, UnknownHostException {
|
||||
return enableTLSOnSocket(delegate.createSocket(host, port));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Socket createSocket(String host, int port, InetAddress localHost, int localPort)
|
||||
throws IOException, UnknownHostException {
|
||||
return enableTLSOnSocket(delegate.createSocket(host, port, localHost, localPort));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Socket createSocket(InetAddress host, int port) throws IOException {
|
||||
return enableTLSOnSocket(delegate.createSocket(host, port));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Socket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort)
|
||||
throws IOException {
|
||||
return enableTLSOnSocket(delegate.createSocket(address, port, localAddress, localPort));
|
||||
}
|
||||
|
||||
private Socket enableTLSOnSocket(Socket socket) {
|
||||
if (socket != null && (socket instanceof SSLSocket)) {
|
||||
((SSLSocket) socket).setEnabledProtocols(new String[] { "TLSv1", "TLSv1.1", "TLSv1.2" });
|
||||
}
|
||||
return socket;
|
||||
}
|
||||
}
|
||||
59
src/android/com/silkimen/http/TrustManagersFactory.java
Normal file
59
src/android/com/silkimen/http/TrustManagersFactory.java
Normal file
@@ -0,0 +1,59 @@
|
||||
package com.silkimen.http;
|
||||
|
||||
import java.security.KeyStore;
|
||||
import java.security.cert.Certificate;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import javax.net.ssl.TrustManagerFactory;
|
||||
import javax.net.ssl.X509TrustManager;
|
||||
|
||||
public class TrustManagersFactory {
|
||||
private final TrustManager[] noOpTrustManager;
|
||||
|
||||
public TrustManagersFactory() {
|
||||
this.noOpTrustManager = new TrustManager[] { new X509TrustManager() {
|
||||
public X509Certificate[] getAcceptedIssuers() {
|
||||
return new X509Certificate[0];
|
||||
}
|
||||
|
||||
public void checkClientTrusted(X509Certificate[] chain, String authType) {
|
||||
// Intentionally left blank
|
||||
}
|
||||
|
||||
public void checkServerTrusted(X509Certificate[] chain, String authType) {
|
||||
// Intentionally left blank
|
||||
}
|
||||
} };
|
||||
}
|
||||
|
||||
public TrustManager[] getNoopTrustManagers() {
|
||||
return this.noOpTrustManager;
|
||||
}
|
||||
|
||||
public TrustManager[] getPinnedTrustManagers(ArrayList<Certificate> pinnedCerts) throws IOException {
|
||||
if (pinnedCerts == null || pinnedCerts.size() == 0) {
|
||||
throw new IOException("You must add at least 1 certificate in order to pin to certificates");
|
||||
}
|
||||
|
||||
try {
|
||||
String keyStoreType = KeyStore.getDefaultType();
|
||||
KeyStore keyStore = KeyStore.getInstance(keyStoreType);
|
||||
keyStore.load(null, null);
|
||||
|
||||
for (int i = 0; i < pinnedCerts.size(); i++) {
|
||||
keyStore.setCertificateEntry("CA" + i, pinnedCerts.get(i));
|
||||
}
|
||||
|
||||
// Create a TrustManager that trusts the CAs in our KeyStore
|
||||
String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
|
||||
TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
|
||||
tmf.init(keyStore);
|
||||
|
||||
return tmf.getTrustManagers();
|
||||
} catch (GeneralSecurityException e) {
|
||||
IOException ioException = new IOException("Security exception configuring SSL trust managers");
|
||||
ioException.initCause(e);
|
||||
throw new HttpRequestException(ioException);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -12,12 +12,10 @@ import org.json.JSONObject;
|
||||
import java.net.SocketTimeoutException;
|
||||
import java.net.UnknownHostException;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import java.nio.charset.CharacterCodingException;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.CharsetDecoder;
|
||||
import java.nio.charset.CodingErrorAction;
|
||||
import java.nio.charset.MalformedInputException;
|
||||
|
||||
import javax.net.ssl.SSLHandshakeException;
|
||||
@@ -32,251 +30,220 @@ import java.util.Iterator;
|
||||
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.github.kevinsawicki.http.HttpRequest;
|
||||
import com.github.kevinsawicki.http.HttpRequest.HttpRequestException;
|
||||
import com.silkimen.http.HttpBodyDecoder;
|
||||
import com.silkimen.http.HttpRequest;
|
||||
import com.silkimen.http.HttpRequest.HttpRequestException;
|
||||
|
||||
abstract class CordovaHttp {
|
||||
protected static final String TAG = "CordovaHTTP";
|
||||
protected static final String[] ACCEPTED_CHARSETS = new String[] { HttpRequest.CHARSET_UTF8, HttpRequest.CHARSET_LATIN1 };
|
||||
private static AtomicBoolean disableRedirect = new AtomicBoolean(false);
|
||||
protected static final String TAG = "CordovaHTTP";
|
||||
private static AtomicBoolean disableRedirect = new AtomicBoolean(false);
|
||||
|
||||
private String urlString;
|
||||
private Object params;
|
||||
private String serializerName;
|
||||
private JSONObject headers;
|
||||
private int timeoutInMilliseconds;
|
||||
private CallbackContext callbackContext;
|
||||
private String urlString;
|
||||
private Object params;
|
||||
private String serializerName;
|
||||
private JSONObject headers;
|
||||
private int timeoutInMilliseconds;
|
||||
private CallbackContext callbackContext;
|
||||
|
||||
public CordovaHttp(String urlString, Object params, JSONObject headers, int timeout, CallbackContext callbackContext) {
|
||||
this(urlString, params, "default", headers, timeout, callbackContext);
|
||||
public CordovaHttp(String urlString, Object params, JSONObject headers, int timeout,
|
||||
CallbackContext callbackContext) {
|
||||
this(urlString, params, "default", headers, timeout, callbackContext);
|
||||
}
|
||||
|
||||
public CordovaHttp(String urlString, Object params, String serializerName, JSONObject headers, int timeout,
|
||||
CallbackContext callbackContext) {
|
||||
this.urlString = urlString;
|
||||
this.params = params;
|
||||
this.serializerName = serializerName;
|
||||
this.headers = headers;
|
||||
this.timeoutInMilliseconds = timeout;
|
||||
this.callbackContext = callbackContext;
|
||||
|
||||
|
||||
}
|
||||
|
||||
public static void disableRedirect(boolean disable) {
|
||||
disableRedirect.set(disable);
|
||||
}
|
||||
|
||||
protected String getUrlString() {
|
||||
return this.urlString;
|
||||
}
|
||||
|
||||
protected Object getParamsObject() {
|
||||
return this.params;
|
||||
}
|
||||
|
||||
protected String getSerializerName() {
|
||||
return this.serializerName;
|
||||
}
|
||||
|
||||
protected HashMap<String, Object> getParamsMap() throws JSONException, Exception {
|
||||
if (this.params instanceof JSONObject) {
|
||||
return this.getMapFromJSONObject((JSONObject) this.params);
|
||||
} else {
|
||||
throw new Exception("unsupported params type, needs to be a JSON object");
|
||||
}
|
||||
}
|
||||
|
||||
protected JSONObject getHeadersObject() {
|
||||
return this.headers;
|
||||
}
|
||||
|
||||
protected HashMap<String, String> getHeadersMap() throws JSONException {
|
||||
return this.getStringMapFromJSONObject(this.headers);
|
||||
}
|
||||
|
||||
protected int getRequestTimeout() {
|
||||
return this.timeoutInMilliseconds;
|
||||
}
|
||||
|
||||
protected CallbackContext getCallbackContext() {
|
||||
return this.callbackContext;
|
||||
}
|
||||
|
||||
protected HttpRequest setupRedirect(HttpRequest request) {
|
||||
if (disableRedirect.get()) {
|
||||
request.followRedirects(false);
|
||||
}
|
||||
|
||||
public CordovaHttp(String urlString, Object params, String serializerName, JSONObject headers, int timeout, CallbackContext callbackContext) {
|
||||
this.urlString = urlString;
|
||||
this.params = params;
|
||||
this.serializerName = serializerName;
|
||||
this.headers = headers;
|
||||
this.timeoutInMilliseconds = timeout;
|
||||
this.callbackContext = callbackContext;
|
||||
return request;
|
||||
}
|
||||
|
||||
protected void setupDataSerializer(HttpRequest request) throws JSONException, Exception {
|
||||
if ("json".equals(this.getSerializerName())) {
|
||||
request.contentType(request.CONTENT_TYPE_JSON, request.CHARSET_UTF8);
|
||||
} else if ("utf8".equals(this.getSerializerName())) {
|
||||
request.contentType("text/plain", request.CHARSET_UTF8);
|
||||
}
|
||||
}
|
||||
|
||||
public static void disableRedirect(boolean disable) {
|
||||
disableRedirect.set(disable);
|
||||
protected void respondWithError(int status, String msg) {
|
||||
try {
|
||||
JSONObject response = new JSONObject();
|
||||
response.put("status", status);
|
||||
response.put("error", msg);
|
||||
this.callbackContext.error(response);
|
||||
} catch (JSONException e) {
|
||||
this.callbackContext.error(msg);
|
||||
}
|
||||
}
|
||||
|
||||
protected String getUrlString() {
|
||||
return this.urlString;
|
||||
}
|
||||
protected void respondWithError(String msg) {
|
||||
this.respondWithError(-1, msg);
|
||||
}
|
||||
|
||||
protected Object getParamsObject() {
|
||||
return this.params;
|
||||
}
|
||||
protected void addResponseHeaders(HttpRequest request, JSONObject response) throws JSONException {
|
||||
Map<String, List<String>> headers = request.headers();
|
||||
Map<String, String> filteredHeaders = new HashMap<String, String>();
|
||||
|
||||
protected String getSerializerName() {
|
||||
return this.serializerName;
|
||||
}
|
||||
for (Map.Entry<String, List<String>> entry : headers.entrySet()) {
|
||||
String key = entry.getKey();
|
||||
List<String> value = entry.getValue();
|
||||
|
||||
protected HashMap<String, Object> getParamsMap() throws JSONException, Exception {
|
||||
if (this.params instanceof JSONObject) {
|
||||
return this.getMapFromJSONObject((JSONObject) this.params);
|
||||
} else {
|
||||
throw new Exception("unsupported params type, needs to be a JSON object");
|
||||
}
|
||||
}
|
||||
|
||||
protected JSONObject getHeadersObject() {
|
||||
return this.headers;
|
||||
}
|
||||
|
||||
protected HashMap<String, String> getHeadersMap() throws JSONException {
|
||||
return this.getStringMapFromJSONObject(this.headers);
|
||||
}
|
||||
|
||||
protected int getRequestTimeout() {
|
||||
return this.timeoutInMilliseconds;
|
||||
}
|
||||
|
||||
protected CallbackContext getCallbackContext() {
|
||||
return this.callbackContext;
|
||||
}
|
||||
|
||||
protected HttpRequest setupRedirect(HttpRequest request) {
|
||||
if (disableRedirect.get()) {
|
||||
request.followRedirects(false);
|
||||
}
|
||||
|
||||
return request;
|
||||
}
|
||||
|
||||
protected void setupDataSerializer(HttpRequest request) throws JSONException, Exception {
|
||||
if ("json".equals(this.getSerializerName())) {
|
||||
request.contentType(request.CONTENT_TYPE_JSON, request.CHARSET_UTF8);
|
||||
} else if ("utf8".equals(this.getSerializerName())) {
|
||||
request.contentType("text/plain", request.CHARSET_UTF8);
|
||||
if ((key != null) && (!value.isEmpty())) {
|
||||
filteredHeaders.put(key.toLowerCase(), TextUtils.join(", ", value));
|
||||
}
|
||||
}
|
||||
|
||||
protected void respondWithError(int status, String msg) {
|
||||
try {
|
||||
JSONObject response = new JSONObject();
|
||||
response.put("status", status);
|
||||
response.put("error", msg);
|
||||
this.callbackContext.error(response);
|
||||
} catch (JSONException e) {
|
||||
this.callbackContext.error(msg);
|
||||
}
|
||||
response.put("headers", new JSONObject(filteredHeaders));
|
||||
}
|
||||
|
||||
protected HashMap<String, String> getStringMapFromJSONObject(JSONObject object) throws JSONException {
|
||||
HashMap<String, String> map = new HashMap<String, String>();
|
||||
Iterator<?> i = object.keys();
|
||||
|
||||
while (i.hasNext()) {
|
||||
String key = (String) i.next();
|
||||
map.put(key, object.getString(key));
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
protected void respondWithError(String msg) {
|
||||
this.respondWithError(-1, msg);
|
||||
protected ArrayList<Object> getListFromJSONArray(JSONArray array) throws JSONException {
|
||||
ArrayList<Object> list = new ArrayList<Object>();
|
||||
|
||||
for (int i = 0; i < array.length(); i++) {
|
||||
list.add(array.get(i));
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
protected void addResponseHeaders(HttpRequest request, JSONObject response) throws JSONException {
|
||||
Map<String, List<String>> headers = request.headers();
|
||||
Map<String, String> filteredHeaders = new HashMap<String, String>();
|
||||
protected HashMap<String, Object> getMapFromJSONObject(JSONObject object) throws JSONException {
|
||||
HashMap<String, Object> map = new HashMap<String, Object>();
|
||||
Iterator<?> i = object.keys();
|
||||
|
||||
for (Map.Entry<String, List<String>> entry : headers.entrySet()) {
|
||||
String key = entry.getKey();
|
||||
List<String> value = entry.getValue();
|
||||
while (i.hasNext()) {
|
||||
String key = (String) i.next();
|
||||
Object value = object.get(key);
|
||||
|
||||
if ((key != null) && (!value.isEmpty())) {
|
||||
filteredHeaders.put(key.toLowerCase(), TextUtils.join(", ", value));
|
||||
}
|
||||
}
|
||||
|
||||
response.put("headers", new JSONObject(filteredHeaders));
|
||||
}
|
||||
|
||||
protected HashMap<String, String> getStringMapFromJSONObject(JSONObject object) throws JSONException {
|
||||
HashMap<String, String> map = new HashMap<String, String>();
|
||||
Iterator<?> i = object.keys();
|
||||
|
||||
while (i.hasNext()) {
|
||||
String key = (String)i.next();
|
||||
map.put(key, object.getString(key));
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
protected ArrayList<Object> getListFromJSONArray(JSONArray array) throws JSONException {
|
||||
ArrayList<Object> list = new ArrayList<Object>();
|
||||
|
||||
for (int i = 0; i < array.length(); i++) {
|
||||
list.add(array.get(i));
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
protected HashMap<String, Object> getMapFromJSONObject(JSONObject object) throws JSONException {
|
||||
HashMap<String, Object> map = new HashMap<String, Object>();
|
||||
Iterator<?> i = object.keys();
|
||||
|
||||
while(i.hasNext()) {
|
||||
String key = (String)i.next();
|
||||
Object value = object.get(key);
|
||||
|
||||
if (value instanceof JSONArray) {
|
||||
map.put(key, getListFromJSONArray((JSONArray)value));
|
||||
} else {
|
||||
map.put(key, object.get(key));
|
||||
}
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
protected void prepareRequest(HttpRequest request) throws HttpRequestException, JSONException {
|
||||
this.setupRedirect(request);
|
||||
|
||||
request.readTimeout(this.getRequestTimeout());
|
||||
request.acceptCharset(ACCEPTED_CHARSETS);
|
||||
request.headers(this.getHeadersMap());
|
||||
request.uncompress(true);
|
||||
}
|
||||
|
||||
protected void prepareRequestBody(HttpRequest request) throws JSONException, Exception {
|
||||
if ("json".equals(this.getSerializerName())) {
|
||||
request.send(this.getParamsObject().toString());
|
||||
} else if ("utf8".equals(this.getSerializerName())) {
|
||||
request.send(this.getParamsMap().get("text").toString());
|
||||
if (value instanceof JSONArray) {
|
||||
map.put(key, getListFromJSONArray((JSONArray) value));
|
||||
} else {
|
||||
request.form(this.getParamsMap());
|
||||
map.put(key, object.get(key));
|
||||
}
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
private CharsetDecoder createCharsetDecoder(final String charsetName) {
|
||||
return Charset.forName(charsetName).newDecoder()
|
||||
.onMalformedInput(CodingErrorAction.REPORT)
|
||||
.onUnmappableCharacter(CodingErrorAction.REPORT);
|
||||
protected void prepareRequest(HttpRequest request) throws HttpRequestException, JSONException {
|
||||
this.setupRedirect(request);
|
||||
|
||||
request.readTimeout(this.getRequestTimeout());
|
||||
// request.acceptCharset(ACCEPTED_CHARSETS);
|
||||
request.headers(this.getHeadersMap());
|
||||
request.uncompress(true);
|
||||
}
|
||||
|
||||
protected void prepareRequestBody(HttpRequest request) throws JSONException, Exception {
|
||||
if ("json".equals(this.getSerializerName())) {
|
||||
request.send(this.getParamsObject().toString());
|
||||
} else if ("utf8".equals(this.getSerializerName())) {
|
||||
request.send(this.getParamsMap().get("text").toString());
|
||||
} else {
|
||||
request.form(this.getParamsMap());
|
||||
}
|
||||
}
|
||||
|
||||
private String decodeBody(AtomicReference<ByteBuffer> rawOutput, String charsetName)
|
||||
throws CharacterCodingException, MalformedInputException {
|
||||
protected void returnResponseObject(HttpRequest request) throws HttpRequestException {
|
||||
try {
|
||||
JSONObject response = new JSONObject();
|
||||
int code = request.code();
|
||||
|
||||
if (charsetName == null) {
|
||||
return tryDecodeByteBuffer(rawOutput);
|
||||
}
|
||||
final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
||||
request.receive(outputStream);
|
||||
ByteBuffer rawOutput = ByteBuffer.wrap(outputStream.toByteArray());
|
||||
|
||||
return decodeByteBuffer(rawOutput, charsetName);
|
||||
}
|
||||
//request.body(rawOutput);
|
||||
response.put("status", code);
|
||||
response.put("url", request.url().toString());
|
||||
this.addResponseHeaders(request, response);
|
||||
|
||||
private String tryDecodeByteBuffer(AtomicReference<ByteBuffer> rawOutput)
|
||||
throws CharacterCodingException, MalformedInputException {
|
||||
|
||||
for (int i = 0; i < ACCEPTED_CHARSETS.length - 1; i++) {
|
||||
try {
|
||||
return decodeByteBuffer(rawOutput, ACCEPTED_CHARSETS[i]);
|
||||
} catch (MalformedInputException e) {
|
||||
continue;
|
||||
} catch (CharacterCodingException e) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
return decodeBody(rawOutput, ACCEPTED_CHARSETS[ACCEPTED_CHARSETS.length - 1]);
|
||||
}
|
||||
|
||||
private String decodeByteBuffer(AtomicReference<ByteBuffer> rawOutput, String charsetName)
|
||||
throws CharacterCodingException, MalformedInputException {
|
||||
|
||||
return createCharsetDecoder(charsetName).decode(rawOutput.get()).toString();
|
||||
}
|
||||
|
||||
protected void returnResponseObject(HttpRequest request) throws HttpRequestException {
|
||||
try {
|
||||
JSONObject response = new JSONObject();
|
||||
int code = request.code();
|
||||
AtomicReference<ByteBuffer> rawOutputReference = new AtomicReference<ByteBuffer>();
|
||||
|
||||
request.body(rawOutputReference);
|
||||
response.put("status", code);
|
||||
response.put("url", request.url().toString());
|
||||
this.addResponseHeaders(request, response);
|
||||
|
||||
if (code >= 200 && code < 300) {
|
||||
response.put("data", decodeBody(rawOutputReference, request.charset()));
|
||||
this.getCallbackContext().success(response);
|
||||
} else {
|
||||
response.put("error", decodeBody(rawOutputReference, request.charset()));
|
||||
this.getCallbackContext().error(response);
|
||||
}
|
||||
} catch(JSONException e) {
|
||||
this.respondWithError("There was an error generating the response");
|
||||
} catch(MalformedInputException e) {
|
||||
this.respondWithError("Could not decode response data due to malformed data");
|
||||
} catch(CharacterCodingException e) {
|
||||
this.respondWithError("Could not decode response data due to invalid or unknown charset encoding");
|
||||
}
|
||||
}
|
||||
|
||||
protected void handleHttpRequestException(HttpRequestException e) {
|
||||
if (e.getCause() instanceof UnknownHostException) {
|
||||
this.respondWithError(0, "The host could not be resolved: " + e.getMessage());
|
||||
} else if (e.getCause() instanceof SocketTimeoutException) {
|
||||
this.respondWithError(1, "The request timed out: " + e.getMessage());
|
||||
} else if (e.getCause() instanceof SSLHandshakeException) {
|
||||
this.respondWithError(-2, "SSL handshake failed: " + e.getMessage());
|
||||
if (code >= 200 && code < 300) {
|
||||
response.put("data", HttpBodyDecoder.decodeBody(rawOutput, request.charset()));
|
||||
this.getCallbackContext().success(response);
|
||||
} else {
|
||||
this.respondWithError("There was an error with the request: " + e.getMessage());
|
||||
response.put("error", HttpBodyDecoder.decodeBody(rawOutput, request.charset()));
|
||||
this.getCallbackContext().error(response);
|
||||
}
|
||||
} catch (JSONException e) {
|
||||
this.respondWithError("There was an error generating the response");
|
||||
} catch (MalformedInputException e) {
|
||||
this.respondWithError("Could not decode response data due to malformed data");
|
||||
} catch (CharacterCodingException e) {
|
||||
this.respondWithError("Could not decode response data due to invalid or unknown charset encoding");
|
||||
}
|
||||
}
|
||||
|
||||
protected void handleHttpRequestException(HttpRequestException e) {
|
||||
if (e.getCause() instanceof UnknownHostException) {
|
||||
this.respondWithError(0, "The host could not be resolved: " + e.getMessage());
|
||||
} else if (e.getCause() instanceof SocketTimeoutException) {
|
||||
this.respondWithError(1, "The request timed out: " + e.getMessage());
|
||||
} else if (e.getCause() instanceof SSLHandshakeException) {
|
||||
this.respondWithError(-2, "SSL handshake failed: " + e.getMessage());
|
||||
} else {
|
||||
this.respondWithError("There was an error with the request: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,8 +13,8 @@ import org.apache.cordova.CallbackContext;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import com.github.kevinsawicki.http.HttpRequest;
|
||||
import com.github.kevinsawicki.http.HttpRequest.HttpRequestException;
|
||||
import com.silkimen.http.HttpRequest;
|
||||
import com.silkimen.http.HttpRequest.HttpRequestException;
|
||||
|
||||
class CordovaHttpDelete extends CordovaHttp implements Runnable {
|
||||
public CordovaHttpDelete(String urlString, Object data, JSONObject headers, int timeout, CallbackContext callbackContext) {
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
*/
|
||||
package com.synconset.cordovahttp;
|
||||
|
||||
import com.github.kevinsawicki.http.HttpRequest;
|
||||
import com.github.kevinsawicki.http.HttpRequest.HttpRequestException;
|
||||
import com.silkimen.http.HttpRequest;
|
||||
import com.silkimen.http.HttpRequest.HttpRequestException;
|
||||
|
||||
import java.io.File;
|
||||
import java.net.SocketTimeoutException;
|
||||
|
||||
@@ -1,37 +0,0 @@
|
||||
/**
|
||||
* A HTTP plugin for Cordova / Phonegap
|
||||
*/
|
||||
package com.synconset.cordovahttp;
|
||||
|
||||
import java.net.SocketTimeoutException;
|
||||
import java.net.UnknownHostException;
|
||||
|
||||
import javax.net.ssl.SSLHandshakeException;
|
||||
|
||||
import org.apache.cordova.CallbackContext;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import com.github.kevinsawicki.http.HttpRequest;
|
||||
import com.github.kevinsawicki.http.HttpRequest.HttpRequestException;
|
||||
|
||||
class CordovaHttpGet extends CordovaHttp implements Runnable {
|
||||
public CordovaHttpGet(String urlString, Object params, JSONObject headers, int timeout, CallbackContext callbackContext) {
|
||||
super(urlString, params, headers, timeout, callbackContext);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
HttpRequest request = HttpRequest.get(this.getUrlString(), this.getParamsMap(), false);
|
||||
|
||||
this.prepareRequest(request);
|
||||
this.returnResponseObject(request);
|
||||
} catch (HttpRequestException e) {
|
||||
this.handleHttpRequestException(e);
|
||||
} catch (Exception e) {
|
||||
this.respondWithError(e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -12,8 +12,8 @@ import org.apache.cordova.CallbackContext;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import com.github.kevinsawicki.http.HttpRequest;
|
||||
import com.github.kevinsawicki.http.HttpRequest.HttpRequestException;
|
||||
import com.silkimen.http.HttpRequest;
|
||||
import com.silkimen.http.HttpRequest.HttpRequestException;
|
||||
|
||||
class CordovaHttpHead extends CordovaHttp implements Runnable {
|
||||
public CordovaHttpHead(String urlString, Object params, JSONObject headers, int timeout, CallbackContext callbackContext) {
|
||||
|
||||
@@ -12,8 +12,8 @@ import org.json.JSONObject;
|
||||
|
||||
import javax.net.ssl.SSLHandshakeException;
|
||||
|
||||
import com.github.kevinsawicki.http.HttpRequest;
|
||||
import com.github.kevinsawicki.http.HttpRequest.HttpRequestException;
|
||||
import com.silkimen.http.HttpRequest;
|
||||
import com.silkimen.http.HttpRequest.HttpRequestException;
|
||||
|
||||
class CordovaHttpPatch extends CordovaHttp implements Runnable {
|
||||
public CordovaHttpPatch(String urlString, Object params, String serializerName, JSONObject headers, int timeout, CallbackContext callbackContext) {
|
||||
@@ -23,7 +23,8 @@ class CordovaHttpPatch extends CordovaHttp implements Runnable {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
HttpRequest request = HttpRequest.patch(this.getUrlString());
|
||||
/* todo */
|
||||
HttpRequest request = HttpRequest.get(this.getUrlString());
|
||||
|
||||
this.setupDataSerializer(request);
|
||||
this.prepareRequest(request);
|
||||
|
||||
@@ -26,7 +26,8 @@ import org.json.JSONObject;
|
||||
|
||||
import android.content.res.AssetManager;
|
||||
|
||||
import com.github.kevinsawicki.http.HttpRequest;
|
||||
import com.silkimen.http.HttpRequest;
|
||||
import com.silkimen.cordovahttp.CordovaHttpRequest;
|
||||
|
||||
public class CordovaHttpPlugin extends CordovaPlugin {
|
||||
private static final String TAG = "CordovaHTTP";
|
||||
@@ -36,7 +37,7 @@ public class CordovaHttpPlugin extends CordovaPlugin {
|
||||
super.initialize(cordova, webView);
|
||||
|
||||
try {
|
||||
HttpRequest.clearCerts();
|
||||
//HttpRequest.clearCerts();
|
||||
this.pinSSLCertsFromCAStore();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
@@ -47,72 +48,78 @@ public class CordovaHttpPlugin extends CordovaPlugin {
|
||||
@Override
|
||||
public boolean execute(String action, final JSONArray args, final CallbackContext callbackContext) throws JSONException {
|
||||
if (action.equals("post")) {
|
||||
String urlString = args.getString(0);
|
||||
Object params = args.get(1);
|
||||
String serializerName = args.getString(2);
|
||||
String url = args.getString(0);
|
||||
Object data = args.get(1);
|
||||
String serializer = args.getString(2);
|
||||
JSONObject headers = args.getJSONObject(3);
|
||||
int timeoutInMilliseconds = args.getInt(4) * 1000;
|
||||
CordovaHttpPost post = new CordovaHttpPost(urlString, params, serializerName, headers, timeoutInMilliseconds, callbackContext);
|
||||
int timeout = args.getInt(4) * 1000;
|
||||
|
||||
CordovaHttpRequest post = new CordovaHttpRequest("POST", url, serializer, data, headers, timeout, callbackContext);
|
||||
|
||||
cordova.getThreadPool().execute(post);
|
||||
} else if (action.equals("get")) {
|
||||
String urlString = args.getString(0);
|
||||
Object params = args.get(1);
|
||||
String url = args.getString(0);
|
||||
JSONObject params = args.getJSONObject(1);
|
||||
JSONObject headers = args.getJSONObject(2);
|
||||
int timeoutInMilliseconds = args.getInt(3) * 1000;
|
||||
CordovaHttpGet get = new CordovaHttpGet(urlString, params, headers, timeoutInMilliseconds, callbackContext);
|
||||
int timeout = args.getInt(3) * 1000;
|
||||
|
||||
CordovaHttpRequest get = new CordovaHttpRequest("GET", url, params, headers, timeout, callbackContext);
|
||||
|
||||
cordova.getThreadPool().execute(get);
|
||||
} else if (action.equals("put")) {
|
||||
String urlString = args.getString(0);
|
||||
Object params = args.get(1);
|
||||
String serializerName = args.getString(2);
|
||||
String url = args.getString(0);
|
||||
Object data = args.get(1);
|
||||
String serializer = args.getString(2);
|
||||
JSONObject headers = args.getJSONObject(3);
|
||||
int timeoutInMilliseconds = args.getInt(4) * 1000;
|
||||
CordovaHttpPut put = new CordovaHttpPut(urlString, params, serializerName, headers, timeoutInMilliseconds, callbackContext);
|
||||
int timeout = args.getInt(4) * 1000;
|
||||
|
||||
CordovaHttpRequest put = new CordovaHttpRequest("PUT", url, serializer, data, headers, timeout, callbackContext);
|
||||
|
||||
cordova.getThreadPool().execute(put);
|
||||
} else if (action.equals("patch")) {
|
||||
String urlString = args.getString(0);
|
||||
Object params = args.get(1);
|
||||
String serializerName = args.getString(2);
|
||||
String url = args.getString(0);
|
||||
Object data = args.get(1);
|
||||
String serializer = args.getString(2);
|
||||
JSONObject headers = args.getJSONObject(3);
|
||||
int timeoutInMilliseconds = args.getInt(4) * 1000;
|
||||
CordovaHttpPatch patch = new CordovaHttpPatch(urlString, params, serializerName, headers, timeoutInMilliseconds, callbackContext);
|
||||
int timeout = args.getInt(4) * 1000;
|
||||
|
||||
CordovaHttpRequest patch = new CordovaHttpRequest("PATCH", url, serializer, data, headers, timeout, callbackContext);
|
||||
|
||||
cordova.getThreadPool().execute(patch);
|
||||
}
|
||||
else if (action.equals("delete")) {
|
||||
String urlString = args.getString(0);
|
||||
Object params = args.get(1);
|
||||
String url = args.getString(0);
|
||||
JSONObject params = args.getJSONObject(1);
|
||||
JSONObject headers = args.getJSONObject(2);
|
||||
int timeoutInMilliseconds = args.getInt(3) * 1000;
|
||||
CordovaHttpDelete delete = new CordovaHttpDelete(urlString, params, headers, timeoutInMilliseconds, callbackContext);
|
||||
int timeout = args.getInt(3) * 1000;
|
||||
|
||||
CordovaHttpRequest delete = new CordovaHttpRequest("DELETE", url, params, headers, timeout, callbackContext);
|
||||
|
||||
cordova.getThreadPool().execute(delete);
|
||||
} else if (action.equals("head")) {
|
||||
String urlString = args.getString(0);
|
||||
Object params = args.get(1);
|
||||
String url = args.getString(0);
|
||||
JSONObject params = args.getJSONObject(1);
|
||||
JSONObject headers = args.getJSONObject(2);
|
||||
int timeoutInMilliseconds = args.getInt(3) * 1000;
|
||||
CordovaHttpHead head = new CordovaHttpHead(urlString, params, headers, timeoutInMilliseconds, callbackContext);
|
||||
int timeout = args.getInt(3) * 1000;
|
||||
|
||||
CordovaHttpRequest head = new CordovaHttpRequest("HEAD", url, params, headers, timeout, callbackContext);
|
||||
|
||||
cordova.getThreadPool().execute(head);
|
||||
} else if (action.equals("setSSLCertMode")) {
|
||||
String mode = args.getString(0);
|
||||
|
||||
HttpRequest.clearCerts();
|
||||
//HttpRequest.clearCerts();
|
||||
|
||||
if (mode.equals("legacy")) {
|
||||
HttpRequest.setSSLCertMode(HttpRequest.CERT_MODE_DEFAULT);
|
||||
//HttpRequest.setSSLCertMode(HttpRequest.CERT_MODE_DEFAULT);
|
||||
callbackContext.success();
|
||||
} else if (mode.equals("nocheck")) {
|
||||
HttpRequest.setSSLCertMode(HttpRequest.CERT_MODE_TRUSTALL);
|
||||
//HttpRequest.setSSLCertMode(HttpRequest.CERT_MODE_TRUSTALL);
|
||||
callbackContext.success();
|
||||
} else if (mode.equals("pinned")) {
|
||||
try {
|
||||
this.loadSSLCertsFromBundle();
|
||||
HttpRequest.setSSLCertMode(HttpRequest.CERT_MODE_PINNED);
|
||||
//HttpRequest.setSSLCertMode(HttpRequest.CERT_MODE_PINNED);
|
||||
callbackContext.success();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
@@ -128,22 +135,24 @@ public class CordovaHttpPlugin extends CordovaPlugin {
|
||||
}
|
||||
}
|
||||
} else if (action.equals("uploadFile")) {
|
||||
String urlString = args.getString(0);
|
||||
String url = args.getString(0);
|
||||
Object params = args.get(1);
|
||||
JSONObject headers = args.getJSONObject(2);
|
||||
String filePath = args.getString(3);
|
||||
String name = args.getString(4);
|
||||
int timeoutInMilliseconds = args.getInt(5) * 1000;
|
||||
CordovaHttpUpload upload = new CordovaHttpUpload(urlString, params, headers, filePath, name, timeoutInMilliseconds, callbackContext);
|
||||
int timeout = args.getInt(5) * 1000;
|
||||
|
||||
CordovaHttpUpload upload = new CordovaHttpUpload(url, params, headers, filePath, name, timeout, callbackContext);
|
||||
|
||||
cordova.getThreadPool().execute(upload);
|
||||
} else if (action.equals("downloadFile")) {
|
||||
String urlString = args.getString(0);
|
||||
String url = args.getString(0);
|
||||
Object params = args.get(1);
|
||||
JSONObject headers = args.getJSONObject(2);
|
||||
String filePath = args.getString(3);
|
||||
int timeoutInMilliseconds = args.getInt(4) * 1000;
|
||||
CordovaHttpDownload download = new CordovaHttpDownload(urlString, params, headers, filePath, timeoutInMilliseconds, callbackContext);
|
||||
int timeout = args.getInt(4) * 1000;
|
||||
|
||||
CordovaHttpDownload download = new CordovaHttpDownload(url, params, headers, filePath, timeout, callbackContext);
|
||||
|
||||
cordova.getThreadPool().execute(download);
|
||||
} else if (action.equals("disableRedirect")) {
|
||||
@@ -158,7 +167,7 @@ public class CordovaHttpPlugin extends CordovaPlugin {
|
||||
|
||||
private void pinSSLCertsFromCAStore() throws GeneralSecurityException, IOException {
|
||||
this.loadSSLCertsFromKeyStore("AndroidCAStore");
|
||||
HttpRequest.setSSLCertMode(HttpRequest.CERT_MODE_PINNED);
|
||||
//HttpRequest.setSSLCertMode(HttpRequest.CERT_MODE_PINNED);
|
||||
}
|
||||
|
||||
private void loadSSLCertsFromKeyStore(String storeType) throws GeneralSecurityException, IOException {
|
||||
@@ -170,7 +179,7 @@ public class CordovaHttpPlugin extends CordovaPlugin {
|
||||
String alias = aliases.nextElement();
|
||||
TrustedCertificateEntry certEntry = (TrustedCertificateEntry) ks.getEntry(alias, null);
|
||||
Certificate cert = certEntry.getTrustedCertificate();
|
||||
HttpRequest.addCert(cert);
|
||||
//HttpRequest.addCert(cert);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -191,7 +200,7 @@ public class CordovaHttpPlugin extends CordovaPlugin {
|
||||
for (int i = 0; i < cerFiles.size(); i++) {
|
||||
InputStream in = cordova.getActivity().getAssets().open(cerFiles.get(i));
|
||||
InputStream caInput = new BufferedInputStream(in);
|
||||
HttpRequest.addCert(caInput);
|
||||
//HttpRequest.addCert(caInput);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,8 +12,8 @@ import org.json.JSONObject;
|
||||
|
||||
import javax.net.ssl.SSLHandshakeException;
|
||||
|
||||
import com.github.kevinsawicki.http.HttpRequest;
|
||||
import com.github.kevinsawicki.http.HttpRequest.HttpRequestException;
|
||||
import com.silkimen.http.HttpRequest;
|
||||
import com.silkimen.http.HttpRequest.HttpRequestException;
|
||||
|
||||
class CordovaHttpPost extends CordovaHttp implements Runnable {
|
||||
public CordovaHttpPost(String urlString, Object params, String serializerName, JSONObject headers, int timeout, CallbackContext callbackContext) {
|
||||
|
||||
@@ -12,8 +12,8 @@ import org.json.JSONObject;
|
||||
|
||||
import javax.net.ssl.SSLHandshakeException;
|
||||
|
||||
import com.github.kevinsawicki.http.HttpRequest;
|
||||
import com.github.kevinsawicki.http.HttpRequest.HttpRequestException;
|
||||
import com.silkimen.http.HttpRequest;
|
||||
import com.silkimen.http.HttpRequest.HttpRequestException;
|
||||
|
||||
class CordovaHttpPut extends CordovaHttp implements Runnable {
|
||||
public CordovaHttpPut(String urlString, Object data, String serializerName, JSONObject headers, int timeout, CallbackContext callbackContext) {
|
||||
|
||||
@@ -23,8 +23,8 @@ import javax.net.ssl.SSLHandshakeException;
|
||||
|
||||
import android.webkit.MimeTypeMap;
|
||||
|
||||
import com.github.kevinsawicki.http.HttpRequest;
|
||||
import com.github.kevinsawicki.http.HttpRequest.HttpRequestException;
|
||||
import com.silkimen.http.HttpRequest;
|
||||
import com.silkimen.http.HttpRequest.HttpRequestException;
|
||||
|
||||
class CordovaHttpUpload extends CordovaHttp implements Runnable {
|
||||
private String filePath;
|
||||
@@ -70,7 +70,7 @@ class CordovaHttpUpload extends CordovaHttp implements Runnable {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
request.part(this.name, filename, mimeType, new File(uri));
|
||||
|
||||
this.returnResponseObject(request);
|
||||
|
||||
Reference in New Issue
Block a user