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 {