tags:

views:

1575

answers:

7

For my app, Transdroid, I am connecting to remote servers via HTTP and optionally securely via HTTPS. For these HTTPS connections with the HttpClient I am using a custom SSL socket factory implementation to make sure self-signed certificates are working. Basically, I accept everything and ignore every checking of any certificate.

This has been working fine for some time now, but it no longer work for Android 2.2 FroYo. When trying to connect, it will return an exception:

java.io.IOException: SSL handshake failure: I/O error during system call, Broken pipe

Here is how I initialize the HttpClient:

    SchemeRegistry registry = new SchemeRegistry();
    registry.register(new Scheme("http", new PlainSocketFactory(), 80));
    registry.register(new Scheme("https", (trustAll ? new FakeSocketFactory() : SSLSocketFactory.getSocketFactory()), 443));
    client = new DefaultHttpClient(new ThreadSafeClientConnManager(httpParams, registry), httpParams);

I make use of a FakeSocketFactory and FakeTrustManager, of which the source can be found here: http://code.google.com/p/transdroid/source/browse/#svn/trunk/src/org/transdroid/util

Again, I don't understand why it suddenly stopped work, or even what the error 'Broken pipe' means. I have seen messages on Twitter that Seesmic and Twidroid fail with SSL enabled on FroYo as well, but am unsure if it's related.

Thanks for any directions/help!

A: 

My users just started getting the same broken pipe error on FroYo. I use a similar custom socket factory, which has worked great up until now.

I was unsuccessful in getting it to work, so I ended up replacing HttpClient with pure java.net code for that specific instance where I need to bypass certificate validation.

If you find a solution using HttpClient, please update this thread, I'll do the same. Good luck.

kria
Wow that was simple enough :)Thank you very much for the fix Eric! You saved my day.
kria
+8  A: 

Here is the answer, with many, many thanks to a helpful Seesmic developer willing to share the fix:

In the custom socket factory, the socket creation (with createSocket) has apparently been changed specifically for the SSLSocketFactory implementation. So the old:

    @Override
    public Socket createSocket(Socket socket, String host, int port, boolean autoClose)
                    throws IOException, UnknownHostException {
            return getSSLContext().getSocketFactory().createSocket();
    }

Needs to be changed to:

    @Override
    public Socket createSocket(Socket socket, String host, int port, boolean autoClose)
                    throws IOException, UnknownHostException {
            return getSSLContext().getSocketFactory().createSocket(socket, host, port, autoClose);
    }

And then it worked again for me! A diff is available here (but the fix is so simple I assume this is not really needed).

Eric
I was having the same problem. Thank you very much for this quick and easy solution.
Ulrich Scheller
A: 

I was looking for a way of doing what you did in the first place: allowing you to do SSL using the DefaultHttpClient. Your original code helped me do that. So thanks for the sample code.

Jbruntt
A: 

what's the underline changes that cause this to break?

Howard
A: 

Eric, great solution! Thx!!!

vladyud
A: 

More Info on this problem http://code.google.com/p/android/issues/detail?id=10472 This fixed the SSL issue we had for HTC Desire when we updated to Android 2.2

Jinu
A: 

Thanks dude.... May God bless you....

vinay