androidsocketssslksoap23g

Android application working on WIFI and 3G(Without proxy), but not working on 3G(If proxy and port are assigned)


I am facing some weird problem, Only my application is not working when I switch to 3G service(With proxy) but it is working great in WIFI and 3G(without proxy).

Default proxy and port given by my Starhub (network provider):

Proxy: 10.12.1.2
Port: 80

For data, I am sending soap request to my webserver.

Here is my code:

public class SearchThread extends Thread {
private String mUrl;
private SoapSerializationEnvelope mEnvelop;
private Handler mHandler;
private String mSoapAction;
private KeepAliveHttpsTransportSE mTransport;

public SearchThread(String url) {
    this.mUrl = url;
}

@Override
public void run() {
    mEnvelop = new SoapSerializationEnvelope(SoapSerializationEnvelope.VER11);
    mEnvelop.setOutputSoapObject(interfaceListener.getSoapObject(element));
    mSoapAction = interfaceListener.getSoapAction(element);
    try {
        TrustManagerManipulator.allowAllSSL();
        mTransport = new KeepAliveHttpsTransportSE(URLS.URL_MAIN, 443, mUrl, 60000);
        mTransport.call(mSoapAction, mEnvelop);
        if (this.isInterrupted()) {
            Log.v(TAG,"Interrupted");
            return;
        }
        recevedSoapResponse(mEnvelop.getResponse());
    } catch (SocketException ex) {
        Log.e("Error : ", "Error on soapPrimitiveData() " + ex.getMessage());
        ex.printStackTrace();
    } catch (IOException e) {
        interfaceListener.recievedParsingResults(
                PARSER.RESULT.CONNECTION_FAILED, element, mHandler, mView);
        e.printStackTrace();
    } catch (XmlPullParserException e) {
        e.printStackTrace();
        interfaceListener.recievedParsingResults(
                PARSER.RESULT.INTERNAL_ERROR, element, mHandler, mView);
    }
}
private void recevedSoapResponse(Object response) {
   //Parsing XML here.
}
public class KeepAliveHttpsTransportSE extends HttpsTransportSE
{
    private final String host;
    private final int port;
    private final String file;
    private final int timeout;
    private ServiceConnection serviceConnection;

    public KeepAliveHttpsTransportSE (String host, int port, String file, int timeout) {
        super(host, port, file, timeout);
        this.host = host;
        this.port = port;
        this.file = file;
        this.timeout = timeout;
    }
 //@Override
    public ServiceConnection getServiceConnection() throws IOException
    {
        if (serviceConnection == null) {
            serviceConnection = new HttpsServiceConnectionSE(host, port, file, timeout);
            serviceConnection.setRequestProperty("Connection", "keep-alive");
        }
        return serviceConnection;
    }
}

}

And here is my SSL code:

public class TrustManagerManipulator implements X509TrustManager {
    private static TrustManager[] trustManagers;
    private static final X509Certificate[] acceptedIssuers = new X509Certificate[] {};

public boolean isClientTrusted(X509Certificate[] chain) {
    return true;
}

public boolean isServerTrusted(X509Certificate[] chain) {
    return true;
}

public static void allowAllSSL() {
    HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() {
        public boolean verify(String hostname, SSLSession session) {
            return true;
        }
    });
    SSLContext context = null;
    if (trustManagers == null) {
        trustManagers = new TrustManager[] { new TrustManagerManipulator() };
    }
    try {
        context = SSLContext.getInstance("TLS");
        context.init(null, trustManagers, new SecureRandom());
    } catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
    } catch (KeyManagementException e) {
        e.printStackTrace();
    }
    HttpsURLConnection.setDefaultSSLSocketFactory(context
            .getSocketFactory());
}

public void checkClientTrusted(X509Certificate[] chain, String authType)
        throws CertificateException {
}

public void checkServerTrusted(X509Certificate[] chain, String authType)
        throws CertificateException {
}

public X509Certificate[] getAcceptedIssuers() {
    return acceptedIssuers;
}
}

Exception:

09-27 12:21:03.295: W/System.err(8924): java.net.SocketException: Socket is closed
09-27 12:21:03.295: W/System.err(8924):     at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.checkOpen(OpenSSLSocketImpl.java:262)
09-27 12:21:03.295: W/System.err(8924):     at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:273)
09-27 12:21:03.295: W/System.err(8924):     at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:257)
09-27 12:21:03.295: W/System.err(8924):     at libcore.net.http.HttpConnection.setupSecureSocket(HttpConnection.java:210)
09-27 12:21:03.295: W/System.err(8924):     at libcore.net.http.HttpsURLConnectionImpl$HttpsEngine.makeSslConnection(HttpsURLConnectionImpl.java:477)
09-27 12:21:03.295: W/System.err(8924):     at libcore.net.http.HttpsURLConnectionImpl$HttpsEngine.connect(HttpsURLConnectionImpl.java:441)
09-27 12:21:03.295: W/System.err(8924):     at libcore.net.http.HttpEngine.sendSocketRequest(HttpEngine.java:282)
09-27 12:21:03.295: W/System.err(8924):     at libcore.net.http.HttpEngine.sendRequest(HttpEngine.java:232)
09-27 12:21:03.295: W/System.err(8924):     at libcore.net.http.HttpURLConnectionImpl.connect(HttpURLConnectionImpl.java:80)
09-27 12:21:03.300: W/System.err(8924):     at libcore.net.http.HttpURLConnectionImpl.getOutputStream(HttpURLConnectionImpl.java:188)
09-27 12:21:03.300: W/System.err(8924):     at libcore.net.http.HttpsURLConnectionImpl.getOutputStream(HttpsURLConnectionImpl.java:280)
09-27 12:21:03.300: W/System.err(8924):     at org.ksoap2.transport.HttpsServiceConnectionSE.openOutputStream(HttpsServiceConnectionSE.java:98)
09-27 12:21:03.300: W/System.err(8924):     at org.ksoap2.transport.HttpTransportSE.call(HttpTransportSE.java:157)
09-27 12:21:03.300: W/System.err(8924):     at org.ksoap2.transport.HttpTransportSE.call(HttpTransportSE.java:96)
09-27 12:21:03.300: W/System.err(8924):     at com.mobile.utils.parser.SearchThread.run(SearchThread.java:25)

Additional Info: All other applications are running on 3G network(with/without proxy settings) and In my application only SOAP request is not working.

I have tried all the possible cases, but no luck. Please provide me some inputs.

Thanks in advance.


Solution

  • Maybe too late four you, but I hope this would help to future people reaching here like me, getting crazy with the same problem.

    It's an Android bug. Everything works right with WiFi, but it crashes on 3G. It happened to me on 4.1, but no problem on 4.2.2.

    To solve it, you have to modify the file org.ksoap2.transport.HttpTransportSE (I've extended a new one and called it MyHttpTransportSE because I'm using ksoap2 assembly jar). Just override method public void call(String soapAction, SoapEnvelope envelope) commenting out the line

        //connection.setRequestProperty("Connection", "close"); 
    

    Of course, if you're working with SSL, you'll need to extend your own HttpsTransportSE from your new MyHttpTransportSE.

    HttpTransportSE source code: https://github.com/karlmdavis/ksoap2-android/blob/master/ksoap2-j2se/src/main/java/org/ksoap2/transport/HttpTransportSE.java?source=c

    HttpsTransportSE source code: https://github.com/mosabua/ksoap2-android/blob/master/ksoap2-j2se/src/main/java/org/ksoap2/transport/HttpsTransportSE.java

    More details here: https://groups.google.com/forum/#!searchin/ksoap2-android/closed/ksoap2-