how to use HttpsUrlConnection instead of DefaultHttpClient
Asked Answered
G

4

6

DefaultHttpClient, ThreadSafeClientConnManager, HttpParams,HttpProtocolParams, SchemeRegistry, SSLSocketFactory, NameValuePair, HttpResponse are deprecated.

I tried to use HttpsUrlConnection but i confused about them.

protected Gson gson;
private ThreadSafeClientConnManager threadSafeClientConnManager;
private DefaultHttpClient client;

AbstractServiceApi() {

    // sets up parameters
    HttpParams params = new BasicHttpParams();
    HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
    HttpProtocolParams.setContentCharset(params, ENCODING);
    HttpConnectionParams.setConnectionTimeout(params, 95 * 1000);
    HttpConnectionParams.setSoTimeout(params, 95 * 1000);
    HttpConnectionParams.setStaleCheckingEnabled(params, false);
    params.setBooleanParameter("http.protocol.expect-continue", false);

    // registers schemes for both http and https
    SchemeRegistry registry = new SchemeRegistry();
    registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
    SSLSocketFactory sslSocketFactory = SSLSocketFactory.getSocketFactory();
    sslSocketFactory.setHostnameVerifier(SSLSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);
    registry.register(new Scheme("https", sslSocketFactory, 443));

    threadSafeClientConnManager = new ThreadSafeClientConnManager(params, registry);
    client = new DefaultHttpClient(threadSafeClientConnManager, params);
    gson = new Gson();
}

I don't have an keystore. https://developer.android.com/reference/javax/net/ssl/HttpsURLConnection.html

   KeyStore keyStore = ...;
   String algorithm = TrustManagerFactory.getDefaultAlgorithm();
   TrustManagerFactory tmf = TrustManagerFactory.getInstance(algorithm);
   tmf.init(keyStore);

   SSLContext context = SSLContext.getInstance("TLS");
   context.init(null, tmf.getTrustManagers(), null);

   URL url = new URL("https://www.example.com/");
   HttpsURLConnection urlConnection = (HttpsURLConnection) url.openConnection();
   urlConnection.setSSLSocketFactory(context.getSocketFactory());
   InputStream in = urlConnection.getInputStream();

could anyone help me?

Gilt answered 15/12, 2015 at 15:59 Comment(0)
G
9

This is my solution.

private HttpsURLConnection urlConnection;
private CookieManager cookieManager;

private HttpsURLConnection getConnection(String url) throws MalformedURLException {
    URL request_url = new URL(url);
    try {
        if (!isHttps()) {
            throw new ConnectException("you have to use SSL certifacated url!");
        }
        urlConnection = (HttpsURLConnection) request_url.openConnection();
        urlConnection.setRequestMethod("POST");
        urlConnection.setReadTimeout(95 * 1000);
        urlConnection.setConnectTimeout(95 * 1000);
        urlConnection.setDoInput(true);
        urlConnection.setRequestProperty("Accept", "application/json");
        urlConnection.setRequestProperty("X-Environment", "android");

        /** Cookie Sets... */
        String cookie = cookieManager.getCookie(urlConnection.getURL().toString());
        cookieManager = CookieManager.getInstance();
        if (cookie != null)
            urlConnection.setRequestProperty("Cookie", cookie);

        List<String> cookieList = urlConnection.getHeaderFields().get("Set-Cookie");
        if (cookieList != null) {
            for (String cookieTemp : cookieList) {
                cookieManager.setCookie(urlConnection.getURL().toString(), cookieTemp);
            }
        }
        /** Cookie Sets... */

        urlConnection.setHostnameVerifier(new HostnameVerifier() {
            @Override
            public boolean verify(String hostname, SSLSession session) {
                /** if it necessarry get url verfication */
                //return HttpsURLConnection.getDefaultHostnameVerifier().verify("your_domain.com", session);
                return true;
            }
        });
        urlConnection.setSSLSocketFactory((SSLSocketFactory) SSLSocketFactory.getDefault());


        urlConnection.connect();

    } catch (IOException e) {
        e.printStackTrace();
    }

    return urlConnection;
}
Gilt answered 17/12, 2015 at 7:58 Comment(2)
why only return true? Doesn't this mean you are not confirming that the domain was verified?Wizardly
It was just a sample. if you need use before line which was commented.Gilt
D
7

You could use https communication using HttpURLConnection (http://developer.android.com/reference/java/net/HttpURLConnection.html)

As I understand you communicate with web server with well-know certificate. In this case it'll look like:

    public static final int CONNECTON_TIMEOUT_MILLISECONDS = 60000;

public static String executeGetHttpRequest(final String path) throws ClientProtocolException, IOException {
    String result = null;
    HttpURLConnection urlConnection = null;
    try {
        URL url = new URL(path);
        urlConnection = (HttpURLConnection) url.openConnection();
        urlConnection.setConnectTimeout(CONNECTON_TIMEOUT_MILLISECONDS);
        urlConnection.setReadTimeout(CONNECTON_TIMEOUT_MILLISECONDS);
        result = readStream(urlConnection.getInputStream());
    } finally {
        if (urlConnection != null) {
            urlConnection.disconnect();
        }
    }
    return result;
}

private static String readStream(InputStream is) throws IOException {
    final BufferedReader reader = new BufferedReader(new InputStreamReader(is, Charset.forName("US-ASCII")));
    StringBuilder total = new StringBuilder();
    String line;
    while ((line = reader.readLine()) != null) {
        total.append(line);
    }
    if (reader != null) {
        reader.close();
    }
    return total.toString();
}

It's working sample. You could look at this good article where described different cases - http://developer.android.com/training/articles/security-ssl.html

Dandridge answered 15/12, 2015 at 16:40 Comment(0)
K
7

For HttpsUrlConnection, you can refer to my following sample code:

    private TrustManager[] getWrappedTrustManagers(TrustManager[] trustManagers) {
        final X509TrustManager originalTrustManager = (X509TrustManager) trustManagers[0];
        return new TrustManager[]{
                new X509TrustManager() {
                    public X509Certificate[] getAcceptedIssuers() {
                        return originalTrustManager.getAcceptedIssuers();
                    }

                    public void checkClientTrusted(X509Certificate[] certs, String authType) {
                        try {
                            originalTrustManager.checkClientTrusted(certs, authType);
                        } catch (CertificateException ignored) {
                        }
                    }

                    public void checkServerTrusted(X509Certificate[] certs, String authType) {
                        try {
                            originalTrustManager.checkServerTrusted(certs, authType);
                        } catch (CertificateException ignored) {
                        }
                    }
                }
        };
    }

    private SSLSocketFactory getSSLSocketFactory() {
        try {
            CertificateFactory cf = CertificateFactory.getInstance("X.509");
            InputStream caInput = getResources().openRawResource(R.raw.your_cert);
            Certificate ca = cf.generateCertificate(caInput);
            caInput.close();

            KeyStore keyStore = KeyStore.getInstance("BKS");
            keyStore.load(null, null);
            keyStore.setCertificateEntry("ca", ca);

            String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
            TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
            tmf.init(keyStore);

            SSLContext sslContext = SSLContext.getInstance("TLS");
            sslContext.init(null, getWrappedTrustManagers(tmf.getTrustManagers()), null);                

            return sslContext.getSocketFactory();
        } catch (Exception e) {
            return HttpsURLConnection.getDefaultSSLSocketFactory();
        }
    }

    private class GETRequest extends AsyncTask<Void, Void, String> {
        @Override
        protected String doInBackground(Void... params) {
            try {
                URL url = new URL("https://your_server_url");
                String token = "rbkY34HnL...";
                HttpsURLConnection urlConnection = (HttpsURLConnection) url.openConnection();
                urlConnection.setSSLSocketFactory(getSSLSocketFactory());
                urlConnection.setHostnameVerifier(new HostnameVerifier() {
                    @Override
                    public boolean verify(String hostname, SSLSession session) {
//                        return true;
                        HostnameVerifier hv = HttpsURLConnection.getDefaultHostnameVerifier();
                        return hv.verify("your_domain.com", session);
                    }
                });    
                urlConnection.setRequestProperty("Authorization", "Bearer " + token);
                urlConnection.connect();
                InputStream inputStream;
                if (urlConnection.getResponseCode() != HttpURLConnection.HTTP_OK) {
                    inputStream = urlConnection.getErrorStream();
                } else {
                    inputStream = urlConnection.getInputStream();
                }
                return String.valueOf(urlConnection.getResponseCode()) + " " + urlConnection.getResponseMessage() + "\r\n" + parseStream(inputStream);
            } catch (Exception e) {
                return e.toString();
            }
        }

        @Override
        protected void onPostExecute(String response) {
            super.onPostExecute(response);
            // do something...
        }
    }

Hope it helps!

Knock answered 17/12, 2015 at 2:7 Comment(1)
If you want to ignore SSL for development, you can also read my answer at #32051982Knock
H
0

You can use HttpURLConnection by this way

URL url = new URL(urlString);

    HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
    urlConnection.setRequestMethod("GET");
    urlConnection.connect();

    // Read the input stream into a String
    InputStream inputStream = urlConnection.getInputStream();
    StringBuffer buffer = new StringBuffer();
    if (inputStream == null) {
        // Nothing to do.
        return null;
    }

    BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
    String line;
    while ((line = reader.readLine()) != null) {
        buffer.append(line + "\n");
    }

    if (buffer.length() == 0) {
        return null;
    }

    String stringResult = buffer.toString();
Horsepowerhour answered 15/12, 2015 at 16:18 Comment(2)
I need Https protocol. HttpUrlConnection is ok.Gilt
The question was about https connections.Marketable

© 2022 - 2024 — McMap. All rights reserved.