fix: 修复源站错误页「仅针对 GET 请求」导致配置发布失败并回滚

This commit is contained in:
ryan
2026-08-08 22:37:40 +08:00
parent 94b74d72f6
commit 61484090f9
5 changed files with 15 additions and 17 deletions
+5 -11
View File
@@ -130,17 +130,11 @@ func renderOriginErrorPageIntercept(cfg ConfigSnapshot) string {
if _, err := ExpandStatusCodeTags(effectiveOriginErrorPageStatusTags(cfg)); err != nil {
return ""
}
// Always enable intercept for GET (and all methods when get_only is false).
// limit_except GET applies to non-GET methods: turn intercept off so origin
// error bodies (e.g. JSON 5xx) pass through unchanged.
var builder strings.Builder
builder.WriteString(" proxy_intercept_errors on;\n")
if cfg.OriginErrorPageGetOnly {
builder.WriteString(" limit_except GET {\n")
builder.WriteString(" proxy_intercept_errors off;\n")
builder.WriteString(" }\n")
}
return builder.String()
// Intercept at the proxy level for all methods. nginx does not allow
// proxy_intercept_errors inside limit_except (only allow/deny are valid
// there), so GET-only is enforced in the internal error location's Lua:
// non-GET requests exit with the original status and no custom HTML.
return " proxy_intercept_errors on;\n"
}
// renderOriginErrorPageServerBits emits server-level error_page + internal location.
@@ -88,11 +88,14 @@ func TestRenderOriginErrorPageGetOnly(t *testing.T) {
if !strings.Contains(out, "proxy_intercept_errors on") {
t.Fatal("missing intercept on")
}
if !strings.Contains(out, "limit_except GET") {
t.Fatal("get_only must emit limit_except GET")
// nginx rejects proxy_intercept_errors inside limit_except (only allow/deny
// are valid there), which made the generated config fail `openresty -t` and
// caused apply rollback. GET-only must rely on the internal location's Lua.
if strings.Contains(out, "limit_except") {
t.Fatal("get_only must not emit limit_except (proxy_intercept_errors is not allowed there)")
}
if !strings.Contains(out, "proxy_intercept_errors off") {
t.Fatal("get_only must turn intercept off for non-GET")
if strings.Contains(out, "proxy_intercept_errors off") {
t.Fatal("get_only must not emit proxy_intercept_errors off")
}
if !strings.Contains(out, `get_only = true`) {
t.Fatal("internal location must set get_only = true")