views:

793

answers:

3

All I need to do is download some basic text-based and image files from a web server that has a self-signed SSL certificate.

I have been trying to figure out how to use HttpClient to do this, but getting the SSL to work is a nightmare that seems to be way too much trouble for such a simple task.

Is there a better way to perform these file downloads? Perhaps through a WebView or Browser feature? Reinventing the wheel of making a simple HTTPS GET request is a major pain, and is significantly holding up my development schedule.

A: 

I think you could do it with the HttpsURLConnection. Try this out:

URL url = new URL("https://yourhttpsurl.com");
URLConnection conn = url.openConnection(); // should return a HttpsURLConnection

BufferedReader in = new BufferedReader(
        new InputStreamReader(conn.getInputStream()));
String str;
while ((str = in.readLine()) != null) {
    // Process str
}

in.close();

I just did the very same task, but I needed handling of cookies as well (and I was lazy) so I actually used HttpClient in the Android app. I know it's a huge overkill but I believe that most of the HttpClient code was unused (that is, unreferenced and thus not compiled) in my small app, because the resulting .apk was just a few kb large.

Edit: It just struck me I've only tested the first approach with properly signed centificates.

aioobe
Yeah, this doesn't work with self-signed certificates.
stormin986
+3  A: 

I would recommend getting a non-self-signed cert for the server.

That being said, here is an example of creating an SSLSocketFactory that supports self-signed certs, and here is an example of using an SSLSocketFactory with HttpClient.

CommonsWare
When I try to combine these two, I get the following problem. The first example you give related to self-signed certificates is using the `javax.net.ssl.SSLContext.getSocketFactory()`, but in the second example on how to integrate it, a `new Scheme()` requires a socket factory of the type org.apache.http.conn.scheme.SocketFactory. Is there a need to transform one to the other or are they identical/fully compatible? I currently am just casting the result of my `javax.*.SSLSocketFactory getSocketFactory()` function to an `org.apache.*.SocketFactory` and the compiler isn't complaining...
stormin986
Yeah doing that is giving me a ClassCastException at runtime. Is there any way to make these two things compatible?
stormin986
Urk. I hate it when these guys name stuff the same. Nope, I have no clue. HttpClient is "opinionated software", and they don't like self-signed certs, so hence we're kinda on our own. Sorry.
CommonsWare
Found one! http://stackoverflow.com/questions/995514/https-connection-android uses HttpsURLConnection and shows how to bypass the certificate check.
stormin986
And here's another good one for DefaultHttpClient: http://stackoverflow.com/questions/1217141/self-signed-ssl-acceptance-android
stormin986
A: 

I found two great examples of how to accept self-signed SSL certificates, one each for HttpsURLConnection and HttpClient.

HttpsURLConnection solution: http://stackoverflow.com/questions/995514/https-connection-android

HttpClient solution: http://stackoverflow.com/questions/1217141/self-signed-ssl-acceptance-android

stormin986