aboutsummaryrefslogtreecommitdiffhomepage
path: root/caddyconfig
diff options
context:
space:
mode:
authorAziz Rmadi <[email protected]>2024-01-16 00:24:17 -0600
committerGitHub <[email protected]>2024-01-16 01:24:17 -0500
commit4181c79a8130a59c40c76437e15265452422ccb1 (patch)
treefdbe25dec45d958720f0581439b39a9f37da28fb /caddyconfig
parent5e2f1b5ced5e7153f9748477612cf46188470ca7 (diff)
downloadcaddy-4181c79a8130a59c40c76437e15265452422ccb1.tar.gz
caddy-4181c79a8130a59c40c76437e15265452422ccb1.zip
httpcaddyfile: Add optional status code argument to `handle_errors` directive (#5965)
Co-authored-by: Aziz Rmadi <[email protected]>
Diffstat (limited to 'caddyconfig')
-rw-r--r--caddyconfig/httpcaddyfile/builtins.go59
-rw-r--r--caddyconfig/httpcaddyfile/httptype.go11
2 files changed, 68 insertions, 2 deletions
diff --git a/caddyconfig/httpcaddyfile/builtins.go b/caddyconfig/httpcaddyfile/builtins.go
index 3b56e0739..bf95a3616 100644
--- a/caddyconfig/httpcaddyfile/builtins.go
+++ b/caddyconfig/httpcaddyfile/builtins.go
@@ -844,10 +844,67 @@ func parseHandle(h Helper) (caddyhttp.MiddlewareHandler, error) {
}
func parseHandleErrors(h Helper) ([]ConfigValue, error) {
- subroute, err := ParseSegmentAsSubroute(h)
+ h.Next()
+ args := h.RemainingArgs()
+ expression := ""
+ if len(args) > 0 {
+ expression = ""
+ codes := []string{}
+ for _, val := range args {
+ if len(val) != 3 {
+ return nil, h.Errf("bad status value '%s'", val)
+ }
+ if strings.HasSuffix(val, "xx") {
+ val = val[:1]
+ _, err := strconv.Atoi(val)
+ if err != nil {
+ return nil, h.Errf("bad status value '%s': %v", val, err)
+ }
+ if expression != "" {
+ expression += " || "
+ }
+ expression += fmt.Sprintf("{http.error.status_code} >= %s00 && {http.error.status_code} <= %s99", val, val)
+ continue
+ }
+ _, err := strconv.Atoi(val)
+ if err != nil {
+ return nil, h.Errf("bad status value '%s': %v", val, err)
+ }
+ codes = append(codes, val)
+ }
+ if len(codes) > 0 {
+ if expression != "" {
+ expression += " || "
+ }
+ expression += "{http.error.status_code} in [" + strings.Join(codes, ", ") + "]"
+ }
+ // Reset cursor position to get ready for ParseSegmentAsSubroute
+ h.Reset()
+ h.Next()
+ h.RemainingArgs()
+ h.Prev()
+ } else {
+ // If no arguments present reset the cursor position to get ready for ParseSegmentAsSubroute
+ h.Prev()
+ }
+
+ handler, err := ParseSegmentAsSubroute(h)
if err != nil {
return nil, err
}
+ subroute, ok := handler.(*caddyhttp.Subroute)
+ if !ok {
+ return nil, h.Errf("segment was not parsed as a subroute")
+ }
+
+ if expression != "" {
+ statusMatcher := caddy.ModuleMap{
+ "expression": h.JSON(caddyhttp.MatchExpression{Expr: expression}),
+ }
+ for i := range subroute.Routes {
+ subroute.Routes[i].MatcherSetsRaw = []caddy.ModuleMap{statusMatcher}
+ }
+ }
return []ConfigValue{
{
Class: "error_route",
diff --git a/caddyconfig/httpcaddyfile/httptype.go b/caddyconfig/httpcaddyfile/httptype.go
index bc2b125ef..066df3014 100644
--- a/caddyconfig/httpcaddyfile/httptype.go
+++ b/caddyconfig/httpcaddyfile/httptype.go
@@ -774,10 +774,19 @@ func (st *ServerType) serversFromPairings(
if srv.Errors == nil {
srv.Errors = new(caddyhttp.HTTPErrorConfig)
}
+ sort.SliceStable(errorSubrouteVals, func(i, j int) bool {
+ sri, srj := errorSubrouteVals[i].Value.(*caddyhttp.Subroute), errorSubrouteVals[j].Value.(*caddyhttp.Subroute)
+ if len(sri.Routes[0].MatcherSetsRaw) == 0 && len(srj.Routes[0].MatcherSetsRaw) != 0 {
+ return false
+ }
+ return true
+ })
+ errorsSubroute := &caddyhttp.Subroute{}
for _, val := range errorSubrouteVals {
sr := val.Value.(*caddyhttp.Subroute)
- srv.Errors.Routes = appendSubrouteToRouteList(srv.Errors.Routes, sr, matcherSetsEnc, p, warnings)
+ errorsSubroute.Routes = append(errorsSubroute.Routes, sr.Routes...)
}
+ srv.Errors.Routes = appendSubrouteToRouteList(srv.Errors.Routes, errorsSubroute, matcherSetsEnc, p, warnings)
}
// add log associations