您显示的代码不是读取HTTP请求的正确方法。
首先,Java有它自己
HttpServer和
HttpsServer类。您应该考虑使用它们。
否则,您必须手动实现HTTP协议。您需要逐行读取输入,直到到达指示请求标头末尾的空行,然后查看已读取的标头,尤其是
Transfer-Encoding和
Content-Length标头,以了解如何读取标头的其余字节。根据RFC
2616第4.4节的要求:
4.4消息长度
消息的传输长度是显示在消息中的消息正文的长度。也就是说,在应用了任何传输编码之后。当消息主体包含在消息中时,该主体的传输长度由以下一项确定(按优先顺序):
1.
任何“不得”包含消息正文的响应消息(例如1xx,204和304响应以及对HEAD请求的任何响应)总是由标头字段后的第一个空行终止,而不考虑实体-
邮件中的标头字段。
如果存在Transfer-Encoding头字段(第14.41节),并且具有除“
identity”以外的任何值,则除非使用了消息终止,否则将使用“块式”传输编码(第3.6节)定义传输长度。通过关闭连接。如果存在Content-
Length标头字段(第14.13节),则其在OCTET中的十进制值表示实体长度和传输长度。如果这两个长度不同(即,如果存在传输编码头字段),则不得发送Content-
Length头字段。如果接收到的消息同时具有Transfer-Encoding头域和Content-Length头域,则后者必须被忽略。如果消息使用媒体类型“ multipart / byteranges”,并且未另外指定ransfer-
length,则此自限制媒体类型将定义传输长度。除非发件人知道收件人可以对此媒体类型使用,否则请勿使用此媒体类型。来自1.1客户端的带有多个字节范围说明符的Range标头在请求中的存在意味着留置权可以解析multipart
/ byteranges响应。范围标头可能由不了解多部分/字节范围的1.0代理转发。在这种情况下,服务器必须使用本节第1,3或5条中定义的方法对消息进行定界。
- 通过服务器关闭连接。(关闭连接不能用于指示请求主体的结束,因为这将使服务器无法发送回响应。)
为了与HTTP / 1.0应用程序兼容,除非已知服务器兼容HTTP / 1.1,否则包含消息主体的HTTP / 1.1请求必须包含有效的Content-
Length头字段。如果一个请求包含一个消息主体,并且没有给出Content-
Length,则服务器如果不能确定消息的长度,则应该以400(错误请求)响应,或者如果希望坚持则以411(要求长度)响应。收到有效的Content-
Length。接收实体的所有HTTP / 1.1应用程序必须接受“块式”传输编码(第3.6节),因此,当无法预先确定消息长度时,允许将该机制用于消息。
消息不得同时包含Content-Length头字段和非身份转移编码。如果消息中确实包含非身份转移编码,则必须忽略Content-Length。
在允许消息正文的消息中给出Content-Length时,其字段值务必与消息正文中的OCTET数量完全匹配。当收到并检测到无效长度时,HTTP /
1.1用户代理务必通知用户。
尝试类似以下内容(半伪代码):
String readLine(BufferedInputStream in){ // HTTP carries both textual and binary elements. // Not using BufferedReader.readLine() so it does // not "steal" bytes from BufferedInputStream... // HTTP itself only allows 7bit ASCII characters // in headers, but some header values may be // further enpred using RFC 2231 or 5987 to // carry Unipre characters ... InputStreamReader r = new InputStreamReader(in, StandardCharsets.US_ASCII); StringBuilder sb = new StringBuilder(); char c; while ((c = r.read()) >= 0) { if (c == 'n') break; if (c == 'r') { c = r.read(); if ((c < 0) || (c == 'n')) break; sb.append('r'); } sb.append(c); } return sb.toString();}...BufferedInputStream in = new BufferedInputStream(clientSocket.getInputStream());String request = readLine(in);// extract method, resource, and version...String line;do{ line = readLine(in); if (line.isEmpty()) break; // store line in headers list...}while (true);// parse headers list...if (request method has a message-body) // POST, etc{ if ((request version >= 1.1) && (Transfer-Encoding header is present) && (Transfer-Encoding != "identity")) { // read chunks... do { line = readLine(in); // read chunk header int size = extract value from line; if (size == 0) break; // use in.read() to read the specified // number of bytes into message-body... readLine(in); // skip trailing line break } while (true); // read trailing headers... line = readLine(in); while (!line.isEmpty()) { // store line in headers list, updating // any existing header as needed... } // parse headers list again ... } else if (Content-Length header is present) { // use in.read() to read the specified // number of bytes into message-body... } else if (Content-Type is "multipart/...") { // use readLine(in) and in.read() as needed // to read/parse/depre MIME enpred data into // message-body until terminating MIME boundary // is reached... } else { // fail the request... }}// process request and message-body as needed..


