Java HttpURLConnection | POST方法| HTTP标头字段的序列

时间:2013-12-26 22:46:02

标签: java http post httpurlconnection

我试图使用java.net.HttpURLConnection在Java中“欺骗”Firefox HTTP POST请求。 我使用Wireshark来检查发送的HTTP头,所以我(希望)有可靠的信息来源,为什么Java结果与理想情况不符(使用Firefox)。

我已将所有标题字段完全设置为Firefox通过HTTP发送的值,并注意到标题字段的顺序不一样。 Firefox的输出如下:

POST ...
**Host**
User-Agent
Accept
Accept-Language
Accept-Encoding
Referer
Connection
Content-Type
Content-Length

当我让wireshark在Java中点击我的实现时,它给了我一个稍微不同的字段序列:

POST...
**User-Agent**
Accept
Accept-Language
Accept-Encoding
Referer
Content-Type
Host
Connection
Content-Length

所以基本上,我有所有的字段,只是以不同的顺序。 我还注意到Host字段的发送值不同: www.thewebsite.com(Firefox)< ---> thewebsite.com(Java HttpURLConnection),虽然我使用“www。”将字符串传递给httpUrlConnection.setRequestProperty

我还没有分析过Wireshark的字节输出,但是我知道服务器在我的响应的标题字段中没有返回相同的Location

我的问题是:

(1)是否可以控制请求中标题字段的顺序,如果是,是否可以使用HttpURLConnection?如果没有,是否可以使用Java直接控制HTTP头中的字节? [我不拥有服务器,所以我唯一的希望让POST方法正常工作是通过我的应用假冒Firefox,服务器并不是真的很冗长,我的唯一信息是:Apache with PHP]

(2)有没有办法解决上面描述的setRequestProperty()问题(“www”)?

(3)还有什么重要的? (我需要关注底层,TCP ......?)

感谢您提出任何意见。

PS。我试图模拟没有发送cookie的情况,这样我就可以忽略这种效果。

3 个答案:

答案 0 :(得分:5)

首先,标题的顺序无关紧要。

其次,为了手动覆盖host标题,您需要在代码中设置sun.net.http.allowRestrictedHeaders=true

System.setProperty("sun.net.http.allowRestrictedHeaders", "true")

或在JVM开始

-Dsun.net.http.allowRestrictedHeaders=true

这是Oracle不久前提出的一项安全预防措施。那是因为根据RFC

  

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

答案 1 :(得分:2)

标题顺序并不重要。服务器获得的标头也是无序的。并且您无法控制httpUrlConnection标头顺序。但是,如果您编写自己的TCP客户端,则可以控制标题顺序。像:

clientSocket = new Socket(serverHost,serverPort);

OutputStream os = clientSocket.getOutputStream();

String send = "GET /?id=y2y HTTP/1.1\r\nConnection: keep-alive\r\nKeep-Alive: timeout=15, max=200\r\nHost: chillyc.info\r\n\r\nGET /?id=y2y HTTP/1.1\r\nConnection: keep-alive\r\nKeep-Alive: timeout=15, max=200\r\nHost: chillyc.info\r\n\r\n";

os.write(send.getBytes());

MarcelStör在第一个答案中回答了第二个问题。  一个

答案 2 :(得分:0)

我很幸运使用Apache Http Components,我的猜测是" Host"标题缺少" www。"差异化,可以使用Apache的HttpPost

完全按照预期设置
httpPost.setHeader("Host", "www.thewebsite.com");

Wireshark输出证实了我的怀疑。此次,我的HTTP帖子之前的TCP通信看起来不同(客户端--->服务器,服务器--->客户端,客户端--->服务器)而不是(客户端--->服务器,服务器) --->客户端,客户端--->服务器,客户端--->服务器)。

现在我获得了所需的Location标头值,服务器也在设置cookie。 :)

在大多数情况下,这个问题已得到解决。

实际上我想使用lightweihgt HttpUrlConnection,因为这是Android Developers博客建议的内容。 System.setProperty("sun.net.http.allowRestrictedHeaders", "true")如果允许{" www。"在Host值。