mirror of
https://github.com/caddyserver/caddy.git
synced 2026-11-11 19:37:55 +00:00
Share the adaptation group counter with named-route extraction because group satisfaction is request-wide. Cover nested invoke and handle_path while retaining sibling exclusivity. Addresses scan report fb62a11d-5561-49e3-87df-c175ea5a1f4d. Code written by GitHub Copilot (GPT-6.1 Sol, Claude Opus 5.5); reviewed by mholt. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
99 lines
1.9 KiB
Go
99 lines
1.9 KiB
Go
package httpcaddyfile_test
|
|
|
|
import (
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"testing"
|
|
|
|
"github.com/caddyserver/caddy/v2"
|
|
"github.com/caddyserver/caddy/v2/modules/caddyhttp"
|
|
_ "github.com/caddyserver/caddy/v2/modules/caddyhttp/rewrite"
|
|
)
|
|
|
|
func TestNamedRouteGroupsAreDistinct(t *testing.T) {
|
|
for _, tc := range []struct {
|
|
name, named, site string
|
|
}{
|
|
{
|
|
name: "handle",
|
|
named: `&(guard) {
|
|
handle /api/admin {
|
|
respond "denied" 403
|
|
}
|
|
handle {
|
|
respond "public"
|
|
}
|
|
}`,
|
|
site: `handle /api/* {
|
|
invoke guard
|
|
respond "allowed"
|
|
}`,
|
|
},
|
|
{
|
|
name: "handle_path",
|
|
named: `&(guard) {
|
|
handle /admin {
|
|
respond "denied" 403
|
|
}
|
|
handle {
|
|
respond "public"
|
|
}
|
|
}`,
|
|
site: `handle_path /api/* {
|
|
invoke guard
|
|
respond "allowed"
|
|
}`,
|
|
},
|
|
{
|
|
name: "nested invoke",
|
|
named: `&(inner) {
|
|
handle /api/admin {
|
|
respond "denied" 403
|
|
}
|
|
handle {
|
|
respond "public"
|
|
}
|
|
}
|
|
&(guard) {
|
|
handle /api/* {
|
|
invoke inner
|
|
}
|
|
handle {
|
|
respond "outer"
|
|
}
|
|
}`,
|
|
site: `handle /api/* {
|
|
invoke guard
|
|
respond "allowed"
|
|
}`,
|
|
},
|
|
} {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
server, handler := adaptedRouteHandler(t, "{\nadmin off\nauto_https off\n}\n"+tc.named+"\n:9080 {\n"+tc.site+`
|
|
handle {
|
|
respond "fallback" 404
|
|
}
|
|
}`)
|
|
for _, request := range []struct {
|
|
path string
|
|
code int
|
|
body string
|
|
}{
|
|
{"/api/admin", http.StatusForbidden, "denied"},
|
|
{"/api/public", http.StatusOK, "public"},
|
|
{"/other", http.StatusNotFound, "fallback"},
|
|
} {
|
|
req := httptest.NewRequest(http.MethodGet, request.path, nil)
|
|
req = caddyhttp.PrepareRequest(req, caddy.NewReplacer(), nil, server)
|
|
rec := httptest.NewRecorder()
|
|
if err := handler.ServeHTTP(rec, req); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if rec.Code != request.code || rec.Body.String() != request.body {
|
|
t.Errorf("%s: got %d %q, want %d %q", request.path, rec.Code, rec.Body.String(), request.code, request.body)
|
|
}
|
|
}
|
|
})
|
|
}
|
|
}
|