diff options
author | Aziz Rmadi <[email protected]> | 2024-01-16 00:24:17 -0600 |
---|---|---|
committer | GitHub <[email protected]> | 2024-01-16 01:24:17 -0500 |
commit | 4181c79a8130a59c40c76437e15265452422ccb1 (patch) | |
tree | fdbe25dec45d958720f0581439b39a9f37da28fb /caddyconfig | |
parent | 5e2f1b5ced5e7153f9748477612cf46188470ca7 (diff) | |
download | caddy-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.go | 59 | ||||
-rw-r--r-- | caddyconfig/httpcaddyfile/httptype.go | 11 |
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 |