Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

HttpGet/Client and HTTPS

Previously, I used custom TrustManager talked about here to do this

SAXParserFactory spf = SAXParserFactory.newInstance();
SAXParser sp = spf.newSAXParser();

XMLReader xr = sp.getXMLReader();
MyXMLHandler mHandler = new MyXMLHandler();
xr.setContentHandler(mHandler);

xr.parse(new InputSource(buildUrlString()));

(where buildUrlString() returns a string containing the https:// url to call) which works fine. However, I want to now be able to send the same url an Accept-Encoding header for gzip compression. I can do that like this

HttpUriRequest request = new HttpGet(buildUrlString());
request.addHeader("Accept-Encoding", "gzip");
HttpClient httpClient = new DefaultHttpClient();
HttpResponse response = httpClient.execute(request);

InputStream instream = response.getEntity().getContent();
Header contentEncoding = response.getFirstHeader("Content-Encoding");
if ((contentEncoding != null)
    && contentEncoding.getValue().equalsIgnoreCase("gzip")) 
{ 
  instream = new GZIPInputStream(instream);
} 
xr.parse(new InputSource(instream));

but that brings back the "Not trusted server certificate" error that I want to ignore. How do I make it do HTTPS? Alternatively, is there a better way to do this? (And is there something I need to check first to make sure the phone really can accept the gzipped webpages that I'm saying it can?)

like image 272
Ben Williams Avatar asked Mar 10 '26 13:03

Ben Williams


2 Answers

If you want to use Apache HTTP client API you can keep using your custom TrustManager by extending the DefaultHttpClient

import org.apache.http.conn.ssl.SSLSocketFactory;

public class MyHttpClient extends DefaultHttpClient {
  final Context context;

  public MyHttpClient(Context context) {
    this.context = context;
  }

  @Override 
  protected ClientConnectionManager createClientConnectionManager() {
    SchemeRegistry registry = new SchemeRegistry();
    registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
    registry.register(new Scheme("https", newSslSocketFactory(), 443));
    return new SingleClientConnManager(getParams(), registry);
  }

  private SSLSocketFactory newSslSocketFactory() {
    try {
      TrustManager tm = new MyCustomTrustManager();
      SSLContext ctx = SSLContext.getInstance("TLS");
      ctx.init(null, new TrustManager[] {tm}, null);
      SSLSocketFactory sf = new SSLSocketFactory(ctx);
      return new SSLSocketFactory(ctx);
    } catch (Exception e) {
      throw new Error(e);
    }
  }
}
like image 183
Jcs Avatar answered Mar 13 '26 02:03

Jcs


Actually this works:

URL url = new URL(buildUrlString());
HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
conn.setRequestProperty("Accept-Encoding","gzip"); 

InputStream instream = conn.getInputStream();
String response = conn.getContentEncoding();
if ((response != null)
    && response.equalsIgnoreCase("gzip")) 
{ 
  instream = new GZIPInputStream(instream);
} 
xr.parse(new InputSource(instream));

I'm still not sure this is the best solution, though, so I'll leave the question up for a bit in case anyone has better ideas. :)

like image 39
Ben Williams Avatar answered Mar 13 '26 03:03

Ben Williams