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$connadap...@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$connadap...@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: [email protected]
>>> > For additional commands, e-mail: [email protected]
>>> > 
>>> > 
>>> > 
>>> 
>>> 
>>> 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: [email protected]
>> For additional commands, e-mail: [email protected]
>> 
>> 
>> 
> 
> 
> Because the 'sock' passed in is just one unconnected sslsocket created in
> the function createSocket, it's not useful in my solution.
> 
> 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 
> 

My expected solution is that:
1. create one normal socket, connect it to the proxy server
2. use this normal socket to go through the socks proxy
3. parse this socket to one new sslsocket in the function connectSocket

The pass parameter 'sock' in connectSocket is created by function
createSocket, who is an unconneted sslsocket, so it's not useful in my
solution. I go through the step 1/2/3 all in the connectSocket.

Oleg, thanks for your patient reply and help, I appreciate it very much.

-- 
View this message in context: 
http://old.nabble.com/How-to-use-httpclient4.0-to-connect-HTTPS-via-socks-proxy--tp29070494p29100013.html
Sent from the HttpClient-User mailing list archive at Nabble.com.


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to