Curl具有手动指定要将主机解析到的IP的功能.例如:
curl https://google.com --resolve "google.com:443:173.194.72.113"
Run Code Online (Sandbox Code Playgroud)
这在使用HTTPS时特别有用.如果它只是一个HTTP请求,我可以通过直接指定IP地址并添加主机头来实现相同的目的.但是在HTTPS中会破坏连接,因为SSL证书主机将与IP地址而不是主机头进行比较.
我的问题是,我怎样才能在Java中实现同样的目标?
Joh*_*hnK 12
如果使用Apache的HttpClient,您可以创建自定义DNS解析程序来检测您要重定向的主机,然后提供替代IP地址.
注意:仅更改HTTPS请求的主机标头不起作用.它会抛出"javax.net.ssl.SSLPeerUnverifiedException",强迫你信任坏证书,阻止SNI工作等等,所以真的不是一个选择.自定义DnsResolver是我发现在Java中使用HTTPS使用这些请求的唯一干净方法.
例:
/* Custom DNS resolver */
DnsResolver dnsResolver = new SystemDefaultDnsResolver() {
@Override
public InetAddress[] resolve(final String host) throws UnknownHostException {
if (host.equalsIgnoreCase("my.host.com")) {
/* If we match the host we're trying to talk to,
return the IP address we want, not what is in DNS */
return new InetAddress[] { InetAddress.getByName("127.0.0.1") };
} else {
/* Else, resolve it as we would normally */
return super.resolve(host);
}
}
};
/* HttpClientConnectionManager allows us to use custom DnsResolver */
BasicHttpClientConnectionManager connManager = new BasicHttpClientConnectionManager(
/* We're forced to create a SocketFactory Registry. Passing null
doesn't force a default Registry, so we re-invent the wheel. */
RegistryBuilder.<ConnectionSocketFactory>create()
.register("http", PlainConnectionSocketFactory.getSocketFactory())
.register("https", SSLConnectionSocketFactory.getSocketFactory())
.build(),
null, /* Default ConnectionFactory */
null, /* Default SchemePortResolver */
dnsResolver /* Our DnsResolver */
);
/* build HttpClient that will use our DnsResolver */
HttpClient httpClient = HttpClientBuilder.create()
.setConnectionManager(connManager)
.build();
/* build our request */
HttpGet httpRequest = new HttpGet("https://my.host.com/page?and=stuff");
/* Executing our request should now hit 127.0.0.1, regardless of DNS */
HttpResponse httpResponse = httpClient.execute(httpRequest);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
6606 次 |
| 最近记录: |