我已经通过使用WireShark检查http通讯来发现/验证了问题。有没有办法解决
这是不可能的。通过SSL套接字进行的通信完全被加密协议的偶然观察所遮盖。使用数据包捕获软件,您将能够查看SSL连接的启动和加密数据包的交换,但是这些数据包的内容只能在连接的另一端(服务器)中提取。如果不是这种情况,那么整个HTTPS协议都会被
破坏 ,因为它的重点是保护HTTP通信免受中间人类型的攻击(在这种情况下,MITM是数据包嗅探器) 。
HTTPS请求(部分)的示例捕获:
.n .... E ............ / .. 5..3..9..2..8 ............. … @
............................... Ql。{… b .... OsR ..!。4。$。T。 ..-.-。T ....
Q.M..Ql。{… LM..L … um.M .... s。… n … p ^ 0} .. I..G4.HK.n … 8Y
...... E … A .. > … 0 … 0 .........)。s ....... 0 .. *。H .. ..... 0F1.0
… U .. ..US1.0 … U。。Google Inc1“ 0 ..U .... Google Internet Authority0
.. 130327132822Z。131231155850Z0h1.0 … U .... US1.0 … U … California1.0
… U … Mountain View1.0 … U。Google Inc1.0 … U .... www.google.com0..0
从理论上讲,知道是否
User-Agent确实排除了标头的唯一方法是您是否有权访问Google服务器,但是实际上,HTTPS规范或Java对其的实现都没有排除标头通常已经发送过来的标头的内容。
HTTP。
HTTP请求捕获示例:
GET / HTTP / 1.1
用户代理:Mozilla / 5.0(Windows NT 5.1; rv:19.0)Gecko / 20100101 Firefox / 19.0
主机:www.google.com
接受:text / html,image / gif,image / jpeg,*;q = .2, / ; q = .2
连接:保持活动状态
这两个示例捕获都是使用 完全相同的 代码生成的:
URL url = new URL(target);URLConnection conn = url.openConnection();conn.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 5.1; rv:19.0) Gecko/20100101 Firefox/19.0");conn.connect();BufferedReader serverResponse = new BufferedReader( new InputStreamReader(conn.getInputStream()));System.out.println(serverResponse.readLine());serverResponse.close();除了HTTPS的目标是“ https://www.google.com ”,HTTP的目标是“
http://www.google.com ”。
编辑1:
根据您更新的问题,使用
-Dhttp.agent属性 确实 会将“ Java
/版本”附加到用户代理标头中,如以下文档所述:
http.agent (默认值:“ Java / <版本>”)
定义在HTTP请求中的User-Agent请求标头中发送的字符串。请注意,字符串“ Java /”将附加到属性中提供的字符串(例如,如果使用-Dhttp.agent =“ foobar”,则User-Agent标头将包含“
foobar Java / 1.5.0”如果VM的版本是1.5.0)。启动时仅检查一次此属性。
“违规”代码位于的静态块初始化程序中
sun.net.www.protocol.http.HttpURLConnection:
static { // ... String agent = java.security.AccessController .doPrivileged(new sun.security.action.GetPropertyAction( "http.agent")); if (agent == null) { agent = "Java/" + version; } else { agent = agent + " Java/" + version; } userAgent = agent; // ...}围绕此“问题”的一种淫秽方式是以下代码片段,我1000%建议您 不要 使用:
protected void forceAgentHeader(final String header) throws Exception { final Class<?> clazz = Class .forName("sun.net.www.protocol.http.HttpURLConnection"); final Field field = clazz.getField("userAgent"); field.setAccessible(true); Field modifiersField = Field.class.getDeclaredField("modifiers"); modifiersField.setAccessible(true); modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL); field.set(null, header);}与
https.proxyHost,
https.proxyPort和
http.agentset 一起使用此覆盖可提供所需的结果:
ConNECT www.google.com:443 HTTP / 1.1
用户代理:Mozilla / 5.0(Windows NT 5.1; rv:19.0)Gecko / 20100101 Firefox / 19.0
主机:www.google.com
接受:text / html,image / gif,图片/ jpeg,*;q = .2, / ; q = .2
代理连接:保持活动状态
但是,是的,不要那样做。仅使用Apache HttpComponents更安全:
final DefaultHttpClient client = new DefaultHttpClient();HttpHost proxy = new HttpHost("127.0.0.1", 8888, "http");HttpHost target = new HttpHost("www.google.com", 443, "https");client.getParams().setParameter(ConnRoutePNames.DEFAULT_PROXY, proxy);HttpProtocolParams .setUserAgent(client.getParams(), "Mozilla/5.0 (Windows NT 5.1; rv:19.0) Gecko/20100101 Firefox/19.0");final HttpGet get = new HttpGet("/");HttpResponse response = client.execute(target, get);


