2015-10-19 140 views
0

我已经构建了一个使用Java套接字传递http请求和响应的Android代理服务器。编码的Http请求/响应主体

代理正在工作,浏览器中的所有内容都通过它。不过,我将能够读取请求/响应,但他们的身体似乎要被编码:

GET http://m.onet.pl/ HTTP/1.1 
Host: m.onet.pl 
Proxy-Connection: keep-alive 
Cache-Control: max-age=0 
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8 
Upgrade-Insecure-Requests: 1 
User-Agent: Mozilla/5.0 (Linux; Android 4.4.4; XT1039 Build/KXB21.14-L1.56) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.76 Mobile Safari/537.36 
DNT: 1 
Accept-Encoding: gzip, deflate, sdch 
Accept-Language: en-GB,en;q=0.8,en-US;q=0.6,pl;q=0.4 
Cookie: onet_ubi=201509221839473724130028; onetzuo_ticket=9AEDF08D278EC7965FF6A20BABD36EF0010012ED90FDD127C16068426F8B65A5D81A000000000000000050521881000000; onet_cid=dd6df83b3a8c33cd497d1ec3fcdea91b; __gfp_64b=2Mp2U1jvfJ3L9f.y6CbKfJ0oVfA7pVdBYfT58G1nf7T.p7; ea_uuid=201509221839478728300022; onet_cinf=1; __utma=86187972.1288403231.1442939988.1444999380.1445243557.40; __utmb=86187972.13.10.1445243557; __utmc=86187972; __utmz=86187972.1442939988.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none) 

����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� 

所以无论是在请求和响应大量的“”发生。我没有找到任何有关http编码的信息。它是什么 ?我该如何正确阅读身体?


假设它可能GZIPed消息我想:

while ((count = externalServerInputReader.read(buf, 0, buf.length)) != -1) 
{ 
    String stream = new String(buf, 0 , count); 
    proxyOutputStream.write(buf, 0, count); 

    if (stream.contains("content-encoding: gzip")) { 
     ByteArrayInputStream bais = new ByteArrayInputStream(buf); 
     GZIPInputStream gzis = new GZIPInputStream(bais); 
     InputStreamReader reader = new InputStreamReader(gzis); 
     BufferedReader in = new BufferedReader(reader); 

     String readed; 
     while ((readed = in.readLine()) != null) { 
      Log.d("Hello", "UnGzip: " + readed); 
     } 
    } 
} 
proxyOutputStream.flush(); 

但是我得到ungzipping尝试错误。

未知格式(幻数5448)

回答

2

我通过保存到 “/ tmp目录/ REQ”,用cat /tmp/req | nc m.onet.pl 80重放它想你的样品要求。服务器发送回gzip编码响应,我可以从响应头文件content-encoding: gzip中知道。在响应是gzip编码的情况下,您可以使用java.util.zip.GZIPInputStream在Java中对其进行解压缩。请注意,您的示例中的用户代理也是对“deflate”和“sdch”的广告支持,因此您可能也会收到这些编码的回复。 “deflate”编码可以使用java.util.zip.InflaterInputStream进行解压缩。我不知道有任何内置的对sdch的支持,因此您需要查找或编写一个库来解压缩 - 请参阅此其他堆栈溢出问题,以了解可能的起点:“Java SDCH compressor/decompressor”。

要解决您在使用GZIPInputStream时添加刺的问题的更新部分,最直接的问题是您应该只在HTTP响应头结束后对流进行gunzip处理。最简单的做法是等待“\ r \ n \ r \ n”来通过底层InputStream(而不是Reader),然后通过单个GZIPInputStream运行开始于下一个字节的数据。这应该可能适用于您给出的示例 - 我成功解码了使用gunzip -c获得的重播响应。为了彻底,还有一些其他问题可以避免它成为任意网站的一般解决方案,但我认为这足以帮助您入门。 (一些例子:1)你可能会错过一个“内容编码”头,因为你将响应分成长度为buf.length的块。 2)使用分块编码的响应需要被分块。 3)保持活跃的响应将需要跟踪响应何时结束而不是等待流结束。)

+0

(quiestion updated)我尝试了ungzipp,但它似乎并不是一个。那可能是那些其他的编码吗?我怎么知道它是哪一个? –

+0

你需要gunzip只是响应。您将当前代码中的标题包括在内,以便进行枪击。尝试跳过第一遍“\ r \ n \ r \ n”或“\ n \ n”进行第一遍实施。这不足以处理分块编码,但它可能足以让你开始。 – twm