我需要请求有一个特定的标题顺序。因此,我按照所需的顺序为每个属性调用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.1rn
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:85.0) Gecko/20100101 Firefox/85.0rn
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8rn
Accept-Language: ru-RU,ru;q=0.8,en-US;q=0.5,en;q=0.3rn
Accept-Encoding: gzip, deflate, brrn
Cookie: <cookie>rn
Upgrade-Insecure-Requests: 1rn
Cache-Control: max-age=0rn
Host: myhostname.comrn
Connection: keep-alivern
是否有办法保持标题顺序不变?
所以我用RawHttp:
解决了这个问题RawHttp http = new RawHttp();
RawHttpRequest httpRequest = http.parseRequest("GET /api/apitest&code="+code+" HTTP/1.1rn" +
"Host:myhostname.comrn" +
"User-Agent:Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:85.0) Gecko/20100101 Firefox/85.0rn" +
"Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8rn" +
"Accept-Language:ru-RU,ru;q=0.8,en-US;q=0.5,en;q=0.3rn" +
"Accept-Encoding:gzip, deflate, brrn" +
"Connection:keep-alivern" +
"Cookie:" + cookies + "rn" +
"Upgrade-Insecure-Requests:1rn" +
"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);
可以用
检查Body是否存在httpResponse.getBody().isPresent()
现在报头顺序不变,这个非rfc兼容的服务器正确回答。
为了显示结果,我将port更改为80,但其他一切都是一样的:
Frame 6099: 680 bytes on wire (5440 bits), 680 bytes captured (5440 bits) on interface DeviceNPF_{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.1rn
Host: myhostname.comrn
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:85.0) Gecko/20100101 Firefox/85.0rn
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8rn
Accept-Language: ru-RU,ru;q=0.8,en-US;q=0.5,en;q=0.3rn
Accept-Encoding: gzip, deflate, brrn
Connection: keep-alivern
Cookie: <cookie>rn
Upgrade-Insecure-Requests: 1rn
Cache-Control: max-age=0rn
rn
[Full request URI: http://myhostname.com/api/apitest&code=1]
[HTTP request 1/1]
[Response in frame: 6101]
然后我移动主机头,捕获的数据包相应地改变:
Frame 78: 680 bytes on wire (5440 bits), 680 bytes captured (5440 bits) on interface DeviceNPF_{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.1rn
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:85.0) Gecko/20100101 Firefox/85.0rn
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8rn
Accept-Language: ru-RU,ru;q=0.8,en-US;q=0.5,en;q=0.3rn
Accept-Encoding: gzip, deflate, brrn
Connection: keep-alivern
Cookie: <cookie>rn
Host: myhostname.comrn
Upgrade-Insecure-Requests: 1rn
Cache-Control: max-age=0rn
rn
[Full request URI: http://myhostname.com/api/apitest&code=1]
[HTTP request 1/1]
[Response in frame: 80]