[英]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.