@marcel91200 / caddy Mirror · read-only / commits / 87a1f228
Fork 0

Fast and extensible multi-platform HTTP/1-2-3 web server with automatic HTTPS

Mirrored from https://github.com/Slazee/caddy.git

Synced Nov 13, 21:45 UTC

reverseproxy: Move status replacement intercept to `replace_status` (#4300)

Francis Lavoie committed Mar 1, 2022 at 16:12 UTC 87a1f228b4c48db7bdab694cf0fd1c76243f29f3
2 files changed +56 -45
caddytest/integration/caddyfile_adapt/reverse_proxy_handle_response.txt
+11 -11
@@ -1,6 +1,9 @@
1 :8884
2
3 reverse_proxy 127.0.0.1:65535 {
4 + @changeStatus status 500
5 + replace_status @changeStatus 400
6 +
7 @accel header X-Accel-Redirect *
8 handle_response @accel {
9 respond "Header X-Accel-Redirect!"
@@ -38,9 +41,6 @@ reverse_proxy 127.0.0.1:65535 {
41 handle_response @multi {
42 respond "Headers Foo, Bar AND statuses 401, 403 and 404!"
43 }
41 -
42 - @changeStatus status 500
43 - handle_response @changeStatus 400
44 }
45 ----------
46 {
@@ -56,6 +56,14 @@ reverse_proxy 127.0.0.1:65535 {
56 "handle": [
57 {
58 "handle_response": [
59 + {
60 + "match": {
61 + "status_code": [
62 + 500
63 + ]
64 + },
65 + "status_code": 400
66 + },
67 {
68 "match": {
69 "headers": {
@@ -155,14 +163,6 @@ reverse_proxy 127.0.0.1:65535 {
163 }
164 ]
165 },
158 - {
159 - "match": {
160 - "status_code": [
161 - 500
162 - ]
163 - },
164 - "status_code": 400
165 - },
166 {
167 "routes": [
168 {
modules/caddyhttp/reverseproxy/caddyfile.go
+45 -34
@@ -91,12 +91,13 @@ func parseCaddyfile(h httpcaddyfile.Helper) (caddyhttp.MiddlewareHandler, error)
91 // ...
92 // }
93 //
94 -// # handle responses
94 +// # intercepting responses
95 // @name {
96 // status <code...>
97 // header <field> [<value>]
98 // }
99 -// handle_response [<matcher>] [status_code] {
99 +// replace_status <matcher> <status_code>
100 +// handle_response [<matcher>] {
101 // <directives...>
102 // }
103 // }
@@ -651,6 +652,39 @@ func (h *Handler) UnmarshalCaddyfile(d *caddyfile.Dispenser) error {
652 // See h.FinalizeUnmarshalCaddyfile
653 h.handleResponseSegments = append(h.handleResponseSegments, d.NewFromNextSegment())
654
655 + case "replace_status":
656 + args := d.RemainingArgs()
657 + if len(args) != 2 {
658 + return d.Errf("must have two arguments: a response matcher and a status code")
659 + }
660 +
661 + if !strings.HasPrefix(args[0], matcherPrefix) {
662 + return d.Errf("must use a named response matcher, starting with '@'")
663 + }
664 +
665 + foundMatcher, ok := h.responseMatchers[args[0]]
666 + if !ok {
667 + return d.Errf("no named response matcher defined with name '%s'", args[0][1:])
668 + }
669 +
670 + _, err := strconv.Atoi(args[1])
671 + if err != nil {
672 + return d.Errf("bad integer value '%s': %v", args[1], err)
673 + }
674 +
675 + // make sure there's no block, cause it doesn't make sense
676 + if d.NextBlock(1) {
677 + return d.Errf("cannot define routes for 'replace_status', use 'handle_response' instead.")
678 + }
679 +
680 + h.HandleResponse = append(
681 + h.HandleResponse,
682 + caddyhttp.ResponseHandler{
683 + Match: &foundMatcher,
684 + StatusCode: caddyhttp.WeakString(args[1]),
685 + },
686 + )
687 +
688 default:
689 return d.Errf("unrecognized subdirective %s", d.Val())
690 }
@@ -699,20 +733,20 @@ func (h *Handler) FinalizeUnmarshalCaddyfile(helper httpcaddyfile.Helper) error
733 for _, d := range h.handleResponseSegments {
734 // consume the "handle_response" token
735 d.Next()
702 -
703 - var matcher *caddyhttp.ResponseMatcher
736 args := d.RemainingArgs()
737
706 - // the first arg should be a matcher (optional)
707 - // the second arg should be a status code (optional)
708 - // any more than that isn't currently supported
709 - if len(args) > 2 {
738 + // TODO: Remove this check at some point in the future
739 + if len(args) == 2 {
740 + return d.Errf("configuring 'handle_response' for status code replacement is no longer supported. Use 'replace_status' instead.")
741 + }
742 +
743 + if len(args) > 1 {
744 return d.Errf("too many arguments for 'handle_response': %s", args)
745 }
746
713 - // the first arg should always be a matcher.
714 - // it doesn't really make sense to support status code without a matcher.
715 - if len(args) > 0 {
747 + var matcher *caddyhttp.ResponseMatcher
748 + if len(args) == 1 {
749 + // the first arg should always be a matcher.
750 if !strings.HasPrefix(args[0], matcherPrefix) {
751 return d.Errf("must use a named response matcher, starting with '@'")
752 }
@@ -724,29 +758,6 @@ func (h *Handler) FinalizeUnmarshalCaddyfile(helper httpcaddyfile.Helper) error
758 matcher = &foundMatcher
759 }
760
727 - // a second arg should be a status code, in which case
728 - // we skip parsing the block for routes
729 - if len(args) == 2 {
730 - _, err := strconv.Atoi(args[1])
731 - if err != nil {
732 - return d.Errf("bad integer value '%s': %v", args[1], err)
733 - }
734 -
735 - // make sure there's no block, cause it doesn't make sense
736 - if d.NextBlock(1) {
737 - return d.Errf("cannot define routes for 'handle_response' when changing the status code")
738 - }
739 -
740 - h.HandleResponse = append(
741 - h.HandleResponse,
742 - caddyhttp.ResponseHandler{
743 - Match: matcher,
744 - StatusCode: caddyhttp.WeakString(args[1]),
745 - },
746 - )
747 - continue
748 - }
749 -
761 // parse the block as routes
762 handler, err := httpcaddyfile.ParseSegmentAsSubroute(helper.WithDispenser(d.NewFromNextSegment()))
763 if err != nil {