Found an error log in Server today:
org.apache.http.message.BasicLineParser.parseProtocolVersion(BasicLineParser.java:147)
org.apache.http.message.BasicLineParser.parseStatusLine(BasicLineParser.java:365)
org.apache.http.impl.nio.codecs.DefaultHttpResponseParser.createMessage(DefaultHttpResponseParser.java:114)
org.apache.http.impl.nio.codecs.DefaultHttpResponseParser.createMessage(DefaultHttpResponseParser.java:51)
Find the corresponding code:
public ProtocolVersion parseProtocolVersion(final CharArrayBuffer buffer, final ParserCursor cursor) throws ParseException { Args.notNull(buffer, "Char array buffer"); Args.notNull(cursor, "Parser cursor"); final String protoname = this.protocol.getProtocol(); final int protolength = protoname.length(); final int indexFrom = cursor.getPos(); final int indexTo = cursor.getUpperBound (); skipWhitespace(buffer, cursor); int i = cursor.getPos(); // long enough for "HTTP/1.1"? if (i + protolength + 4 > indexTo) { throw new ParseException ("Not a valid protocol version: " + buffer.substring(indexFrom, indexTo)); } // check the protocol name and slash boolean ok = true; for (int j=0; ok && (j<protolength); j++) { ok = (buffer.charAt(i+j) == protoname.charAt(j)); } if (ok) { ok = (buffer.charAt(i+protolength) == '/'); } if (!ok) { throw new ParseException ("Not a valid protocol version: " + buffer.substring(indexFrom, indexTo)); }
It means that the protocol stack reads ""HTTP/1.1 201 Created when reading buffer.substring(indexFrom, indexTo), with two double quotation marks in front. The packet capture found that this situation occurs on the same long connection:
Host: abc.com
Connection: keep-alive
Cache-Control: max-age=0
Accept-Encoding: gzip, deflate, sdch
Accept-Language: zh-CN,zh;q=0.8,en;q=0.6
HTTP/1.1 204 OK
Date: Sat, 12 Nov 2016 04:41:29 GMT
Content-Length: 2
"" Get /creat HTTP/1.1
Host: abc.com
Connection: keep-alive
Cache-Control: max-age=0
Accept-Encoding: gzip, deflate, sdch
Accept-Language: zh-CN,zh;q=0.8,en;q=0.6
HTTP/1.1 201 Created
Date: Sat, 12 Nov 2016 04:41:29 GMT
Content-Length: 2
...
3.3.3. Message Body Length
The length of a message body is determined by one of the following (in order of precedence): 1. Any response to a HEAD request and any response with a 1xx (Informational), 204 (No Content), or 304 (Not Modified) status code is always terminated by the first empty line after the header fields, regardless of the header fields present in the message, and thus cannot contain a message body.
identify the problem:
Among the two responses returned on a long connection, the response code returned by the first response is 204, but two quotation marks are included in the body, which violates the HTTP1.1 specification, resulting in Apache that complies with the specification. The thread that took the first response did not read the last two quotation marks from the stream, and when reading the second response, it found that the first two bytes were two double quotation marks, not HTTP/1.1, and an exception was thrown directly.
In conclusion, the response of 204 must comply with the specification, and data cannot be written in the body, otherwise it will pollute the data in the stream and affect the reading of the next data packet on the long connection.