Fix works for me, too. Thanks.
It now sets the "Content-Length: 0" header for ALL traffic that
is not chunk-encoded. But chunk-encoding may be disabled already
(e.g. for http/1.0). I'd therefore suggest to move the fix to where
the handling of zero-length bodies actually takes place.
--- usr.sbin/httpd/server_fcgi.c Thu May 20 05:57:23 2021
+++ usr.sbin/httpd/server_fcgi.c Thu May 20 06:03:40 2021
@@ -620,6 +620,12 @@
EVBUFFER_LENGTH(clt->clt_srvevb) == 0) {
/* Can't chunk encode an empty body. */
clt->clt_fcgi.chunked = 0;
+ 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);
+ }
}
/* Set chunked encoding */
@@ -636,13 +642,6 @@
if (kv_add(&resp->http_headers,
"Transfer-Encoding", "chunked") == NULL)
return (-1);
- } else {
- 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);
- }
}
/* Is it a persistent connection? */
On 2021-05-19 20:44, Florian Obser wrote:
> The whole point of using Transfer-Encoding: chunked for fastcgi was so
> that we do not need to provide a Content-Length header if upstream
> doesn't give us one. (We'd need to slurp in all the data ugh).
>
> Now turns out that if we disable chunked encoding for zero sized bodies
> some browsers are picky and want a Content-Length: 0 (Firefox, Safari)
> or they'll just sit there and wait for the connection to close.
>
> Problem reported by Matthias Pressfreund with wordpress.
> Debugged with the help of weerd@ who pointed out that the problem is
> actually browser dependent. From there it was pretty clear what the
> problem was.
>
> OK?
>
> diff --git server_fcgi.c server_fcgi.c
> index 31d7322e9f7..b9dc4f6fe04 100644
> --- server_fcgi.c
> +++ server_fcgi.c
> @@ -636,6 +636,13 @@ server_fcgi_header(struct client *clt, unsigned int code)
> if (kv_add(&resp->http_headers,
> "Transfer-Encoding", "chunked") == NULL)
> return (-1);
> + } else {
> + 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);
> + }
> }
>
> /* Is it a persistent connection? */
>