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 &&