If httpd is configured to do "block return" with a 1xx or 204 status, it
sends a response with a Content-Length header and a body, which per RFC
7230 it must not.

The use case for this is a webapp which wants the webserver itself to be
configured to return a 204 response for certain requests. I'm running
httpd behind relayd, and relayd doesn't accept the 204 responses httpd
returns.

Here's a possible patch.


--
Carlin


Index: usr.sbin/httpd/server_http.c
===================================================================
RCS file: /cvs/src/usr.sbin/httpd/server_http.c,v
retrieving revision 1.122
diff -u -p -u -r1.122 server_http.c
--- usr.sbin/httpd/server_http.c        20 Jun 2018 16:43:05 -0000      1.122
+++ usr.sbin/httpd/server_http.c        5 Sep 2018 16:37:35 -0000
@@ -846,6 +846,7 @@ server_abort_http(struct client *clt, un
        const char              *httperr = NULL, *style;
        char                    *httpmsg, *body = NULL, *extraheader = NULL;
        char                     tmbuf[32], hbuf[128], *hstsheader = NULL;
+       char                    *clenheader = NULL;
        char                     buf[IBUF_READ_SIZE];
        char                    *escapedmsg = NULL;
        int                      bodylen;
@@ -961,6 +962,16 @@ server_abort_http(struct client *clt, un
                }
        }
 
+       if ((code >= 100 && code < 200) || code == 204)
+               clenheader = NULL;
+       else {
+               if (asprintf(&clenheader,
+                   "Content-Length: %d\r\n", bodylen) == -1) {
+                       clenheader = NULL;
+                       goto done;
+               }
+       }
+
        /* Add basic HTTP headers */
        if (asprintf(&httpmsg,
            "HTTP/1.0 %03d %s\r\n"
@@ -968,15 +979,17 @@ server_abort_http(struct client *clt, un
            "Server: %s\r\n"
            "Connection: close\r\n"
            "Content-Type: text/html\r\n"
-           "Content-Length: %d\r\n"
+           "%s"
            "%s"
            "%s"
            "\r\n"
            "%s",
-           code, httperr, tmbuf, HTTPD_SERVERNAME, bodylen,
+           code, httperr, tmbuf, HTTPD_SERVERNAME,
+           clenheader == NULL ? "" : clenheader,
            extraheader == NULL ? "" : extraheader,
            hstsheader == NULL ? "" : hstsheader,
-           desc->http_method == HTTP_METHOD_HEAD ? "" : body) == -1)
+           desc->http_method == HTTP_METHOD_HEAD || clenheader == NULL ?
+           "" : body) == -1)
                goto done;
 
        /* Dump the message without checking for success */
@@ -987,6 +1000,7 @@ server_abort_http(struct client *clt, un
        free(body);
        free(extraheader);
        free(hstsheader);
+       free(clenheader);
        if (msg == NULL)
                msg = "\"\"";
        if (asprintf(&httpmsg, "%s (%03d %s)", msg, code, httperr) == -1) {

Reply via email to