hc-httpclient-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Jacky-Zhu-1 <jacky_...@trendmicro.com.cn>
Subject How to use httpclient4.0 to connect HTTPS via socks proxy?
Date Sun, 04 Jul 2010 18:39:02 GMT

I've been trying to use httpclient4.0 to connect https server via socks
proxy, but it failed again and again.

My code is something like this:
KeyStore ks = loadCertFromFile(certFileName, passphrase);
X509TrustManager trustManager = getTrustManager(ks);
SocketFactory sf = new SocksSSLSocketFactory(getSSLContext(trustManager),
"10.64.69.40", 1080);
DefaultHttpClient httpclient = new DefaultHttpClient();
ClientConnectionManager ccm = httpclient.getConnectionManager();
SchemeRegistry schemeRegistry = ccm.getSchemeRegistry();
schemeRegistry.register(new Scheme("https", sf, portNumber));
httpResponse = httpclient.execute(httpHost, httpUriRequest);

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.");
        }

        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 sock;
    }

    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;
    }
}


But I got java.net.SocketException:Socket is not connected when running:
httpResponse = httpclient.execute(httpHost, httpUriRequest);

Here is the log.
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)]


Actually I have connected to the proxy server in the connectSocket function,
I couldn't figure out why it reported this exception? (Why connection
shutdown after getconnection?)

Anyone can help me? Thank you in advance.
-- 
View this message in context: http://old.nabble.com/How-to-use-httpclient4.0-to-connect-HTTPS-via-socks-proxy--tp29070494p29070494.html
Sent from the HttpClient-User mailing list archive at Nabble.com.


---------------------------------------------------------------------
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