What does a TCP dump for the JRE vs Apache Client through the SOCKS proxy look like?
You can also up the log level of the client to debug... Bill- On Dec 12, 2011 1:25 AM, "VJ" <[email protected]> wrote: > Hello All, > I am facing a strange problem with HTTPClient and SOCKS proxy. > I have a test setup with HTTPClient (4.1.2) running behind a SOCKS Proxy. > It fails resolve the host name of a server. I, also, have an HTTP proxy > server in the same setup. When used with HTTP proxy, the HTTPClient > resolves the host name. In addition, if I use the HttpsUrlConnection (JRE), > the host name resolves fine with HTTP Proxy as well as SOCKS Proxy. > > Environment Details: All machines on RHEL 5.4, JRE 1.6, HTTP Client 4.1.2, > HTTP Core 4.1.2, SOCKS Proxy SS5 > > Code: > > ******************************************************************************* > package net.vj.proxy; > > public interface Constant { > String HTTP_PROXY_TYPE = "HTTP"; > String SOCKS_PROXY_TYPE = "SOCKS"; > String SOCKS_PROXY_HOST = "192.168.123.7"; > int SOCKS_PROXY_PORT = 1080; > String HTTP_PROXY_HOST = "192.168.123.2"; > int HTTP_PROXY_PORT = 8000; > String SERVER_URL ="https://somesharepoint.mydomain.com"; > } > > package net.vj.proxy; > > import static net.vj.proxy.Constant.*; > > import java.security.KeyStore; > import java.security.SecureRandom; > > import javax.net.ssl.SSLContext; > import javax.net.ssl.TrustManager; > import javax.net.ssl.X509TrustManager; > > import org.apache.http.HttpHost; > import org.apache.http.client.HttpClient; > import org.apache.http.conn.params.ConnRoutePNames; > import org.apache.http.conn.scheme.Scheme; > import org.apache.http.conn.ssl.AllowAllHostnameVerifier; > import org.apache.http.conn.ssl.SSLSocketFactory; > import org.apache.http.impl.client.DefaultHttpClient; > import org.apache.log4j.Logger; > > import net.myutil.SecurityUtil; > > public class HttpClientFactory { > private static final Logger log = > Logger.getLogger(HttpClientFactory.class); > public static final String SYS_PROP_SOCKS_PROXY_HOST = "socksProxyHost"; > public static final String SYS_PROP_SOCKS_PROXY_PORT = "socksProxyPort"; > > /** > * Private default constructor for Utility class. > */ > private HttpClientFactory(){ > //EMPTY Constructor > } > > public static HttpClient getHttpClient(String proxyType) throws > Exception{ > //Get the truststore which trust your server > KeyStore truststore = SecurityUtil.getTrustStore(); > > SSLSocketFactory socketFactory = new SSLSocketFactory(truststore); > > DefaultHttpClient client = new DefaultHttpClient(); > Scheme sch = new Scheme("https", 443, socketFactory); > client.getConnectionManager().getSchemeRegistry().register(sch); > > //Set proxy > setProxy(client, proxyType); > > return client; > } > > private static void setProxy(DefaultHttpClient httpclient, String > proxyType){ > log.info("Setting the proxy server"); > String proxyHost = null; > int proxyPort = 0; > HttpHost hcProxyHost = null; > if(HTTP_PROXY_TYPE.equals(proxyType)){ > proxyHost = HTTP_PROXY_HOST; > proxyPort = HTTP_PROXY_PORT; > hcProxyHost = new HttpHost(proxyHost, proxyPort); > > httpclient.getParams().setParameter(ConnRoutePNames.DEFAULT_PROXY, > hcProxyHost); > log.info("Proxy server set to " + proxyHost +" proxyPort " + > proxyPort); > } else if(SOCKS_PROXY_TYPE.equals(proxyType)){ > proxyHost = SOCKS_PROXY_HOST; > proxyPort = SOCKS_PROXY_PORT; > System.setProperty(SYS_PROP_SOCKS_PROXY_HOST, proxyHost); > System.setProperty(SYS_PROP_SOCKS_PROXY_PORT, ""+proxyPort); > log.info("SOCK proxy is set to ["+ proxyHost +":" + proxyPort > +"]"); > } > } > public static HttpClient getHttpsAllTrustClient(String proxyType) > throws Exception{ > // set up a TrustManager that trusts everything > SSLSocketFactory socketFactory = null; > SSLContext sslContext = SSLContext.getInstance("SSL"); > sslContext.init(null, new TrustManager[] { new > AllPassX509TrustManager()}, new SecureRandom()); > socketFactory = new SSLSocketFactory(sslContext); > socketFactory.setHostnameVerifier(new AllowAllHostnameVerifier()); > DefaultHttpClient client = new DefaultHttpClient(); > > Scheme sch = new Scheme("https", 443, socketFactory); > client.getConnectionManager().getSchemeRegistry().register(sch); > > setProxy(client, proxyType); > return client; > } > > private static class AllPassX509TrustManager implements > X509TrustManager{ > public java.security.cert.X509Certificate[] getAcceptedIssuers() { > return null; > } > public void checkClientTrusted( > java.security.cert.X509Certificate[] certs, String authType) { > } > public void checkServerTrusted( > java.security.cert.X509Certificate[] certs, String authType) { > } > } > } > > package net.vj.proxy; > > > import static net.vj.proxy.Constant.*; > > import java.io.BufferedReader; > import java.io.InputStreamReader; > import java.net.HttpURLConnection; > import java.net.InetSocketAddress; > import java.net.Proxy; > import java.net.URL; > import java.security.KeyStore; > import java.security.KeyStoreException; > import java.security.NoSuchAlgorithmException; > import java.security.cert.Certificate; > import java.security.cert.X509Certificate; > > import javax.net.ssl.HostnameVerifier; > import javax.net.ssl.HttpsURLConnection; > import javax.net.ssl.SSLContext; > import javax.net.ssl.SSLPeerUnverifiedException; > import javax.net.ssl.SSLSession; > import javax.net.ssl.SSLSocketFactory; > import javax.net.ssl.TrustManager; > import javax.net.ssl.TrustManagerFactory; > > import org.apache.http.Header; > import org.apache.http.HttpResponse; > import org.apache.http.client.methods.HttpGet; > import org.apache.http.impl.client.DefaultHttpClient; > import org.apache.log4j.BasicConfigurator; > > import com.avaya.spirit.gateway.common.utils.SecurityUtil; > > > public class TestConnection { > > public static void main(String[] args) throws Exception { > TestConnection test = new TestConnection(); > try{ > System.out.println("Attempting with Default JRE Connection > through HTTP Proxy to: " + SERVER_URL); > test.testWithDefaultJREConnections(HTTP_PROXY_TYPE); > } catch (Exception e){ > e.printStackTrace(); > } > try{ > System.out.println("Connecting with Apache HTTPClient through > HTTP Proxy to :" + SERVER_URL); > test.testWithHttpClient(HTTP_PROXY_TYPE); > } catch (Exception e){ > e.printStackTrace(); > } > try{ > System.out.println("Attempting with Default JRE Connection > through SOCKS Proxy to: " + SERVER_URL); > test.testWithDefaultJREConnections(SOCKS_PROXY_TYPE); > } catch (Exception e){ > e.printStackTrace(); > } > try{ > System.out.println("Connecting with Apache HTTPClient through > SOCKS Proxy to :" + SERVER_URL); > test.testWithHttpClient(SOCKS_PROXY_TYPE); > } catch (Exception e){ > e.printStackTrace(); > } > } > > private void testWithDefaultJREConnections(String proxyType) throws > Exception { > > URL url = new URL(SERVER_URL); > Proxy proxy = null; > if(SOCKS_PROXY_TYPE.equals(proxyType)){ > Proxy.Type type = Proxy.Type.SOCKS; > proxy = new Proxy(type, new InetSocketAddress(SOCKS_PROXY_HOST, > SOCKS_PROXY_PORT)); > } else if (HTTP_PROXY_TYPE.equals(proxyType)){ > Proxy.Type type = Proxy.Type.HTTP; > proxy = new Proxy(type, new InetSocketAddress(HTTP_PROXY_HOST, > HTTP_PROXY_PORT)); > } > HttpURLConnection conn = (HttpURLConnection) > url.openConnection(proxy); > prepareHttpsConnection((HttpsURLConnection) conn); > InputStreamReader isr = new > InputStreamReader(conn.getInputStream()); > BufferedReader br = new BufferedReader(isr); > String line; > while((line = br.readLine()) != null){ > System.out.println("Line: " + line); > } > > } > void prepareHttpsConnection(final HttpsURLConnection conn) throws > Exception{ > > // Resume the use of SSL Session stored in SSLContext, which > // is stored in the SSLSocketFactory > KeyStore truststore = SecurityUtil.getTrustStore(); > > SSLSocketFactory socketFactory = null; > SSLContext sslContext = SSLContext.getInstance("TLS"); > sslContext.init(null, getTrustManagers(truststore), null); > > socketFactory = sslContext.getSocketFactory(); > > conn.setSSLSocketFactory(socketFactory); > conn.setHostnameVerifier(hv); > > HttpsURLConnection.setDefaultHostnameVerifier(hv); > HttpsURLConnection.setDefaultSSLSocketFactory(socketFactory); > } > > @SuppressWarnings("unused") > private final HostnameVerifier hv = new HostnameVerifier() > { > /** > * {@inheritDoc}. > * @see javax.net.ssl.HostnameVerifier#verify(java.lang.String, > javax.net.ssl.SSLSession) > */ > public boolean verify(final String urlHostName, final SSLSession > session) > { > try > { > Certificate[] certs = session.getPeerCertificates(); > X509Certificate cert = (X509Certificate) certs[0]; > } > catch (final SSLPeerUnverifiedException e) > { > e.printStackTrace(); > } > > return false; > } > }; > > > private static TrustManager[] getTrustManagers(KeyStore trustStore) > throws KeyStoreException, NoSuchAlgorithmException{ > TrustManagerFactory tmf = TrustManagerFactory.getInstance("PKIX");; > tmf.init(trustStore); > return tmf.getTrustManagers(); > } > > private void testWithHttpClient(String proxyType) throws Exception{ > BasicConfigurator.configure(); > DefaultHttpClient client = > (DefaultHttpClient)HttpClientFactory.getHttpClient(proxyType); > > HttpGet httpRequest = new HttpGet(SERVER_URL); > System.out.println("Connecting to: " + httpRequest.getURI()); > try{ > HttpResponse response = client.execute(httpRequest); > System.out.println("Response: " + response.getStatusLine()); > for (Header each : response.getAllHeaders()){ > System.out.println(each.getName() + " : " + > each.getValue()); > } > } catch (Exception e){ > e.printStackTrace(); > Throwable t = e.getCause(); > while (t != null){ > System.out.println(" *************Caused by *********"); > t.printStackTrace(); > t = t.getCause(); > } > } > } > } > > ******************************************************************************* > > Output of running the test: > > _______________________________________________________________________________ > Attempting with Default JRE Connection through HTTP Proxy to: > https://somesharepoint.mydomain.com > java.io.IOException: Server returned HTTP response code: 401 for URL: > https://somesharepoint.mydomain.com > at sun.net.www.protocol.http.HttpURLConnection.getInputStream(Unknown > Source) > at sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(Unknown > Source) > at > > net.vj.proxy.TestConnection.testWithDefaultJREConnections(TestConnection.java:80) > at net.vj.proxy.TestConnection.main(TestConnection.java:43) > > Connecting with Apache HTTPClient through HTTP Proxy to : > https://somesharepoint.mydomain.com > INFO [net.vj.proxy.HttpClientFactory] Setting the proxy server > 0 [main] INFO net.vj.proxy.HttpClientFactory - Setting the proxy server > INFO [net.vj.proxy.HttpClientFactory] Proxy server set to 192.168.123.2 > proxyPort 8000 > 1 [main] INFO net.vj.proxy.HttpClientFactory - Proxy server set to > 192.168.123.2 proxyPort 8000 > Connecting to: https://somesharepoint.mydomain.com > Response: HTTP/1.1 401 Unauthorized > Content-Length : 1656 > Content-Type : text/html > Server : Microsoft-IIS/6.0 > WWW-Authenticate : NTLM > MicrosoftSharePointTeamServices : 12.0.0.6520 > X-Powered-By : ASP.NET > Date : Mon, 12 Dec 2011 06:12:28 GMT > > Attempting with Default JRE Connection through SOCKS Proxy to: > https://somesharepoint.mydomain.com > java.io.IOException: Server returned HTTP response code: 401 for URL: > https://somesharepoint.mydomain.com > at sun.net.www.protocol.http.HttpURLConnection.getInputStream(Unknown > Source) > at sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(Unknown > Source) > at > > net.vj.proxy.TestConnection.testWithDefaultJREConnections(TestConnection.java:80) > at net.vj.proxy.TestConnection.main(TestConnection.java:55) > > Connecting with Apache HTTPClient through SOCKS Proxy to : > https://somesharepoint.mydomain.com > INFO [net.vj.proxy.HttpClientFactory] Setting the proxy server > 4105 [main] INFO net.vj.proxy.HttpClientFactory - Setting the proxy server > 4105 [main] INFO net.vj.proxy.HttpClientFactory - Setting the proxy server > INFO [net.vj.proxy.HttpClientFactory] SOCK proxy is set to [ > 192.168.123.7:1080] > 4106 [main] INFO net.vj.proxy.HttpClientFactory - SOCK proxy is set to [ > 192.168.123.7:1080] > 4106 [main] INFO net.vj.proxy.HttpClientFactory - SOCK proxy is set to [ > 192.168.123.7:1080] > Connecting to: https://somesharepoint.mydomain.com > java.net.UnknownHostException: somesharepoint.mydomain.com > at java.net.InetAddress.getAllByName0(Unknown Source) > at java.net.InetAddress.getAllByName(Unknown Source) > at java.net.InetAddress.getAllByName(Unknown Source) > at > > org.apache.http.impl.conn.DefaultClientConnectionOperator.resolveHostname(DefaultClientConnectionOperator.java:242) > at > > org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:130) > at > > org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:149) > at > > org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:121) > at > > org.apache.http.impl.client.DefaultRequestDirector.tryConnect(DefaultRequestDirector.java:573) > at > > org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:425) > at > > org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:820) > at > > org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:754) > at > > org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:732) > at net.vj.proxy.TestConnection.testWithHttpClient(TestConnection.java:159) > at net.vj.proxy.TestConnection.main(TestConnection.java:61) > > _______________________________________________________________________________ > > Please ignore the HTTP 401 error, I am getting it since my server requires > Authentication. > I am concerned with java.net.UnknownHostException: > somesharepoint.mydomain.com, when using HTTPClient through SOCKS Proxy. > > If you wish to run the code, please using your own SecurityUtil class to > create KeyStore, that can trust your server. > > Thank you for reading this really long email/post, I appreciate any input > that you may have. > > Regards > VJ >
