{
return super.createSocket(context);
}
}
@Override
public Socket connectSocket(int connectTimeout, Socket socket, HttpHost host, InetSocketAddress remoteAddress,
InetSocketAddress localAddress, HttpContext context) throws IOException {
ProxyConfig proxyConfig = (ProxyConfig) context.getAttribute(ProxyConfigKey);
if (proxyConfig != null) {//make proxy server to resolve host in http url
remoteAddress = InetSocketAddress
.createUnresolved(host.getHostName(), host.getPort());
}
return super.connectSocket(connectTimeout, socket, host, remoteAddress, localAddress, context);
}
}
然后在创建httpclient对象时,给HttpClientConnectionManager设置socketFactoryRegistry
Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create()
.register(Protocol.HTTP.toString(), new SocksConnectionSocketFactory())
.register(Protocol.HTTPS.toString(), new SocksSSLConnectionSocketFactory(sslContext, NoopHostnameVerifier.INSTANCE))
.build();
PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(socketFactoryRegistry);
让代理服务器解析域名
场景:运行httpClient的进程所在主机可能并不能上公网,大部分时候,也无法进行DNS解析,这时通常会出现域名无法解析的IO异常,下面介绍怎么避免在客户端解析域名。
上面有一行代码非常关键:
remoteAddress = InetSocketAddress
.createUnresolved(host.getHostName(), host.getPort());
变量host是你发起http请求的目标主机和端口信息,这里创建了一个未解析(Unresolved)的SocketAddress,在socks协议握手阶段,InetSocketAddress信息会原封不动的发送到代理服务器,由代理服务器解析出具体的IP地址。
Socks的协议描述中有个片段:
The SOCKS request is formed as follows:
+----+-----+-------+------+----------+----------+
|VER | CMD | RSV | ATYP | DST.ADDR | DST.PORT |
+----+-----+-------+------+----------+----------+
| 1 | 1 | X'00' | 1 | Variable | 2 |
+----+-----+-------+------+----------+----------+
Where:
o VER protocol version: X'05'
o CMD
o CONNECT X'01'
o BIND X'02'
o UDP ASSOCIATE X'03'
o RSV RESERVED
&nbs