This is a rewording of my later posts to bugs@ in: https://marc.info/?t=163309376900001&r=1&w=2 ====
RFC 7231 [HTTP 1.1] states that, for a HEAD request, the server SHOULD send the same header fields in response to HEAD as it would for GET, except that payload headers MAY be omitted. Content-Length is such a header field. The CGI on beta.undeadly.org has been updated (to be RFC-compliant) such that it does not send a body in response to HEAD requests. We now how: #### www.undeadly.org ########## $ printf "HEAD /cgi?action=front HTTP/1.0\r\nHost: www.undeadly.org\r\n\r\n" \ | nc -c www.undeadly.org https \ | head HTTP/1.0 200 OK Connection: close Content-Type: text/html Date: Wed, 06 Oct 2021 10:24:59 GMT Server: OpenBSD httpd Strict-Transport-Security: max-age=31536000; preload <!DOCTYPE html> <html lang="en"> <head> #### beta.undeadly.org ######### $ printf "HEAD /cgi?action=front HTTP/1.0\r\nHost: beta.undeadly.org\r\n\r\n" \ | nc -c beta.undeadly.org https HTTP/1.0 200 OK Connection: close Content-Length: 0 Content-Type: text/html Date: Wed, 06 Oct 2021 10:25:01 GMT Server: OpenBSD httpd Strict-Transport-Security: max-age=31536000; preload So, if the CGI treats HEAD the same way as GET [and returns a body], httpd does not add a Content-Length header. However, if the CGI behaves correctly, and does not include the body in the response, httpd _does_ add a Content-Type header. That's clearly wrong/unhelpful. I'm insufficiently familiar with the httpd code to be certain that the patch below is correct, but it fixes the problem in light testing. Ross ---- Index: server_fcgi.c =================================================================== RCS file: /cvs/src/usr.sbin/httpd/server_fcgi.c,v retrieving revision 1.88 diff -u -p -r1.88 server_fcgi.c --- server_fcgi.c 20 May 2021 15:12:10 -0000 1.88 +++ server_fcgi.c 7 Oct 2021 02:56:07 -0000 @@ -621,12 +621,14 @@ server_fcgi_header(struct client *clt, u /* Can't chunk encode an empty body. */ clt->clt_fcgi.chunked = 0; - /* But then we need a Content-Length... */ - key.kv_key = "Content-Length"; - if ((kv = kv_find(&resp->http_headers, &key)) == NULL) { - if (kv_add(&resp->http_headers, - "Content-Length", "0") == NULL) - return (-1); + /* But then we need a Content-Length unless method is HEAD... */ + if (desc->http_method != HTTP_METHOD_HEAD) { + key.kv_key = "Content-Length"; + if ((kv = kv_find(&resp->http_headers, &key)) == NULL) { + if (kv_add(&resp->http_headers, + "Content-Length", "0") == NULL) + return (-1); + } } }