Porting Desktop's HttpClient code to Android's HttpURLConnection
<p>Currently, I try to port a desktop application. The application is using HttpClient previously. Due to the advice from <a href="http://android-developers.blogspot.com/2011/09/androids-http-clients.html" rel="nofollow">Android’s HTTP Clients</a>, I guess I better make use of <code>HttpURLConnection</code> instead of <code>DefaultHttpClient</code> (or <code>AndroidHttpClient</code>)</p>

<p>However, in my previous Desktop networking code, I did quite a number of number of special handling for the following situations. They work quite well for several years.</p>

<ul>
<li>Set correct HTTP proxy and HTTP proxy port, depending on current OS network settings.</li>
<li>NTLM authentication, which the credential information will be provided by user.</li>
<li>HTTP redirection.</li>
</ul>

<p>By following the article advice, most probably I will be using <code>HttpURLConnection</code>. I was wondering :</p>

<ul>
<li>Do I need to handle HTTP proxy and HTTP proxy port configuration in Android device?</li>
<li>Do I need to handle NTLM authentication in Android device?</li>
<li>Do I need to handle HTTP redirection?</li>
</ul>

<p>I post my previous desktop's network code for reference purpose. Sorry, is quite a lengthy code.</p>

<p><strong>Honestly, I am getting a little confused. As in desktop environement development, we are encouraged to use <code>HttpClient</code> over <code>HttpURLConnection</code> most of the time : <a href="http://stackoverflow.com/questions/643730/httpclient-vs-httpurlconnection?rq=1">httpclient vs httpurlconnection</a></strong></p>

<hr>

<pre><code>/**
  * Initialize HttpClient with information from system properties.
  *
  * @param httpClient HttpClient to be initialized
  */
public static void setHttpClientProxyFromSystemProperties(HttpClient httpClient) {
    final String httpproxyHost = System.getProperties().getProperty("http.proxyHost");
    final String httpproxyPort = System.getProperties().getProperty("http.proxyPort");

    if (null == httpproxyHost || null == httpproxyPort) {
        HostConfiguration hostConfiguration = httpClient.getHostConfiguration();
        hostConfiguration.setProxyHost(null);
    }
    else {
        int port = -1;
        try {
            port = Integer.parseInt(httpproxyPort);
        }
        catch (NumberFormatException exp) {
        }     

        if (isValidPortNumber(port)) {
            HostConfiguration hostConfiguration = httpClient.getHostConfiguration();
            hostConfiguration.setProxy(httpproxyHost, port);                
        }
        else {
            HostConfiguration hostConfiguration = httpClient.getHostConfiguration();
            hostConfiguration.setProxyHost(null);
        }
    }
}

// We prefer to have this method in gui package instead of engine. This is because it requires
// access to JStockOptions.
private static void setHttpClientProxyCredentialsFromJStockOptions(HttpClient httpClient) {
    final JStockOptions jStockOptions = MainFrame.getInstance().getJStockOptions();
    if (jStockOptions.isProxyAuthEnabled() == false) {
        httpClient.getState().clearCredentials();
    }
    else {
        httpClient.getState().setProxyCredentials(AuthScope.ANY, jStockOptions.getCredentials());
    }
}

private static String _getResponseBodyAsStringBasedOnProxyAuthOption(HttpClient client, String request) {
    org.yccheok.jstock.engine.Utils.setHttpClientProxyFromSystemProperties(client);
    org.yccheok.jstock.gui.Utils.setHttpClientProxyCredentialsFromJStockOptions(client);

    final HttpMethod method = new GetMethod(request);
    final JStockOptions jStockOptions = MainFrame.getInstance().getJStockOptions();
    String respond = null;
    try {
        if (jStockOptions.isProxyAuthEnabled()) {
            method.setFollowRedirects(false);
            client.executeMethod(method);

            int statuscode = method.getStatusCode();
            if ((statuscode == HttpStatus.SC_MOVED_TEMPORARILY) ||
                (statuscode == HttpStatus.SC_MOVED_PERMANENTLY) ||
                (statuscode == HttpStatus.SC_SEE_OTHER) ||
                (statuscode == HttpStatus.SC_TEMPORARY_REDIRECT)) {
                //Make new Request with new URL
                Header header = method.getResponseHeader("location");
                HttpMethod RedirectMethod = new GetMethod(header.getValue());
                // I assume it is OK to release method for twice. (The second
                // release will happen in finally block). We shouldn't have an
                // unreleased method, before executing another new method.
                method.releaseConnection();
                // Do RedirectMethod within try-catch-finally, so that we can have a
                // exception free way to release RedirectMethod connection.
                // #2836422
                try {
                    client.executeMethod(RedirectMethod);
                    respond = RedirectMethod.getResponseBodyAsString();
                }
                catch (HttpException exp) {
                    log.error(null, exp);
                    return null;
                }
                catch (IOException exp) {
                    log.error(null, exp);
                    return null;
                }
                finally {
                    RedirectMethod.releaseConnection();
                }
            }
            else {
                respond = method.getResponseBodyAsString();
            } // if statuscode = Redirect
        }
        else {
            client.executeMethod(method);
            respond = method.getResponseBodyAsString();
        } //  if jStockOptions.isProxyAuthEnabled()
    }
    catch (HttpException exp) {
        log.error(null, exp);
        return null;
    }
    catch (IOException exp) {
        log.error(null, exp);
        return null;
    }
    finally {
        method.releaseConnection();
    }
    return respond;
}
</code></pre>
