hc-httpclient-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Oleg Kalnichevski <ol...@apache.org>
Subject Re: How to use httpclient4.0 to connect HTTPS via socks proxy?
Date Wed, 07 Jul 2010 14:02:39 GMT
On Wed, 2010-07-07 at 06:40 -0700, Jacky-Zhu-1 wrote:
> 
> 
> olegk wrote:
> > 
> > On Wed, 2010-07-07 at 05:48 -0700, Jacky-Zhu-1 wrote:
> >> 
> >> 
> >> olegk wrote:
> >> > 
> >> >> Hi Oleg,
> >> >> Yes, I have implemented my SocksSSLSocketFactory who has implemented
> >> the
> >> >> SocketFatory interface, as the code I pasted. 
> >> >> In the debug mode, I also found this class was used by HttpClient,
and
> >> >> the
> >> >> function createSocket and connectSocket of the SocksSSLSocketFactory
> >> were
> >> >> calle, everything is ok before return from connectSocket: the normal
> >> >> socket
> >> >> has been created and conneted to proxy server, the socks4 protocol
> >> >> finished
> >> >> successfully, the sslsocket is created using this normal socket
> >> >> successfully, but after return this sslsocket from connectSocket, the
> >> >> error
> >> >> happens, from the log I found that this sslsocket was shutdown, I
> >> don't
> >> >> know
> >> >> why, I don't know what happend after connectSocket returned the
> >> >> sslsocket.
> >> >> So my problem is that the sslsocket I created was shutdown after I
> >> >> returned
> >> >> it to HttpClient in connectSocket function.
> >> >> 
> >> >> 
> >> >> 10-07-05 10:57:42,269 DEBUG -Get connection for route
> >> >> HttpRoute[{}->https://10.64.69.13:9000]
> >> >>
> >> [org.apache.http.impl.conn.SingleClientConnManager.getConnection(SingleClientConnManager.java:195)]

> >> >> 2010-07-05 10:57:42,269 DEBUG -Get connection for route
> >> >> HttpRoute[{}->https://10.64.69.13:9000]
> >> >>
> >> [org.apache.http.impl.conn.SingleClientConnManager.getConnection(SingleClientConnManager.java:195)]

> >> >> 2010-07-05 10:57:42,286 DEBUG -Connection shut down
> >> >>
> >> [org.apache.http.impl.conn.DefaultClientConnection.shutdown(DefaultClientConnection.java:141)]

> >> >> 2010-07-05 10:57:42,286 DEBUG -Connection shut down
> >> >>
> >> [org.apache.http.impl.conn.DefaultClientConnection.shutdown(DefaultClientConnection.java:141)]

> >> >> 2010-07-05 10:57:42,287 DEBUG -Releasing connection
> >> >> org.apache.http.impl.conn.SingleClientConnManager$ConnAdapter@19ab6f6
> >> >>
> >> [org.apache.http.impl.conn.SingleClientConnManager.releaseConnection(SingleClientConnManager.java:250)]

> >> >> 2010-07-05 10:57:42,287 DEBUG -Releasing connection
> >> >> org.apache.http.impl.conn.SingleClientConnManager$ConnAdapter@19ab6f6
> >> >>
> >> [org.apache.http.impl.conn.SingleClientConnManager.releaseConnection(SingleClientConnManager.java:250)]

> >> >> 2010-07-05 10:57:42,287 ERROR
> >> >> -executeRequest=============================:class:class
> >> >> java.net.SocketException:Socket is not connected
> >> >>
> >> [com.trendmicro.imss.ui.modelobjects.prefilter.client.CommonUtils.executeRequest(CommonUtils.java:641)]

> >> >> 
> >> > 
> >> > Post code of the SocketFactory implementation.
> >> > 
> >> > Oleg
> >> > 
> >> > 
> >> > ---------------------------------------------------------------------
> >> > To unsubscribe, e-mail: httpclient-users-unsubscribe@hc.apache.org
> >> > For additional commands, e-mail: httpclient-users-help@hc.apache.org
> >> > 
> >> > 
> >> > 
> >> 
> >> 
> >> Hi Oleg,
> >> Here is the class which implemented SocketFactory:
> >> public class SocksSSLSocketFactory implements SocketFactory { 
> >> 
> >>     private String proxyHost; 
> >>     private int proxyPort; 
> >>     private String userName; 
> >>     private String passWd; 
> >>     private final javax.net.ssl.SSLSocketFactory socketfactory; 
> >> 
> >>     public SocksSSLSocketFactory(SSLContext sslContext, String socksHost,
> >> int socksPort) { 
> >>         this(sslContext, socksHost, socksPort, null, null); 
> >>     } 
> >> 
> >>     public SocksSSLSocketFactory(SSLContext sslContext, String socksHost,
> >> int socksPort, 
> >>             String userName, String passWd) { 
> >>         this.socketfactory = sslContext.getSocketFactory(); 
> >>         proxyHost = socksHost; 
> >>         proxyPort = socksPort; 
> >>         this.userName = userName; 
> >>         this.passWd = passWd; 
> >>     } 
> >> 
> >>     public Socket createSocket() throws IOException { 
> >>         return (SSLSocket) this.socketfactory.createSocket(); 
> >>     } 
> >> 
> >>     public Socket connectSocket(Socket sock, 
> >>             String host, 
> >>             int port, 
> >>             InetAddress localAddress, 
> >>             int localPort, 
> >>             HttpParams params) throws IOException, UnknownHostException,
> >> ConnectTimeoutException { 
> >>         if (host == null) { 
> >>             throw new IllegalArgumentException("Target host may not be
> >> null."); 
> >>         } 
> >>         if (params == null) { 
> >>             throw new IllegalArgumentException("Parameters may not be
> >> null."); 
> >>         } 
> >> 
> > 
> > Is there any good reason for not re-using Socket instance passed to this
> > method as parameter 'sock'?
> > 
> > Otherwise, I see no obvious problems with your code and I am afraid I
> > will not be able to help any further.
> > 
> > Oleg 
> > 
> > 
> > 
> >>         InetSocketAddress epoint = new InetSocketAddress(host, port); 
> >>         sock = getSocketConnected(epoint); 
> >>         SSLSocket sslSocket =
> >> (SSLSocket)this.socketfactory.createSocket(sock, host, port, false); 
> >>         if ((localAddress != null) || (localPort > 0)) { 
> >>             // we need to bind explicitly 
> >>             if (localPort < 0) { 
> >>                 localPort = 0; // indicates "any" 
> >>             } 
> >>             InetSocketAddress isa = 
> >>                     new InetSocketAddress(localAddress, localPort); 
> >>             sslSocket.bind(isa); 
> >>         } 
> >>         
> >>         return sslSocket; 
> >>     } 
> >> 
> >>     public boolean isSecure(Socket sock) throws IllegalArgumentException
> >> { 
> >>         if (sock == null) { 
> >>             throw new IllegalArgumentException("Socket may not be
> >> null."); 
> >>         } 
> >>         // This check is performed last since it calls a method
> >> implemented 
> >>         // by the argument object. getClass() is final in
> >> java.lang.Object. 
> >>         if (sock.isClosed()) { 
> >>             throw new IllegalArgumentException("Socket is closed."); 
> >>         } 
> >>         return false; 
> >>     } 
> >> 
> >>     //generate the socket connected to socks4 proxy server 
> >>     private Socket getSocketConnected(InetSocketAddress endpoint) throws
> >> IOException { 
> >>         Socket socket = new Socket(proxyHost, proxyPort); 
> >>         InputStream in = socket.getInputStream(); 
> >>         OutputStream out = socket.getOutputStream(); 
> >> 
> >>         out.write(4); 
> >>         out.write(1); 
> >>         out.write((endpoint.getPort() >> 8) & 0xff); 
> >>         out.write((endpoint.getPort() >> 0) & 0xff); 
> >>         out.write(endpoint.getAddress().getAddress()); 
> >>         if (userName != null) 
> >>         { 
> >>             try { 
> >>                 out.write(userName.getBytes("ISO-8859-1")); 
> >>             } catch (java.io.UnsupportedEncodingException uee) { 
> >>                 assert false; 
> >>             } 
> >>         } 
> >>         out.write(0); 
> >>         out.flush(); 
> >>         byte[] data = new byte[8]; 
> >>         int n = readSocketReply(in, data); 
> >>         if (n != 8) { 
> >>             throw new SocketException("Reply from SOCKS server has bad
> >> length: " + n); 
> >>         } 
> >>         if (data[0] != 0 && data[0] != 4) { 
> >>             throw new SocketException("Reply from SOCKS server has bad
> >> version"); 
> >>         } 
> >>         SocketException ex = null; 
> >>         switch (data[1]) { 
> >>             case 90: 
> >>                 // Success! 
> >>                 break; 
> >>             case 91: 
> >>                 ex = new SocketException("SOCKS request rejected"); 
> >>                 break; 
> >>             case 92: 
> >>                 ex = new SocketException("SOCKS server couldn't reach
> >> destination"); 
> >>                 break; 
> >>             case 93: 
> >>                 ex = new SocketException("SOCKS authentication failed"); 
> >>                 break; 
> >>             default: 
> >>                 ex = new SocketException("Reply from SOCKS server
> >> contains
> >> bad status"); 
> >>                 break; 
> >>         } 
> >>         if (ex != null) { 
> >>             in.close(); 
> >>             out.close(); 
> >>             throw ex; 
> >>         } 
> >> 
> >>         return socket; 
> >>     } 
> >> 
> >>     private int readSocketReply(InputStream in, byte[] data) throws
> >> IOException { 
> >>         int len = data.length; 
> >>         int received = 0; 
> >>         for (int attempts = 0; received < len && attempts < 3;
> >> attempts++) { 
> >>             int count = in.read(data, received, len - received); 
> >>             if (count < 0) 
> >>                 throw new SocketException("Malformed reply from SOCKS
> >> server"); 
> >>             received += count; 
> >>         } 
> >>         return received; 
> >>     } 
> >> } 
> >> 
> > 
> > 
> > 
> > ---------------------------------------------------------------------
> > To unsubscribe, e-mail: httpclient-users-unsubscribe@hc.apache.org
> > For additional commands, e-mail: httpclient-users-help@hc.apache.org
> > 
> > 
> > 
> 
> 
> Because the 'sock' passed in is just one unconnected sslsocket created in
> the function createSocket, it's not useful in my solution.
> 

Why?

> Maybe I should read the httpclient source code to see what happened.
> If any finding, I will update it here.
> Maybe I should read the HttpClient source code to see 

This always helps.

Oleg


---------------------------------------------------------------------
To unsubscribe, e-mail: httpclient-users-unsubscribe@hc.apache.org
For additional commands, e-mail: httpclient-users-help@hc.apache.org


Mime
View raw message