Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/315.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/url/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java HttpURLConnection属性顺序_Java_Url_Http Headers_Httpconnection_Request Headers - Fatal编程技术网

Java HttpURLConnection属性顺序

Java HttpURLConnection属性顺序,java,url,http-headers,httpconnection,request-headers,Java,Url,Http Headers,Httpconnection,Request Headers,我需要一个特殊的订单。 因此,我按要求的顺序为每个属性调用setRequestProperty: URL url = new URL(urlString); HttpURLConnection request = (HttpURLConnection) url.openConnection(); request.setRequestMethod("GET"); request.setRequestProperty

我需要一个特殊的订单。 因此,我按要求的顺序为每个属性调用setRequestProperty:

        URL url = new URL(urlString);
        HttpURLConnection request = (HttpURLConnection) url.openConnection();
        request.setRequestMethod("GET");
        request.setRequestProperty("Host", "myhostname.com");
        request.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:85.0) Gecko/20100101 Firefox/85.0");
        request.setRequestProperty("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8");
        request.setRequestProperty("Accept-Language", "ru-RU,ru;q=0.8,en-US;q=0.5,en;q=0.3");
        request.setRequestProperty("Accept-Encoding", "gzip, deflate, br");
        request.setRequestProperty("Connection", "keep-alive");
        request.setRequestProperty("Cookie", cookies);
        request.setRequestProperty("Upgrade-Insecure-Requests", "1");
        request.setRequestProperty("Cache-Control", "max-age=0");
但实际(嗅探)请求如下所示:

    GET /api/apitest&code=1 HTTP/1.1\r\n
    User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:85.0) Gecko/20100101 Firefox/85.0\r\n
    Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8\r\n
    Accept-Language: ru-RU,ru;q=0.8,en-US;q=0.5,en;q=0.3\r\n
    Accept-Encoding: gzip, deflate, br\r\n
    Cookie: <cookie>\r\n
    Upgrade-Insecure-Requests: 1\r\n
    Cache-Control: max-age=0\r\n
    Host: myhostname.com\r\n
    Connection: keep-alive\r\n
GET/api/apitest&code=1 HTTP/1.1\r\n
用户代理:Mozilla/5.0(Windows NT 10.0;Win64;x64;rv:85.0)Gecko/20100101 Firefox/85.0\r\n
接受:text/html、application/xhtml+xml、application/xml;q=0.9,图像/webp,*/*;q=0.8\r\n
接受语言:如如如,如;q=0.8,在美国;q=0.5,en;q=0.3\r\n
接受编码:gzip,deflate,br\r\n
Cookie:\r\n
升级不安全的请求:1\r\n
缓存控制:最大年龄=0\r\n
主机:myhostname.com\r\n
连接:保持活动状态\r\n

有没有办法保持标题顺序不变?

所以我用RawHttp解决了这个问题:

RawHttp http = new RawHttp();
RawHttpRequest httpRequest = http.parseRequest("GET /api/apitest&code="+code+" HTTP/1.1\r\n" +
                "Host:myhostname.com\r\n" +
                "User-Agent:Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:85.0) Gecko/20100101 Firefox/85.0\r\n" +
                "Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8\r\n" +
                "Accept-Language:ru-RU,ru;q=0.8,en-US;q=0.5,en;q=0.3\r\n" +
                "Accept-Encoding:gzip, deflate, br\r\n" +
                "Connection:keep-alive\r\n" +
                "Cookie:" + cookies + "\r\n" +
                "Upgrade-Insecure-Requests:1\r\n" +
                "Cache-Control:max-age=0");

        URL url = new URL(api_url);
        Socket httpsSocket = HttpsURLConnection.getDefaultSSLSocketFactory().createSocket(api_url.getHost(),  443);

        httpRequest.writeTo(httpsSocket.getOutputStream());
        RawHttpResponse httpResponse = http.parseResponse(httpsSocket.getInputStream());

        BodyReader body = httpResponse.getBody().get();
        String response = body.decodeBodyToString(StandardCharsets.UTF_8);
身体的存在可以通过

httpResponse.getBody().isPresent()
现在标题顺序不变,并且此不符合RFC的服务器正确应答

为了显示结果,我已将端口更改为80,但其他一切都是一样的:

Frame 6099: 680 bytes on wire (5440 bits), 680 bytes captured (5440 bits) on interface \Device\NPF_{28393799-9889-4CF5-B65C-ED851CC47ECC}, id 0
Ethernet II, Src: ASUSTekC_<MAC>, Dst: D-Link_<MAC>
Internet Protocol Version 4, Src: 192.168.1.3, Dst: <IP>
Transmission Control Protocol, Src Port: 58530, Dst Port: 80, Seq: 4, Ack: 1, Len: 626
[2 Reassembled TCP Segments (629 bytes): #6096(3), #6099(626)]
Hypertext Transfer Protocol
    GET /api/apitest&code=1 HTTP/1.1\r\n
    Host: myhostname.com\r\n
    User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:85.0) Gecko/20100101 Firefox/85.0\r\n
    Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8\r\n
    Accept-Language: ru-RU,ru;q=0.8,en-US;q=0.5,en;q=0.3\r\n
    Accept-Encoding: gzip, deflate, br\r\n
    Connection: keep-alive\r\n
    Cookie: <cookie>\r\n
    Upgrade-Insecure-Requests: 1\r\n
    Cache-Control: max-age=0\r\n
    \r\n
    [Full request URI: http://myhostname.com/api/apitest&code=1]
    [HTTP request 1/1]
    [Response in frame: 6101]
Frame 6099:680字节在线路上(5440位),680字节在接口\Device\NPF{28393799-9889-4CF5-B65C-ED851CC47ECC}上捕获(5440位),id 0
Ethernet II,Src:ASUSTekC,Dst:D-Link_
互联网协议版本4,Src:192.168.1.3,Dst:
传输控制协议,Src端口:58530,Dst端口:80,序列:4,应答:1,长度:626
[2个重新组装的TCP段(629字节):#6096(3),#6099(626)]
超文本传输协议
GET/api/apitest&code=1 HTTP/1.1\r\n
主机:myhostname.com\r\n
用户代理:Mozilla/5.0(Windows NT 10.0;Win64;x64;rv:85.0)Gecko/20100101 Firefox/85.0\r\n
接受:text/html、application/xhtml+xml、application/xml;q=0.9,图像/webp,*/*;q=0.8\r\n
接受语言:如如如,如;q=0.8,在美国;q=0.5,en;q=0.3\r\n
接受编码:gzip,deflate,br\r\n
连接:保持活动状态\r\n
Cookie:\r\n
升级不安全的请求:1\r\n
缓存控制:最大年龄=0\r\n
\r\n
[完整请求URI:http://myhostname.com/api/apitest&code=1]
[HTTP请求1/1]
[帧中的响应:6101]
然后我移动了主机头,捕获的数据包也相应地改变了:

Frame 78: 680 bytes on wire (5440 bits), 680 bytes captured (5440 bits) on interface \Device\NPF_{28393799-9889-4CF5-B65C-ED851CC47ECC}, id 0
Ethernet II, Src: ASUSTekC_<MAC>, Dst: D-Link_<MAC>
Internet Protocol Version 4, Src: 192.168.1.3, Dst: <IP>
Transmission Control Protocol, Src Port: 58619, Dst Port: 80, Seq: 4, Ack: 1, Len: 626
[2 Reassembled TCP Segments (629 bytes): #76(3), #78(626)]
Hypertext Transfer Protocol
    GET /api/apitest&code=1 HTTP/1.1\r\n
    User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:85.0) Gecko/20100101 Firefox/85.0\r\n
    Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8\r\n
    Accept-Language: ru-RU,ru;q=0.8,en-US;q=0.5,en;q=0.3\r\n
    Accept-Encoding: gzip, deflate, br\r\n
    Connection: keep-alive\r\n
    Cookie: <cookie>\r\n
    Host: myhostname.com\r\n
    Upgrade-Insecure-Requests: 1\r\n
    Cache-Control: max-age=0\r\n
    \r\n
    [Full request URI: http://myhostname.com/api/apitest&code=1]
    [HTTP request 1/1]
    [Response in frame: 80]
第78帧:线路上680字节(5440位),接口\Device\NPF{28393799-9889-4CF5-B65C-ED851CC47ECC}上捕获680字节(5440位),id 0
Ethernet II,Src:ASUSTekC,Dst:D-Link_
互联网协议版本4,Src:192.168.1.3,Dst:
传输控制协议,Src端口:58619,Dst端口:80,序列:4,应答:1,长度:626
[2重新组装的TCP段(629字节):#76(3),#78(626)]
超文本传输协议
GET/api/apitest&code=1 HTTP/1.1\r\n
用户代理:Mozilla/5.0(Windows NT 10.0;Win64;x64;rv:85.0)Gecko/20100101 Firefox/85.0\r\n
接受:text/html、application/xhtml+xml、application/xml;q=0.9,图像/webp,*/*;q=0.8\r\n
接受语言:如如如,如;q=0.8,在美国;q=0.5,en;q=0.3\r\n
接受编码:gzip,deflate,br\r\n
连接:保持活动状态\r\n
Cookie:\r\n
主机:myhostname.com\r\n
升级不安全的请求:1\r\n
缓存控制:最大年龄=0\r\n
\r\n
[完整请求URI:http://myhostname.com/api/apitest&code=1]
[HTTP请求1/1]
[帧中的响应:80]

为什么会出现这样的问题?请查看第32页的“接收具有不同字段名的标题字段的顺序不重要”,因此标题的顺序不应与接收者相关。“我需要请求具有特定的标题顺序”:不,您不需要。你怎么会不这么想?Java没有提供这样做的方法,而且基于JavaServlet技术的服务器无论如何都看不到标题顺序。任何其他HTTP服务器也不应该在意。我理解,通常情况下,头的顺序并不重要。但在我的例子中,我访问的API只是在标题顺序改变时返回错误。例如,在接受语言之前移动接受编码会使服务器返回“403禁止”错误。那么问题就出在服务器上,这就是您需要解决的地方。它不符合RFC 2616和后续版本。您无法在Java客户端解决这个问题。假设你诊断正确,这似乎不太可能。你有任何证据表明你用这种技术控制了导线上的头的顺序吗?我应该证明一下吗?使用Wireshark和order嗅探的数据包与源代码中的相同。已更改源中的顺序,并在捕获的数据包中看到相同的顺序。已更新我的答案以显示捕获的数据包