2016-09-07 146 views
0

如何使用InputStream读取HTTP请求?我用这样来阅读:如何正确读取http请求?

InputStream in = address.openStream(); 
BufferedReader reader = new BufferedReader(new InputStreamReader(in)); 
StringBuilder result = new StringBuilder(); 
String line; 
while((line = reader.readLine()) != null) { 
    result.append(line); 
} 
System.out.println(result.toString()); 

reader.readLine()可能被阻止,因为没有保证null线将到达。当然,我可以读Content-Length头,然后在一个循环中读取请求:

for (int i = 0; i < contentLength; i++) { 
       int a = br.read(); 
       body.append((char) a); 
    } 

但如果内容长度设置得过大(我想这可以手动设置目的),br.read()将被阻止。 我尝试从InputStream中像这样直接读取的字节:

byte[] bytes = getBytes(is); 

public static byte[] getBytes(InputStream is) throws IOException { 

      int len; 
      int size = 1024; 
      byte[] buf; 

      if (is instanceof ByteArrayInputStream) { 
       size = is.available(); 
       buf = new byte[size]; 
       len = is.read(buf, 0, size); 
      } else { 
       ByteArrayOutputStream bos = new ByteArrayOutputStream(); 
       buf = new byte[size]; 
       while ((len = is.read(buf, 0, size)) != -1) 
       bos.write(buf, 0, len); 
       buf = bos.toByteArray(); 
      } 
      return buf; 
      } 

但它永远等待。做什么?

+0

为什么不能保证能够达到'null'行?根据文档,如果已经到达流的末尾,它将返回'null'。所以如果连接被关闭,你会在读完最后一行后得到空值。 –

+0

我可以达到的第一个空行是头和请求体之间的分隔符(如表单数据)。但身体后面没有空线。做什么? – Tony

+0

也许你得到一个空的身体请求? –

回答

2

如果你正在实现HTTP服务器,你应该根据HTTP规范检测请求的结束。 Wiki - https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol

首先,您应该阅读请求行,它始终是单行。 然后阅读所有请求标题。你阅读它们,直到你有一个空行(即两行结尾 - <CR><LF>)。

之后,你有一个状态栏和标题,你应该决定你需要阅读的身体或没有,因为不是所有的请求可能有身体 - summary table

然后,如果你需要一个身体,你应该分析你的头(你已经得到)并获得Content-Length。如果是 - 只要从指定的流中读取尽可能多的字节。 当内容长度缺失时,长度以其他方式确定。分块传输编码使用块大小为0来标记内容的结尾。无内容长度的身份编码将读取内容,直到套接字关闭。

-1

创建一个扩展HttpServletRequestWrapper的请求包装器,它将覆盖getInputStream(),该getInputStream()返回ServletInputStream,该ServletInputStream具有安全读取方法。试试

+0

它与servlet无关。 – Tony