From cfa6abae5ffc6f2cb58139890121ad44c178fe25 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Carlos=20Ch=C3=A1vez?= Date: Mon, 27 Nov 2023 15:30:55 +0100 Subject: [PATCH 1/2] chore: fixes short write error. --- .github/workflows/nightly-caddy.yml | 1 + interceptor.go | 5 +++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/nightly-caddy.yml b/.github/workflows/nightly-caddy.yml index f406364..191329a 100644 --- a/.github/workflows/nightly-caddy.yml +++ b/.github/workflows/nightly-caddy.yml @@ -13,6 +13,7 @@ on: jobs: nightly-caddy: + name: "Nightly Caddy (caddy version: ${{ github.event.inputs.caddyversion || 'master' }})" strategy: matrix: go-version: [1.20.x] diff --git a/interceptor.go b/interceptor.go index b55fab7..055d289 100644 --- a/interceptor.go +++ b/interceptor.go @@ -4,6 +4,7 @@ package coraza import ( + "errors" "fmt" "io" "log" @@ -73,7 +74,7 @@ func (i *rwInterceptor) Write(b []byte) (int, error) { // if there is an interruption it must be from at least phase 4 and hence // WriteHeader or Write should have been called and hence the status code // has been flushed to the delegated response writer. - return 0, nil + return 0, errors.New("response writer is interrupted") } if !i.wroteHeader { @@ -89,7 +90,7 @@ func (i *rwInterceptor) Write(b []byte) (int, error) { i.overrideWriteHeader(it.Status) // We only flush the status code after an interruption. i.flushWriteHeader() - return 0, nil + return 0, errors.New("response writer is interrupted") } return n, err } From 11fb2274ca74bdaf6a97eea36203e48c18c7ea84 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Carlos=20Ch=C3=A1vez?= Date: Mon, 27 Nov 2023 23:29:48 +0100 Subject: [PATCH 2/2] fix: removes the content length header on phase 3 interruption so caddy does not fail as per https://github.com/caddyserver/caddy/pull/5952. --- interceptor.go | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/interceptor.go b/interceptor.go index 055d289..d9b1305 100644 --- a/interceptor.go +++ b/interceptor.go @@ -4,7 +4,6 @@ package coraza import ( - "errors" "fmt" "io" "log" @@ -43,6 +42,7 @@ func (i *rwInterceptor) WriteHeader(statusCode int) { i.statusCode = statusCode if it := i.tx.ProcessResponseHeaders(statusCode, i.proto); it != nil { + i.w.Header().Del("Content-Length") i.statusCode = obtainStatusCodeFromInterruptionOrDefault(it, i.statusCode) i.flushWriteHeader() return @@ -74,7 +74,11 @@ func (i *rwInterceptor) Write(b []byte) (int, error) { // if there is an interruption it must be from at least phase 4 and hence // WriteHeader or Write should have been called and hence the status code // has been flushed to the delegated response writer. - return 0, errors.New("response writer is interrupted") + // + // We return the number of bytes as according to the interface io.Writer + // if we don't return an error, the number of bytes written is len(p). + // See https://pkg.go.dev/io#Writer + return len(b), nil } if !i.wroteHeader { @@ -90,7 +94,11 @@ func (i *rwInterceptor) Write(b []byte) (int, error) { i.overrideWriteHeader(it.Status) // We only flush the status code after an interruption. i.flushWriteHeader() - return 0, errors.New("response writer is interrupted") + + // We return the number of bytes as according to the interface io.Writer + // if we don't return an error, the number of bytes written is len(p). + // See https://pkg.go.dev/io#Writer + return len(b), nil } return n, err }