我可以在使用 java 的 HttpUrlConnection 类的地方覆盖 Host 标头吗?

Posted

技术标签:

【中文标题】我可以在使用 java 的 HttpUrlConnection 类的地方覆盖 Host 标头吗?【英文标题】:Can I override the Host header where using java's HttpUrlConnection class? 【发布时间】:2011-11-30 17:20:55 【问题描述】:

我正在使用以下代码在 java 中打开 http 连接:

 URL url = new URL("http://***.com");
 HttpURLConnection conn = (HttpURLConnection) url.openConnection();
 conn.setDoOutput(true);
 conn.setRequestMethod("GET");
 conn.setRequestProperty("Host", "Test:8080");
 conn.getOutputStream();

但是,无论我调用方法的顺序如何,调用 conn.setRequestProperty("Host", "Test:8080") 似乎都没有效果,并且主机被重置到目标服务器。有没有办法在不使用其他库的情况下覆盖 Host 标头?

TIA 马特

【问题讨论】:

【参考方案1】:

这在过去可以正常工作,但已作为安全修复的一部分被禁用。显然在更改日志中没有注释。在 bugs.sun.com 上甚至还有像 #7022056 这样的错误。

另一个标题有一个similar question,答案更详细,所以我只是链接它而不是自己写。 :-)

唯一的解决方法似乎是将sun.net.http.allowRestrictedHeaders 设置为true 或使用另一个http 库,如已经提到的http components。

【讨论】:

谢谢,System.setProperty("sun.net.http.allowRestrictedHeaders", "true") 效果很好。 啊,刚刚花了几个小时调试这个并寻找答案!非常感谢。【参考方案2】:

Host 标头由基于 URL 的 HttpURLConnection 填充。您无法使用Host=bar.com 打开foo.com。来自RFC

Host request-header 字段指定被请求资源的 Internet 主机和端口号,从用户给出的原始 URI 或引用资源(通常是 HTTP URL)获得

顺便说一句,你也可以试试apache http components。

【讨论】:

谢谢,它很可能是 RFC 兼容的,但它不是很有帮助,因为我正在尝试实现一个反向代理,它需要修改主机头上的端口,因为目标服务器需要端口映射。 你可以试试apache http组件 一般我同意,但您可能必须连接到一个不受您控制的奇怪远程系统,该系统没有 DNS 条目,但仍需要正确的主机标头,因为它有虚拟主机。可悲的是,我今天遇到了这样的情况,但我希望(为了所有其他人)它们真的很少见。 ;-)【参考方案3】:

这是 volley 如何处理 HTTPUrlConnection 和重试策略的问题。

一个快速的解决方法是扩展“HurlStack”类并覆盖“createConnection”函数以返回一个HTTPUrlConnection,其ChunkStreamMode为0

public class CustomHurlStack extends HurlStack 


   public CustomHurlStack()
       super();

   

   @Override
   protected HttpURLConnection createConnection(URL url) throws IOException 
       HttpURLConnection connection = super.createConnection(url);
       connection.setChunkedStreamingMode(0);
       return connection;
   

【讨论】:

以上是关于我可以在使用 java 的 HttpUrlConnection 类的地方覆盖 Host 标头吗?的主要内容,如果未能解决你的问题,请参考以下文章

使用URL设置ImageView

java 通过HTTP请求模拟登陆,获取不到cookie,高手帮忙看一下,代码如下

我可以在使用 java 的移动设备上启用蓝牙吗?

是否可以在 java 项目中使用 lupdate(QtLinguist)?

我可以在使用 java 的 HttpUrlConnection 类的地方覆盖 Host 标头吗?

使用“默认”参数值重载 Java 方法