Hi,

relayd enforces a rule in rfc section 3.3.2:

rfc 7230 3.3 Message Body

   All 1xx (Informational), 204 (No Content), and 304 (Not Modified)
   responses do not include a message body.  All other responses do
   include a message body, although the body might be of zero length.

rfc 7230 3.3.2.  Content-Length

   A server MUST NOT send a Content-Length header field in any response
   with a status code of 1xx (Informational) or 204 (No Content).  A
   server MUST NOT send a Content-Length header field in any 2xx
   (Successful) response to a CONNECT request (Section 4.3.6 of
   [RFC7231]).


There is also this paragraph in Section 3.3.3 thats relevant:


   4.  If a message is received without Transfer-Encoding and with
       either multiple Content-Length header fields having differing
       field-values or a single Content-Length header field having an
       invalid value, then the message framing is invalid and the
       recipient MUST treat it as an unrecoverable error.  If this is a
       request message, the server MUST respond with a 400 (Bad Request)
       status code and then close the connection.  If this is a response
       message received by a proxy, the proxy MUST close the connection
       to the server, discard the received response, and send a 502 (Bad
       Gateway) response to the client.  If this is a response message
       received by a user agent, the user agent MUST close the
       connection to the server and discard the received response.


There are two problems with this:

* I have found a Tomcat Server that sends "204 No Content" with a
  "Content-Length: 0" Header.

* Relayd sends the wrong HTTP Status Code, it should be 502 Bad Gateway

Here is a diff that relaxes the logic: send a 502 Bad Gateway, but
only if Content-Length != 0.

ok?

diff --git usr.sbin/relayd/relay_http.c usr.sbin/relayd/relay_http.c
index 3b6f8e84e37..ad45cf2d5d6 100644
--- usr.sbin/relayd/relay_http.c
+++ usr.sbin/relayd/relay_http.c
@@ -324,19 +324,6 @@ relay_read_http(struct bufferevent *bev, void *arg)
                                relay_abort_http(con, 400, "malformed", 0);
                                goto abort;
                        }
-                       /*
-                        * response with a status code of 1xx
-                        * (Informational) or 204 (No Content) MUST
-                        * not have a Content-Length (rfc 7230 3.3.3)
-                        */
-                       if (desc->http_method == HTTP_METHOD_RESPONSE && (
-                           ((desc->http_status >= 100 &&
-                           desc->http_status < 200) ||
-                           desc->http_status == 204))) {
-                               relay_abort_http(con, 500,
-                                   "Internal Server Error", 0);
-                               goto abort;
-                       }
                        /*
                         * Need to read data from the client after the
                         * HTTP header.
@@ -349,6 +336,23 @@ relay_read_http(struct bufferevent *bev, void *arg)
                                relay_abort_http(con, 500, errstr, 0);
                                goto abort;
                        }
+                       /*
+                        * response with a status code of 1xx
+                        * (Informational) or 204 (No Content) MUST
+                        * not have a Content-Length (rfc 7230 3.3.3)
+                        * Instead we check for value != 0 because there are
+                        * servers that do not follow the rfc and send
+                        * Content-Length: 0.
+                        */
+                       if (desc->http_method == HTTP_METHOD_RESPONSE && (
+                           ((desc->http_status >= 100 &&
+                           desc->http_status < 200) ||
+                           desc->http_status == 204)) &&
+                           cre->toread != 0) {
+                               relay_abort_http(con, 502,
+                                   "Bad Gateway", 0);
+                               goto abort;
+                       }
                }
  lookup:
                if (strcasecmp("Transfer-Encoding", key) == 0 &&

Reply via email to