Skip to content

Commit 6f7522f

Browse files
WeidiDengmholt
authored andcommitted
reverseproxy: buffer requests for fastcgi by default (caddyserver#6759)
* buffer requests for fastcgi by default * fix import cycle * fix the return value of bufferedBody * more comments about fastcgi buffering --------- Co-authored-by: Matt Holt <mholt@users.noreply.github.com>
1 parent 6d42dd4 commit 6f7522f

1 file changed

Lines changed: 17 additions & 3 deletions

File tree

modules/caddyhttp/reverseproxy/reverseproxy.go

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,19 @@ func (h *Handler) Provision(ctx caddy.Context) error {
244244
return fmt.Errorf("loading transport: %v", err)
245245
}
246246
h.Transport = mod.(http.RoundTripper)
247+
// enable request buffering for fastcgi if not configured
248+
// This is because most fastcgi servers are php-fpm that require the content length to be set to read the body, golang
249+
// std has fastcgi implementation that doesn't need this value to process the body, but we can safely assume that's
250+
// not used.
251+
// http3 requests have a negative content length for GET and HEAD requests, if that header is not sent.
252+
// see: https://github.com/caddyserver/caddy/issues/6678#issuecomment-2472224182
253+
// Though it appears even if CONTENT_LENGTH is invalid, php-fpm can handle just fine if the body is empty (no Stdin records sent).
254+
// php-fpm will hang if there is any data in the body though, https://github.com/caddyserver/caddy/issues/5420#issuecomment-2415943516
255+
256+
// TODO: better default buffering for fastcgi requests without content length, in theory a value of 1 should be enough, make it bigger anyway
257+
if module, ok := h.Transport.(caddy.Module); ok && module.CaddyModule().ID.Name() == "fastcgi" && h.RequestBuffers == 0 {
258+
h.RequestBuffers = 4096
259+
}
247260
}
248261
if h.LoadBalancing != nil && h.LoadBalancing.SelectionPolicyRaw != nil {
249262
mod, err := ctx.LoadModule(h.LoadBalancing, "SelectionPolicyRaw")
@@ -1218,13 +1231,14 @@ func (h Handler) bufferedBody(originalBody io.ReadCloser, limit int64) (io.ReadC
12181231
buf := bufPool.Get().(*bytes.Buffer)
12191232
buf.Reset()
12201233
if limit > 0 {
1221-
n, err := io.CopyN(buf, originalBody, limit)
1222-
if (err != nil && err != io.EOF) || n == limit {
1234+
var err error
1235+
written, err = io.CopyN(buf, originalBody, limit)
1236+
if (err != nil && err != io.EOF) || written == limit {
12231237
return bodyReadCloser{
12241238
Reader: io.MultiReader(buf, originalBody),
12251239
buf: buf,
12261240
body: originalBody,
1227-
}, n
1241+
}, written
12281242
}
12291243
} else {
12301244
written, _ = io.Copy(buf, originalBody)

0 commit comments

Comments
 (0)