Irregular Http 204 response triggers Apache's Http protocol parsing failure

Found an error log in Server today:

 

wrote
ParseException#Not a valid protocol version: ""HTTP/1.1 201 Created#org.apache.http.ParseException: Not a valid protocol version: ""HTTP/1.1 201 Created
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:

 

wrote
GET /check 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 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

...
 
Everyone pay attention to the response I marked in red. It returns 204, but it indicates Content-Length: 2. This response does not conform to the definition of the HTTP protocol:
https://tools.ietf.org/html/rfc7230#section-3.3.1

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.

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=326904017&siteId=291194637