diff --git a/src/main/java/com/nutomic/syncthingandroid/http/GetTask.java b/src/main/java/com/nutomic/syncthingandroid/http/GetTask.java index c1ea42c9..32ceda1b 100644 --- a/src/main/java/com/nutomic/syncthingandroid/http/GetTask.java +++ b/src/main/java/com/nutomic/syncthingandroid/http/GetTask.java @@ -3,18 +3,17 @@ package com.nutomic.syncthingandroid.http; import android.util.Log; import android.util.Pair; -import javax.net.ssl.HttpsURLConnection; -import java.io.BufferedReader; import java.io.IOException; -import java.io.InputStreamReader; import java.net.URL; +import javax.net.ssl.HttpsURLConnection; + /** * Performs a GET request to the Syncthing API * Performs a GET request with no parameters to the URL in uri[0] with the path in uri[1] and * returns the result as a String. */ -public class GetTask extends RestTask { +public class GetTask extends RestTask { private static final String TAG = "GetTask"; @@ -28,7 +27,7 @@ public class GetTask extends RestTask { public static final String URI_EVENTS = "/rest/events"; public GetTask(URL url, String path, String httpsCertPath, String apiKey, - OnSuccessListener listener) { + OnSuccessListener listener) { super(url, path, httpsCertPath, apiKey, listener); } @@ -40,16 +39,7 @@ public class GetTask extends RestTask { try { HttpsURLConnection connection = openConnection(params); Log.v(TAG, "Calling Rest API at " + connection.getURL()); - connection.connect(); - BufferedReader br = new BufferedReader(new InputStreamReader(connection.getInputStream(), "UTF-8")); - String line; - String result = ""; - while ((line = br.readLine()) != null) { - result += line; - } - br.close(); - Log.v(TAG, "API call result: " + result); - return new Pair<>(true, result); + return connect(connection); } catch (IOException e) { Log.w(TAG, "Failed to call rest api", e); return new Pair<>(false, null); diff --git a/src/main/java/com/nutomic/syncthingandroid/http/PollWebGuiAvailableTask.java b/src/main/java/com/nutomic/syncthingandroid/http/PollWebGuiAvailableTask.java index bd8fd57e..9f95ce97 100644 --- a/src/main/java/com/nutomic/syncthingandroid/http/PollWebGuiAvailableTask.java +++ b/src/main/java/com/nutomic/syncthingandroid/http/PollWebGuiAvailableTask.java @@ -4,14 +4,15 @@ package com.nutomic.syncthingandroid.http; import android.util.Log; import android.util.Pair; -import javax.net.ssl.HttpsURLConnection; import java.io.IOException; import java.net.URL; +import javax.net.ssl.HttpsURLConnection; + /** * Polls to load the web interface, until we receive http status 200. */ -public class PollWebGuiAvailableTask extends RestTask { +public class PollWebGuiAvailableTask extends RestTask { private static final String TAG = "PollWebGuiAvailableTask"; @@ -22,12 +23,12 @@ public class PollWebGuiAvailableTask extends RestTask { private static final long WEB_GUI_POLL_INTERVAL = 100; public PollWebGuiAvailableTask(URL url, String httpsCertPath, String apiKey, - OnSuccessListener listener) { + OnSuccessListener listener) { super(url, "", httpsCertPath, apiKey, listener); } @Override - protected Pair doInBackground(Void... aVoid) { + protected Pair doInBackground(Void... aVoid) { int status = 0; do { try { diff --git a/src/main/java/com/nutomic/syncthingandroid/http/PostTask.java b/src/main/java/com/nutomic/syncthingandroid/http/PostTask.java index f4c0ad44..ba338de5 100644 --- a/src/main/java/com/nutomic/syncthingandroid/http/PostTask.java +++ b/src/main/java/com/nutomic/syncthingandroid/http/PostTask.java @@ -3,17 +3,16 @@ package com.nutomic.syncthingandroid.http; import android.util.Log; import android.util.Pair; -import javax.net.ssl.HttpsURLConnection; -import java.io.BufferedReader; import java.io.IOException; -import java.io.InputStreamReader; import java.io.OutputStream; import java.net.URL; +import javax.net.ssl.HttpsURLConnection; + /** * Sends a POST request to the Syncthing API. */ -public class PostTask extends RestTask { +public class PostTask extends RestTask { private static final String TAG = "PostTask"; @@ -21,7 +20,7 @@ public class PostTask extends RestTask { public static final String URI_SCAN = "/rest/db/scan"; public PostTask(URL url, String path, String httpsCertPath, String apiKey, - OnSuccessListener listener) { + OnSuccessListener listener) { super(url, path, httpsCertPath, apiKey, listener); } @@ -31,7 +30,7 @@ public class PostTask extends RestTask { * For {@link #URI_SCAN}, params[0] must contain the folder, and params[1] the subfolder. */ @Override - protected Pair doInBackground(String... params) { + protected Pair doInBackground(String... params) { try { HttpsURLConnection connection = (mPath.equals(URI_SCAN)) ? openConnection("folder", params[0], "sub", params[1]) @@ -43,16 +42,7 @@ public class PostTask extends RestTask { OutputStream os = connection.getOutputStream(); os.write(params[0].getBytes("UTF-8")); } - connection.connect(); - BufferedReader br = new BufferedReader(new InputStreamReader(connection.getInputStream(), "UTF-8")); - String line; - String result = ""; - while ((line = br.readLine()) != null) { - result += line; - } - br.close(); - Log.v(TAG, "API call result: " + result); - return new Pair<>(true, true); + return connect(connection); } catch (IOException e) { Log.w(TAG, "Failed to call rest api", e); return new Pair<>(false, null); diff --git a/src/main/java/com/nutomic/syncthingandroid/http/RestTask.java b/src/main/java/com/nutomic/syncthingandroid/http/RestTask.java index de0161ad..c6e31015 100644 --- a/src/main/java/com/nutomic/syncthingandroid/http/RestTask.java +++ b/src/main/java/com/nutomic/syncthingandroid/http/RestTask.java @@ -7,36 +7,49 @@ import android.os.AsyncTask; import android.util.Log; import android.util.Pair; +import com.google.common.base.Charsets; +import com.google.common.io.ByteSource; import com.nutomic.syncthingandroid.syncthing.RestApi; -import javax.net.ssl.*; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; +import java.net.HttpURLConnection; import java.net.URL; -import java.security.*; +import java.security.InvalidKeyException; +import java.security.KeyManagementException; +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; +import java.security.SecureRandom; +import java.security.SignatureException; import java.security.cert.CertificateException; import java.security.cert.CertificateFactory; import java.security.cert.X509Certificate; -public abstract class RestTask extends - AsyncTask> { +import javax.net.ssl.HttpsURLConnection; +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLSocketFactory; +import javax.net.ssl.TrustManager; +import javax.net.ssl.X509TrustManager; + +public abstract class RestTask extends + AsyncTask> { private static final String TAG = "RestTask"; - public interface OnSuccessListener { - public void onSuccess(Result result); + public interface OnSuccessListener { + public void onSuccess(String result); } private final URL mUrl; protected final String mPath; private final String mHttpsCertPath; private final String mApiKey; - private final OnSuccessListener mListener; + private final OnSuccessListener mListener; public RestTask(URL url, String path, String httpsCertPath, String apiKey, - OnSuccessListener listener) { + OnSuccessListener listener) { mUrl = url; mPath = path; mHttpsCertPath = httpsCertPath; @@ -60,8 +73,34 @@ public abstract class RestTask extends return connection; } - protected void onPostExecute(Pair result) { - if (mListener == null) + /** + * Opens the connection, then returns success status and response string. + */ + protected Pair connect(HttpsURLConnection connection) throws IOException { + connection.connect(); + if (connection.getResponseCode() != HttpURLConnection.HTTP_OK) { + int responseCode = connection.getResponseCode(); + String responseMessage = connection.getResponseMessage(); + Log.i(TAG, "Request to " + connection.getURL() + " failed, code: " + responseCode + + ", message: " + responseMessage); + return new Pair<>(false, streamToString(connection.getErrorStream())); + } + return new Pair<>(true, streamToString(connection.getInputStream())); + } + + private String streamToString(InputStream is) throws IOException { + ByteSource byteSource = new ByteSource() { + @Override + public InputStream openStream() throws IOException { + return is; + } + }; + return byteSource.asCharSource(Charsets.UTF_8).read(); + } + + + protected void onPostExecute(Pair result) { + if (mListener == null || !result.first) return; mListener.onSuccess(result.second);