diff --git a/caddy.go b/caddy.go index b3e8889fa..758b0b2f6 100644 --- a/caddy.go +++ b/caddy.go @@ -725,8 +725,10 @@ func Validate(cfg *Config) error { // Errors are logged along the way, and an appropriate exit // code is emitted. func exitProcess(ctx context.Context, logger *zap.Logger) { - // let the rest of the program know we're quitting - atomic.StoreInt32(exiting, 1) + // let the rest of the program know we're quitting; only do it once + if !atomic.CompareAndSwapInt32(exiting, 0, 1) { + return + } // give the OS or service/process manager our 2 weeks' notice: we quit if err := notify.Stopping(); err != nil { diff --git a/caddyconfig/httpcaddyfile/tlsapp.go b/caddyconfig/httpcaddyfile/tlsapp.go index 09a862e76..71b524926 100644 --- a/caddyconfig/httpcaddyfile/tlsapp.go +++ b/caddyconfig/httpcaddyfile/tlsapp.go @@ -423,6 +423,7 @@ func (st ServerType) buildTLSApp( } al = append(al, name) } + slices.Sort(al) // to stabilize the adapt output if len(al) > 0 { tlsApp.CertificatesRaw["automate"] = caddyconfig.JSON(al, &warnings) } diff --git a/go.mod b/go.mod index eac017d10..67443562f 100644 --- a/go.mod +++ b/go.mod @@ -9,7 +9,7 @@ require ( github.com/Masterminds/sprig/v3 v3.3.0 github.com/alecthomas/chroma/v2 v2.14.0 github.com/aryann/difflib v0.0.0-20210328193216-ff5ff6dc229b - github.com/caddyserver/certmagic v0.21.5-0.20241219182349-258b5328e49e + github.com/caddyserver/certmagic v0.21.5 github.com/caddyserver/zerossl v0.1.3 github.com/dustin/go-humanize v1.0.1 github.com/go-chi/chi/v5 v5.0.12 diff --git a/go.sum b/go.sum index 4855f2e0a..538304a28 100644 --- a/go.sum +++ b/go.sum @@ -89,8 +89,8 @@ github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/bradfitz/go-smtpd v0.0.0-20170404230938-deb6d6237625/go.mod h1:HYsPBTaaSFSlLx/70C2HPIMNZpVV8+vt/A+FMnYP11g= github.com/buger/jsonparser v0.0.0-20181115193947-bf1c66bbce23/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s= -github.com/caddyserver/certmagic v0.21.5-0.20241219182349-258b5328e49e h1:AFPVZ2IOgM6NdL2GwMMf+V7NDU3IQ9t4aPbcNbHsitY= -github.com/caddyserver/certmagic v0.21.5-0.20241219182349-258b5328e49e/go.mod h1:n1sCo7zV1Ez2j+89wrzDxo4N/T1Ws/Vx8u5NvuBFabw= +github.com/caddyserver/certmagic v0.21.5 h1:iIga4nZRgd27EIEbX7RZmoRMul+EVBn/h7bAGL83dnY= +github.com/caddyserver/certmagic v0.21.5/go.mod h1:n1sCo7zV1Ez2j+89wrzDxo4N/T1Ws/Vx8u5NvuBFabw= github.com/caddyserver/zerossl v0.1.3 h1:onS+pxp3M8HnHpN5MMbOMyNjmTheJyWRaZYwn+YTAyA= github.com/caddyserver/zerossl v0.1.3/go.mod h1:CxA0acn7oEGO6//4rtrRjYgEoa4MFw/XofZnrYwGqG4= github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8= diff --git a/modules/caddyhttp/reverseproxy/reverseproxy.go b/modules/caddyhttp/reverseproxy/reverseproxy.go index f9485c570..230bec951 100644 --- a/modules/caddyhttp/reverseproxy/reverseproxy.go +++ b/modules/caddyhttp/reverseproxy/reverseproxy.go @@ -243,6 +243,19 @@ func (h *Handler) Provision(ctx caddy.Context) error { return fmt.Errorf("loading transport: %v", err) } h.Transport = mod.(http.RoundTripper) + // enable request buffering for fastcgi if not configured + // This is because most fastcgi servers are php-fpm that require the content length to be set to read the body, golang + // std has fastcgi implementation that doesn't need this value to process the body, but we can safely assume that's + // not used. + // http3 requests have a negative content length for GET and HEAD requests, if that header is not sent. + // see: https://github.com/caddyserver/caddy/issues/6678#issuecomment-2472224182 + // Though it appears even if CONTENT_LENGTH is invalid, php-fpm can handle just fine if the body is empty (no Stdin records sent). + // php-fpm will hang if there is any data in the body though, https://github.com/caddyserver/caddy/issues/5420#issuecomment-2415943516 + + // TODO: better default buffering for fastcgi requests without content length, in theory a value of 1 should be enough, make it bigger anyway + if module, ok := h.Transport.(caddy.Module); ok && module.CaddyModule().ID.Name() == "fastcgi" && h.RequestBuffers == 0 { + h.RequestBuffers = 4096 + } } if h.LoadBalancing != nil && h.LoadBalancing.SelectionPolicyRaw != nil { mod, err := ctx.LoadModule(h.LoadBalancing, "SelectionPolicyRaw") @@ -1216,13 +1229,14 @@ func (h Handler) bufferedBody(originalBody io.ReadCloser, limit int64) (io.ReadC buf := bufPool.Get().(*bytes.Buffer) buf.Reset() if limit > 0 { - n, err := io.CopyN(buf, originalBody, limit) - if (err != nil && err != io.EOF) || n == limit { + var err error + written, err = io.CopyN(buf, originalBody, limit) + if (err != nil && err != io.EOF) || written == limit { return bodyReadCloser{ Reader: io.MultiReader(buf, originalBody), buf: buf, body: originalBody, - }, n + }, written } } else { written, _ = io.Copy(buf, originalBody)