Proxy HttpRoutePlanner-它如何与HTTPS代理一起工作

Proxy HttpRoutePlanner-它如何与HTTPS代理一起工作,proxy,apache-httpclient-4.x,apache-commons-httpclient,Proxy,Apache Httpclient 4.x,Apache Commons Httpclient,我设置了一个HTTPS代理,以便HTTP客户端可以安全地向代理发送普通HTTP请求。例如,客户端可以向代理发送加密的HTTP GET请求,代理将删除加密并将普通HTTP GET请求发送到终端站点 我了解到,这不是一个常见的设置,只有谷歌浏览器有内置功能来支持这种情况。(信息在此-)。我已经让Google Chrome与我的HTTPS代理一起工作,因此在代理端没有问题 我希望编写一个HTTP客户端,它将加密对HTTPS代理的所有请求。我尝试通过这种方式将HTTPS代理设置为DefaultHttpC

我设置了一个HTTPS代理,以便HTTP客户端可以安全地向代理发送普通HTTP请求。例如,客户端可以向代理发送加密的HTTP GET请求,代理将删除加密并将普通HTTP GET请求发送到终端站点

我了解到,这不是一个常见的设置,只有谷歌浏览器有内置功能来支持这种情况。(信息在此-)。我已经让Google Chrome与我的HTTPS代理一起工作,因此在代理端没有问题

我希望编写一个HTTP客户端,它将加密对HTTPS代理的所有请求。我尝试通过这种方式将HTTPS代理设置为DefaultHttpClient-

DefaultHttpClient dhc = new DefaultHttpClient();
HttpHost proxy = new HttpHost("192.168.2.3", 8181, "https"); //NOTE : https
dhc.getParams().setParameter(ConnRoutePNames.DEFAULT_PROXY, proxy);
然后尝试执行任何请求会给我一个SSLPeerUnverifiedException。我不明白为什么

在探索DefaultHttpClient API的过程中,我遇到了HttpRoutePlanner和HttpRoute,通过它们我们可以指定是否应该加密与代理的连接。然而,我无法使这项工作

下面是一个图表,通过将我的设置与HTTP代理设置区分开来来解释我的设置-

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
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
HTTP客户端HTTP代理HTTP终端站点
HTTP客户端HTTP代理HTTPS终端站点
注意:对于HTTPS终端站点,代理只能看到连接请求。然后在客户端和终端站点之间建立SSL隧道

HTTPS代理:

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
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
HTTP客户端HTTPS代理HTTP终端站点
HTTP客户端HTTPS代理HTTPS终端站点
注意:对于HTTPS终端站点,只有初始连接请求应加密到代理。随后的请求无论如何都将通过隧道传输


有人能告诉我如何实现这个目标吗?我相信HttpRoutePlanner应该会有所帮助,但我不知道该怎么做。

ApacheHttpClient 4.x仅通过连接隧道通过代理支持SSL。它不支持HTTPS代理。

我能够使Apache HttpClient 4.x与HTTPS代理一起工作。我在问题中提到的SSLPeerUnverifiedException被抛出,因为我不信任代理服务器的证书。一旦解决了这一问题,那么到HTTPS终端站点的连接将按预期工作

对于HTTP终端站点的连接,我必须使用自己的HttpRoutePlanner使其工作。这是代码和解释-

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终端站点通信,路由应该是安全的,但不应该有任何隧道或分层

@MediumOne相信我,它不起作用。看,它确实对我有用。我遇到了海报在有HTTP终端站点时遇到的相同错误。错误是-
“无法建立路由:计划={}->https://localhost:7777->;http://www.exceptional.io;当前={s}->https://localhost:7777->;http://www.exceptional.io“
我可以通过将自己的RoutePlanner设置为“true”来强制建立安全连接。现在计划的路线变成
{s}->https://localhost:7777->;http://www.exceptional.io“
我看不到任何错误。您的示例似乎是关于通过HTTPS代理的HTTP,而不是通过HTTPS的HTTPS。如果要使用“信任所有”策略,使用“双”SSL层有什么意义。。。