簡體   English   中英

如何正確閱讀http請求?

[英]How to read http request properly?

如何使用InputStream讀取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);
    }

但是,如果Content-Length設置得太大(我想可以出於目的手動設置),則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;
          }

但是,它永遠等待着。 做什么?

如果要實現HTTP服務器,則應根據HTTP規范檢測請求的結束。 Wiki- https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol

首先,您應該閱讀一條請求行,它始終是一行。 然后讀取所有請求標頭。 您閱讀它們直到您有一個空行(即兩個行尾- <CR><LF> )。

在擁有狀態行和標頭之后,您應該決定是否需要閱讀正文,因為並非所有請求都可能具有正文- 摘要表

然后,如果需要主體,則應解析標頭(已獲取)並獲取Content-Length。 如果是,則從流中讀取指定數量的字節。 如果缺少Content-Length,則以其他方式確定長度。 分塊傳輸編碼使用塊大小0標記內容的結尾。 沒有Content-Length的身份編碼將讀取內容,直到關閉套接字為止。

創建一個擴展HttpServletRequestWrapper的請求包裝器,該包裝器將覆蓋getInputStream(),而后者又返回具有安全讀取方法的ServletInputStream。 試試看

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM