diff --git a/modules/caddyhttp/reverseproxy/fastcgi/client.go b/modules/caddyhttp/reverseproxy/fastcgi/client.go index 7284fe67285..b8bfde7c94c 100644 --- a/modules/caddyhttp/reverseproxy/fastcgi/client.go +++ b/modules/caddyhttp/reverseproxy/fastcgi/client.go @@ -41,6 +41,8 @@ import ( "go.uber.org/zap" "go.uber.org/zap/zapcore" + + "github.com/caddyserver/caddy/v2/modules/caddyhttp" ) // FCGIListenSockFileno describes listen socket file number. @@ -136,6 +138,18 @@ type client struct { // Do made the request and returns a io.Reader that translates the data read // from fcgi responder out of fcgi packet before returning it. func (c *client) Do(p map[string]string, req io.Reader) (r io.Reader, err error) { + // check for CONTENT_LENGTH, since the lack of it or wrong value will cause the backend to hang + if clStr, ok := p["CONTENT_LENGTH"]; !ok { + return nil, caddyhttp.Error(http.StatusLengthRequired, nil) + } else { + cl, err := strconv.ParseInt(clStr, 10, 64) + // stdlib won't return a negative Content-Length, but we check just in case, + // the most likely cause is from a missing content length, which is -1 + if err != nil || cl < 0 { + return nil, caddyhttp.Error(http.StatusLengthRequired, err) + } + } + writer := &streamWriter{c: c} writer.buf = bufPool.Get().(*bytes.Buffer) writer.buf.Reset()