我设置了 HTTPS 代理,以便 HTTP 客户端可以安全地将纯 HTTP 请求发送到代理。例如,客户端可以向代理发送加密的 HTTP GET 请求,代理将删除加密并将纯 HTTP GET 请求发送到终端站点。
我了解到这不是一个常见的设置,只有谷歌浏览器具有支持这种情况的内置功能。(此处的信息 - http://wiki.squid-cache.org/Features/HTTPS#Encrypted_browser-Squid_connection)。我已经让 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
注意:对于 HTTPS 终端站点,代理只能看到 CONNECT 请求。然后在客户端和终端站点之间建立 SSL 隧道
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 请求应加密到代理。无论如何,后续请求将被隧道化。
任何人都可以让我知道如何实现这个目标吗?我相信 HttpRoutePlanner 应该会有所帮助,但我不知道如何。