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) {