]> iEval git - fonbot.git/blobdiff - src/ro/ieval/fonbot/HttpCallExecutableRunnable.java
Make FonBot usable
[fonbot.git] / src / ro / ieval / fonbot / HttpCallExecutableRunnable.java
index e95dba73ab478c02d5f94fa77e18ee996f4c918e..12b1014c672cf4f6e1b3a760e89227471313a58b 100644 (file)
@@ -6,15 +6,9 @@ import static ro.ieval.fonbot.Utils.toNonNull;
 import java.io.InputStream;
 import java.io.OutputStream;
 import java.net.URL;
-import java.security.cert.CertificateException;
-import java.security.cert.X509Certificate;
 import java.util.Collection;
 
-import javax.net.ssl.HttpsURLConnection;
-import javax.net.ssl.SSLContext;
-import javax.net.ssl.SSLSocketFactory;
-import javax.net.ssl.X509TrustManager;
-
+import java.net.HttpURLConnection;
 import org.eclipse.jdt.annotation.Nullable;
 
 import android.content.Context;
@@ -22,8 +16,6 @@ import android.preference.PreferenceManager;
 import android.util.Base64;
 import android.util.Log;
 
-import com.google.android.gcm.GCMRegistrar;
-
 /*
  * Copyright © 2013 Marius Gavrilescu
  * 
@@ -44,41 +36,18 @@ import com.google.android.gcm.GCMRegistrar;
  */
 
 /**
- * ExecutableRunnable that makes a HTTPS call to the server and hands the response to a callback
+ * ExecutableRunnable that makes a HTTP(S) call to the server and hands the response to a callback
  *
  * @author Marius Gavrilescu <marius@ieval.ro>
  */
 public final class HttpCallExecutableRunnable extends ExecutableRunnable{
-       /**
-        * X509TrustManager that trusts any certificate
-        *
-        * @author Marius Gavrilescu
-        */
-       private static final class TotallyInsecureTrustManager implements X509TrustManager {
-               @Override
-               public @Nullable X509Certificate[] getAcceptedIssuers() {
-                       return new X509Certificate[0];
-               }
-
-               @Override
-               public void checkServerTrusted(final @Nullable X509Certificate[] chain, final @Nullable String authType)
-                               throws CertificateException {
-                       //do nothing
-               }
-
-               @Override
-               public void checkClientTrusted(final @Nullable X509Certificate[] chain, final @Nullable String authType)
-                               throws CertificateException {
-                       //do nothing
-               }
-       }
 
        /**
         * Callback which is run after a HTTP call.
         *
         * @author Marius Gavrilescu
         */
-       public static interface ResultCallback{
+       public interface ResultCallback{
                /**
                 * Callback invoked if the HTTP call is successful.
                 *
@@ -86,26 +55,13 @@ public final class HttpCallExecutableRunnable extends ExecutableRunnable{
                 * @param responseMessage HTTP response message
                 * @param inputStream HTTP content InputStream
                 */
-               public void onResult(final int responseCode, final String responseMessage, final InputStream inputStream);
+               void onResult(final int responseCode, final String responseMessage, final InputStream inputStream);
                /**
                 * Callback invoked if the HTTP call is unsuccessful.
                 *
                 * @param error localized error message
                 */
-               public void onError(final String error);
-       }
-
-       /** SSLSocketFactory that uses {@link TotallyInsecureTrustManager} */
-       private static final SSLSocketFactory DEFAULT_SOCKET_FACTORY;
-       static{
-               try{
-                       final SSLContext sslcontext=SSLContext.getInstance("TLS");
-                       sslcontext.init(null, new X509TrustManager[]{new TotallyInsecureTrustManager()}, null);
-                       DEFAULT_SOCKET_FACTORY=sslcontext.getSocketFactory();
-               } catch(final Exception e){
-                       Log.wtf("HttpCallExecutableRunnable", "Cannot create SSLSocketFactory", e);
-                       throw new AssertionError("Log.wtf did not terminate the process");
-               }
+               void onError(final String error);
        }
 
        /**
@@ -128,6 +84,8 @@ public final class HttpCallExecutableRunnable extends ExecutableRunnable{
         * Callback to run after the request returns
         */
        private final ResultCallback callback;
+       /** If true, the task should be retried if it fails */
+       private final boolean mustRetryTask;
 
        /**
         * Constructs a SendHttpMessageAsyncTask which sends a binary message.
@@ -136,13 +94,15 @@ public final class HttpCallExecutableRunnable extends ExecutableRunnable{
         * @param headers the extra headers
         * @param context the context instance
         * @param resultCallback {@link ResultCallback} instance
+        * @param mustRetryTask true if this task should be retried if it fails
         * @param data the message to send
         */
-       public HttpCallExecutableRunnable(final String path, final @Nullable Collection<Header> headers, final Context context, final @Nullable ResultCallback resultCallback, final byte[] data){//NOPMD array is supposed to be immutable.
+       public HttpCallExecutableRunnable(final String path, final @Nullable Collection<Header> headers, final Context context, final @Nullable ResultCallback resultCallback, final boolean mustRetryTask, final byte[] data){//NOPMD array is supposed to be immutable.
                this.path=path;
                this.headers=headers;
                this.context=context;
                this.callback=resultCallback;
+               this.mustRetryTask=mustRetryTask;
                this.data=data;
        }
 
@@ -153,13 +113,15 @@ public final class HttpCallExecutableRunnable extends ExecutableRunnable{
         * @param headers the extra headers
         * @param context the context instance
         * @param resultCallback {@link ResultCallback} instance
+        * @param mustRetryTask true if this task should be retried if it fails
         * @param message message to send
         */
-       public HttpCallExecutableRunnable(final String path, final @Nullable Collection<Header> headers, final Context context, final @Nullable ResultCallback resultCallback, final String... message){
+       public HttpCallExecutableRunnable(final String path, final @Nullable Collection<Header> headers, final Context context, final @Nullable ResultCallback resultCallback, final boolean mustRetryTask, final String... message){
                this.path=path;
                this.headers=headers;
                this.context=context;
                this.callback=resultCallback;
+               this.mustRetryTask=mustRetryTask;
                if(message.length == 0)
                        this.data=null;//NOPMD final field
                else
@@ -167,47 +129,55 @@ public final class HttpCallExecutableRunnable extends ExecutableRunnable{
        }
 
        @Override
-       public void run() {
+       public void run(){
                try {
-                       final URL url=Utils.getServerURL(toNonNull(context),toNonNull(path));
-                       final HttpsURLConnection conn=(HttpsURLConnection) url.openConnection();
-                       conn.setSSLSocketFactory(DEFAULT_SOCKET_FACTORY);
-                       if(data!=null){
-                               conn.setDoOutput(true);
-                               conn.setFixedLengthStreamingMode(data.length);
-                       }
-                       conn.setRequestProperty("X-ID", GCMRegistrar.getRegistrationId(context));
-                       final String user=PreferenceManager.getDefaultSharedPreferences(context).getString("username", null);
-                       final String password=PreferenceManager.getDefaultSharedPreferences(context).getString("password", null);
-                       if(user == null || password == null){
-                               if(callback!=null)
-                                       callback.onError(toNonNull(context.getString(user_or_password_not_set)));
-                               return;
-                       }
-
-                       conn.setRequestProperty("Authorization", "Basic "+Base64.encodeToString(
-                                       (user+':'+password).getBytes(), Base64.NO_WRAP));
-                       if(headers != null)
-                               for (final Header header : headers)
-                                       conn.setRequestProperty(header.name, header.value);
-                       conn.connect();
-                       if(data!=null){
-                               final OutputStream stream=conn.getOutputStream();
-                               stream.write(data);
-                               stream.close();
-                       }
-                       Log.d(getClass().getName(),"HTTP Response: "+conn.getResponseCode()+" "+conn.getResponseMessage());
-                       final String message=conn.getResponseMessage();
-                       if(message==null && callback != null)
-                               callback.onError(toNonNull(context.getString(no_response_returned_from_server)));
-                       else if(message != null && callback != null)
-                               callback.onResult(conn.getResponseCode(), message,
-                                               toNonNull(conn.getInputStream()));
-                       conn.disconnect();
+                       doRun();
                } catch (Exception e) {
                        e.printStackTrace();
                        if(callback != null)
                                callback.onError(toNonNull(context.getString(connection_error)));
+                       if(mustRetryTask)
+                               retry();
+               }
+       }
+
+       public void doRun() throws Exception{
+               final URL url=Utils.getServerURL(toNonNull(context),toNonNull(path));
+               final HttpURLConnection conn=(HttpURLConnection) url.openConnection();
+               conn.setReadTimeout(24*60*1000);//24 minutes
+               if(data!=null){
+                       conn.setDoOutput(true);
+                       conn.setFixedLengthStreamingMode(data.length);
+               }
+               final String user=PreferenceManager.getDefaultSharedPreferences(context).getString("username", null);
+               final String password=PreferenceManager.getDefaultSharedPreferences(context).getString("password", null);
+               if(user == null || password == null || user.length() == 0 || password.length() == 0){
+                       if(callback!=null)
+                               callback.onError(toNonNull(context.getString(user_or_password_not_set)));
+                       return;
+               }
+
+               conn.setRequestProperty("Authorization", "Basic "+Base64.encodeToString((user+':'+password).getBytes(), Base64.NO_WRAP));
+               if(headers != null)
+                       for (final Header header : headers)
+                               conn.setRequestProperty(header.name, header.value);
+               conn.connect();
+               if(data!=null){
+                       final OutputStream stream=conn.getOutputStream();
+                       stream.write(data);
+                       stream.close();
+               }
+               Log.d(getClass().getName(),"HTTP Response: "+conn.getResponseCode()+" "+conn.getResponseMessage());
+               String message=conn.getResponseMessage();
+               if(message==null && callback != null)
+                       callback.onError(toNonNull(context.getString(no_response_returned_from_server)));
+               else if(message != null && callback != null){
+                       if(message.charAt(message.length()-1) == ')')//message is (something)
+                               message=message.substring(1, message.length()-1);
+                       else if(message.charAt(0) == '(')//message is (something) something else
+                               message=message.substring(message.indexOf(')')+2);
+                       callback.onResult(conn.getResponseCode(), message, conn.getResponseCode() == 200 ? conn.getInputStream() : null);
                }
+               conn.disconnect();
        }
 }
This page took 0.028131 seconds and 4 git commands to generate.