mirror of
https://github.com/caddyserver/caddy.git
synced 2026-07-31 09:27:54 -04:00
* test: add failing tests for intercept replace_status (#7805) Add integration tests that verify replace_status actually substitutes the HTTP status code sent to the client. Currently these tests fail because replace_status is silently a no-op due to value-receiver boxing and shouldBuffer returning false. Tests added: - TestInterceptReplaceStatusWithMatcher: 500 -> 200 with @err matcher - TestInterceptReplaceStatusWithoutMatcher: 403 -> 200 unconditionally - TestInterceptReplaceStatusNotMatched: 200 passes through unchanged * fix: make intercept replace_status actually substitute the status code Fix #7805: replace_status was silently a no-op because: 1. shouldBuffer returned false when a replacement status was set, causing the original status to be streamed directly to the wire 2. The value-receiver WriteHeader method operated on a stale copy The fix: - shouldBuffer now returns true when replace_status matches, so the response is buffered instead of streamed - After next.ServeHTTP returns, if routes are nil (replace_status only), write the substituted status and buffered body to the client The interceptedResponseHandler.WriteHeader substitution branch is no longer needed for this path since substitution happens post-ServeHTTP. * refactor: remove dead WriteHeader method and resolved TODO The value-receiver WriteHeader on interceptedResponseHandler was unreachable dead code — the substitution is now handled post-ServeHTTP via buffering. Remove it along with the TODO comment that noted status code replacement was unfinished. * style: apply nit suggestions from dunglas code review Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
110 lines
2.4 KiB
Go
110 lines
2.4 KiB
Go
package integration
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"github.com/caddyserver/caddy/v2/caddytest"
|
|
)
|
|
|
|
func TestIntercept(t *testing.T) {
|
|
tester := caddytest.NewTester(t)
|
|
tester.InitServer(`{
|
|
skip_install_trust
|
|
admin localhost:2999
|
|
http_port 9080
|
|
https_port 9443
|
|
grace_period 1ns
|
|
}
|
|
|
|
localhost:9080 {
|
|
respond /intercept "I'm a teapot" 408
|
|
header /intercept To-Intercept ok
|
|
respond /no-intercept "I'm not a teapot"
|
|
|
|
intercept {
|
|
@teapot status 408
|
|
handle_response @teapot {
|
|
header /intercept intercepted {resp.header.To-Intercept}
|
|
respond /intercept "I'm a combined coffee/tea pot that is temporarily out of coffee" 503
|
|
}
|
|
}
|
|
}
|
|
`, "caddyfile")
|
|
|
|
r, _ := tester.AssertGetResponse("http://localhost:9080/intercept", 503, "I'm a combined coffee/tea pot that is temporarily out of coffee")
|
|
if r.Header.Get("intercepted") != "ok" {
|
|
t.Fatalf(`header "intercepted" value is not "ok": %s`, r.Header.Get("intercepted"))
|
|
}
|
|
|
|
tester.AssertGetResponse("http://localhost:9080/no-intercept", 200, "I'm not a teapot")
|
|
}
|
|
|
|
func TestInterceptReplaceStatusWithMatcher(t *testing.T) {
|
|
tester := caddytest.NewTester(t)
|
|
tester.InitServer(`{
|
|
skip_install_trust
|
|
admin localhost:2999
|
|
http_port 9080
|
|
https_port 9443
|
|
grace_period 1ns
|
|
}
|
|
|
|
localhost:9080 {
|
|
respond /error "boom" 500
|
|
|
|
intercept {
|
|
@err status 5xx
|
|
replace_status @err 200
|
|
}
|
|
}
|
|
`, "caddyfile")
|
|
|
|
tester.AssertGetResponse("http://localhost:9080/error", 200, "boom")
|
|
}
|
|
|
|
func TestInterceptReplaceStatusWithoutMatcher(t *testing.T) {
|
|
tester := caddytest.NewTester(t)
|
|
tester.InitServer(`{
|
|
skip_install_trust
|
|
admin localhost:2999
|
|
http_port 9080
|
|
https_port 9443
|
|
grace_period 1ns
|
|
}
|
|
|
|
localhost:9080 {
|
|
respond /forbidden "denied" 403
|
|
|
|
intercept {
|
|
replace_status 200
|
|
}
|
|
}
|
|
`, "caddyfile")
|
|
|
|
tester.AssertGetResponse("http://localhost:9080/forbidden", 200, "denied")
|
|
}
|
|
|
|
func TestInterceptReplaceStatusNotMatched(t *testing.T) {
|
|
tester := caddytest.NewTester(t)
|
|
tester.InitServer(`{
|
|
skip_install_trust
|
|
admin localhost:2999
|
|
http_port 9080
|
|
https_port 9443
|
|
grace_period 1ns
|
|
}
|
|
|
|
localhost:9080 {
|
|
respond /ok "all good" 200
|
|
|
|
intercept {
|
|
@err status 5xx
|
|
replace_status @err 503
|
|
}
|
|
}
|
|
`, "caddyfile")
|
|
|
|
// 200 does not match @err (5xx), so status should pass through unchanged
|
|
tester.AssertGetResponse("http://localhost:9080/ok", 200, "all good")
|
|
}
|