HttpRoutePlanner-它如何与HTTPS代理一起使用 [英] HttpRoutePlanner - How does it work with an HTTPS Proxy
问题描述
我已经设置了HTTPS代理,以便HTTP客户端可以将纯HTTP请求安全地发送到代理.例如,客户端可以将加密的HTTP GET请求发送到代理,代理将删除加密并将纯HTTP GET请求发送到终端站点.
I have an HTTPS proxy set up so that HTTP clients can send plain HTTP requests securely to the proxy. For example, a client can send an encrypted HTTP GET request to the proxy, which will remove the encryption and send the plain HTTP GET request to the end-site.
我了解到这不是一个常见的设置,只有Google Chrome浏览器具有内置功能来支持这种情况. (此处的信息- http://wiki.squid-cache.org/Features/HTTPS#Encrypted_browser-Squid_connection ).我已经将Google Chrome浏览器与HTTPS代理一起使用,因此在代理方面没有任何麻烦.
I learned that this is not a common set up and only Google Chrome has in-built features to support such a scenario. (Info here - http://wiki.squid-cache.org/Features/HTTPS#Encrypted_browser-Squid_connection). I have made Google Chrome work with my HTTPS proxy and hence there is no trouble on the proxy side.
我希望编写一个HTTP客户端,该客户端将加密对我的HTTPS代理的所有请求.我尝试通过这种方式将HTTPS代理设置为DefaultHttpClient-
I wish to write an HTTP Client that will encrypt all requests to my HTTPS Proxy. I tried setting an HTTPS proxy to DefaultHttpClient this way -
DefaultHttpClient dhc = new DefaultHttpClient();
HttpHost proxy = new HttpHost("192.168.2.3", 8181, "https"); //NOTE : https
dhc.getParams().setParameter(ConnRoutePNames.DEFAULT_PROXY, proxy);
然后尝试执行任何请求都会给我SSLPeerUnverifiedException.我不明白原因.
Then trying to execute any request gives me an SSLPeerUnverifiedException. I do not understand the reason why.
在探索DefaultHttpClient API的过程中,我遇到了HttpRoutePlanner和HttpRoute,我们可以使用它们指定是否应加密与代理的连接.但是,我无法完成这项工作.
During my exploration of the DefaultHttpClient API, I came across HttpRoutePlanner and HttpRoute with which we can specify whether the connection to proxies should be encrypted or not. However, I am unable to make this work.
以下是通过与HTTP代理设置进行区别的方式解释了我的设置的图-
Here is a diagram that explains my setup by differentiating it with a HTTP Proxy setup -
HTTP代理:
HTTP Client <------- Plain Text GET, POST Requests -------> HTTP Proxy <------- Plain Text GET, POST Requests -------> HTTP End-Site
HTTP Client <------- Plain Text CONNECT Requests -------> HTTP Proxy <------- Plain Text CONNECT Requests -------> HTTPS End-Site
注意:对于HTTPS终端站点,代理只能看到CONNECT请求.然后在客户端和站点之间建立一个SSL隧道
NOTE: For HTTPS End-Sites, only the CONNECT Request is seen by the proxy. Then an SSL Tunnel is established between the Client and End-Site
HTTPS代理:
HTTP Client <------- Encrypted GET, POST Requests -------> HTTPS Proxy <-------- Plain Text GET, POST Requests --------> HTTP End-Site
HTTP Client <------- Encrypted CONNECT Requests -------> HTTPS Proxy <------- Plain Text CONNECT Requests -------> HTTPS End-Site
注意:对于HTTPS终端站点,仅应将初始CONNECT请求加密到代理.无论如何,后续请求将被隧穿.
NOTE: For HTTPS End-Sites, only the initial CONNECT Request should be encrypted to the proxy. The subsequent request will anyway be tunnelled.
有人可以让我知道我如何实现这个目标吗?我相信HttpRoutePlanner应该可以提供帮助,但是我不知道如何.
Can anybody please let me know how I can achieve this goal? I believe HttpRoutePlanner should help, but I don't know how.
推荐答案
我能够使Apache HttpClient 4.x与HTTPS代理一起使用.因为我不信任代理服务器的证书,所以引发了我在问题中提到的SSLPeerUnverifiedException.处理完这些之后,到HTTPS终端站点的连接将按预期工作.
I was able to make the Apache HttpClient 4.x work with the HTTPS proxy. The SSLPeerUnverifiedException that I mentioned in the question was thrown because I was not trusting the Proxy Server's certificate. Once this is taken care of, then connections to HTTPS End-Sites worked as expected.
要连接到HTTP终端站点,我必须使用自己的HttpRoutePlanner使其起作用.这是带有说明的代码-
For connections to HTTP end-sites, I had to use my own HttpRoutePlanner to make it work. Here's the code with the explanations -
DefaultHttpClient dhc = new DefaultHttpClient();
HttpHost proxy = new HttpHost("192.168.2.3", 8181, "https");
dhc.getParams().setParameter(ConnRoutePNames.DEFAULT_PROXY, proxy);
SchemeSocketFactory factory = null;
try {
factory = new SSLSocketFactory(new SimpleTrustStrategy()); //Trust All strategy
} catch (GeneralSecurityException e1) {
e1.printStackTrace();
}
Scheme https = new Scheme("https", 443, factory);
dhc.getConnectionManager().getSchemeRegistry().register(https);
HttpGet request = new HttpGet("http://en.wikipedia.org/wiki/Main_Page");
try {
HttpHost host = determineTarget(request);
if(host.getSchemeName().equalsIgnoreCase("http")){
dhc.setRoutePlanner(new MyRoutePlanner());
}
} catch (ClientProtocolException e1) {
e1.printStackTrace();
}
MyRoutePlanner
的实现如下-
public class MyRoutePlanner implements HttpRoutePlanner {
@Override
public HttpRoute determineRoute(HttpHost target, HttpRequest request,
HttpContext context) throws HttpException {
return new HttpRoute(target, null
, new HttpHost("192.168.2.3", 8181, "https")
, true, TunnelType.PLAIN, LayerType.PLAIN); //Note: true
}
}
要使HttpClient通过HTTPS代理与HTTP终端站点对话,路由应该是安全的,但不应有任何隧道或分层.
To make the HttpClient talk to a HTTP End-site through an HTTPS Proxy, the route should be secure, but there should not be any Tunnelling or Layering.
这篇关于HttpRoutePlanner-它如何与HTTPS代理一起使用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!