From e3909cc385f68a636cc8675dc12f6cd5185d722d Mon Sep 17 00:00:00 2001 From: Mohammed Al Sahaf Date: Fri, 24 Feb 2023 22:54:04 +0300 Subject: reverseproxy: refactor HTTP transport layer (#5369) Co-authored-by: Francis Lavoie Co-authored-by: Weidi Deng --- caddytest/integration/reverseproxy_test.go | 268 ++++++++++++++--------------- 1 file changed, 134 insertions(+), 134 deletions(-) (limited to 'caddytest') diff --git a/caddytest/integration/reverseproxy_test.go b/caddytest/integration/reverseproxy_test.go index f7b1967..4333d12 100644 --- a/caddytest/integration/reverseproxy_test.go +++ b/caddytest/integration/reverseproxy_test.go @@ -22,39 +22,39 @@ func TestSRVReverseProxy(t *testing.T) { }, "apps": { "pki": { - "certificate_authorities" : { - "local" : { - "install_trust": false + "certificate_authorities": { + "local": { + "install_trust": false } } }, - "http": { - "grace_period": 1, - "servers": { - "srv0": { - "listen": [ - ":8080" - ], - "routes": [ - { - "handle": [ - { - "handler": "reverse_proxy", - "upstreams": [ - { - "lookup_srv": "srv.host.service.consul" - } + "http": { + "grace_period": 1, + "servers": { + "srv0": { + "listen": [ + ":18080" + ], + "routes": [ + { + "handle": [ + { + "handler": "reverse_proxy", + "upstreams": [ + { + "lookup_srv": "srv.host.service.consul" + } + ] + } + ] + } ] - } - ] - } - ] - } + } + } } - } } - } - `, "json") + } + `, "json") } func TestSRVWithDial(t *testing.T) { @@ -62,39 +62,39 @@ func TestSRVWithDial(t *testing.T) { { "apps": { "pki": { - "certificate_authorities" : { - "local" : { - "install_trust": false - } + "certificate_authorities": { + "local": { + "install_trust": false + } } - }, - "http": { - "grace_period": 1, - "servers": { - "srv0": { - "listen": [ - ":8080" - ], - "routes": [ - { - "handle": [ - { - "handler": "reverse_proxy", - "upstreams": [ - { - "dial": "tcp/address.to.upstream:80", - "lookup_srv": "srv.host.service.consul" - } + }, + "http": { + "grace_period": 1, + "servers": { + "srv0": { + "listen": [ + ":18080" + ], + "routes": [ + { + "handle": [ + { + "handler": "reverse_proxy", + "upstreams": [ + { + "dial": "tcp/address.to.upstream:80", + "lookup_srv": "srv.host.service.consul" + } + ] + } + ] + } ] - } - ] - } - ] - } + } + } } - } } - } + } `, "json", `upstream: specifying dial address is incompatible with lookup_srv: 0: {\"dial\": \"tcp/address.to.upstream:80\", \"lookup_srv\": \"srv.host.service.consul\"}`) } @@ -138,41 +138,41 @@ func TestDialWithPlaceholderUnix(t *testing.T) { }, "apps": { "pki": { - "certificate_authorities" : { - "local" : { - "install_trust": false - } + "certificate_authorities": { + "local": { + "install_trust": false + } } - }, - "http": { - "grace_period": 1, - "servers": { - "srv0": { - "listen": [ - ":8080" - ], - "routes": [ - { - "handle": [ - { - "handler": "reverse_proxy", - "upstreams": [ - { - "dial": "unix/{http.request.header.X-Caddy-Upstream-Dial}" - } + }, + "http": { + "grace_period": 1, + "servers": { + "srv0": { + "listen": [ + ":18080" + ], + "routes": [ + { + "handle": [ + { + "handler": "reverse_proxy", + "upstreams": [ + { + "dial": "unix/{http.request.header.X-Caddy-Upstream-Dial}" + } + ] + } + ] + } ] - } - ] - } - ] - } - } - } + } + } + } } - } + } `, "json") - req, err := http.NewRequest(http.MethodGet, "http://localhost:8080", nil) + req, err := http.NewRequest(http.MethodGet, "http://localhost:18080", nil) if err != nil { t.Fail() return @@ -190,18 +190,18 @@ func TestReverseProxyWithPlaceholderDialAddress(t *testing.T) { }, "apps": { "pki": { - "certificate_authorities" : { - "local" : { - "install_trust": false - } + "certificate_authorities": { + "local": { + "install_trust": false + } } - }, + }, "http": { "grace_period": 1, "servers": { "srv0": { "listen": [ - ":8080" + ":18080" ], "routes": [ { @@ -264,14 +264,14 @@ func TestReverseProxyWithPlaceholderDialAddress(t *testing.T) { } } } - `, "json") + `, "json") req, err := http.NewRequest(http.MethodGet, "http://localhost:9080", nil) if err != nil { t.Fail() return } - req.Header.Set("X-Caddy-Upstream-Dial", "localhost:8080") + req.Header.Set("X-Caddy-Upstream-Dial", "localhost:18080") tester.AssertResponse(req, 200, "Hello, World!") } @@ -284,18 +284,18 @@ func TestReverseProxyWithPlaceholderTCPDialAddress(t *testing.T) { }, "apps": { "pki": { - "certificate_authorities" : { - "local" : { - "install_trust": false - } + "certificate_authorities": { + "local": { + "install_trust": false + } } - }, + }, "http": { "grace_period": 1, "servers": { "srv0": { "listen": [ - ":8080" + ":18080" ], "routes": [ { @@ -340,7 +340,7 @@ func TestReverseProxyWithPlaceholderTCPDialAddress(t *testing.T) { "handler": "reverse_proxy", "upstreams": [ { - "dial": "tcp/{http.request.header.X-Caddy-Upstream-Dial}:8080" + "dial": "tcp/{http.request.header.X-Caddy-Upstream-Dial}:18080" } ] } @@ -358,7 +358,7 @@ func TestReverseProxyWithPlaceholderTCPDialAddress(t *testing.T) { } } } - `, "json") + `, "json") req, err := http.NewRequest(http.MethodGet, "http://localhost:9080", nil) if err != nil { @@ -375,42 +375,42 @@ func TestSRVWithActiveHealthcheck(t *testing.T) { "apps": { "pki": { "certificate_authorities" : { - "local" : { - "install_trust": false - } + "local" : { + "install_trust": false + } } - }, - "http": { - "grace_period": 1, - "servers": { - "srv0": { - "listen": [ - ":8080" - ], - "routes": [ - { - "handle": [ - { - "handler": "reverse_proxy", - "health_checks": { - "active": { - "path": "/ok" + }, + "http": { + "grace_period": 1, + "servers": { + "srv0": { + "listen": [ + ":18080" + ], + "routes": [ + { + "handle": [ + { + "handler": "reverse_proxy", + "health_checks": { + "active": { + "path": "/ok" + } + }, + "upstreams": [ + { + "lookup_srv": "srv.host.service.consul" + } + ] + } + ] } - }, - "upstreams": [ - { - "lookup_srv": "srv.host.service.consul" - } ] - } - ] - } - ] - } + } + } } - } } - } + } `, "json", `upstream: lookup_srv is incompatible with active health checks: 0: {\"dial\": \"\", \"lookup_srv\": \"srv.host.service.consul\"}`) } @@ -440,7 +440,7 @@ func TestReverseProxyHealthCheck(t *testing.T) { health_timeout 100ms } } - `, "caddyfile") + `, "caddyfile") time.Sleep(100 * time.Millisecond) // TODO: for some reason this test seems particularly flaky, getting 503 when it should be 200, unless we wait tester.AssertGetResponse("http://localhost:9080/", 200, "Hello, World!") -- cgit v1.2.3 From 960150bb034dc9a549ee7289b1a4eb4abafeb30a Mon Sep 17 00:00:00 2001 From: Francis Lavoie Date: Sat, 25 Feb 2023 19:34:27 -0500 Subject: caddyfile: Implement heredoc support (#5385) --- caddytest/integration/caddyfile_adapt/heredoc.txt | 50 ++++++++++++++++++++++ .../caddyfile_adapt/import_args_snippet.txt | 2 +- .../caddyfile_adapt/reverse_proxy_options.txt | 4 +- caddytest/integration/testdata/import_respond.txt | 2 +- 4 files changed, 54 insertions(+), 4 deletions(-) create mode 100644 caddytest/integration/caddyfile_adapt/heredoc.txt (limited to 'caddytest') diff --git a/caddytest/integration/caddyfile_adapt/heredoc.txt b/caddytest/integration/caddyfile_adapt/heredoc.txt new file mode 100644 index 0000000..15f8aef --- /dev/null +++ b/caddytest/integration/caddyfile_adapt/heredoc.txt @@ -0,0 +1,50 @@ +example.com { + respond < + Foo + Foo + + EOF 200 +} +---------- +{ + "apps": { + "http": { + "servers": { + "srv0": { + "listen": [ + ":443" + ], + "routes": [ + { + "match": [ + { + "host": [ + "example.com" + ] + } + ], + "handle": [ + { + "handler": "subroute", + "routes": [ + { + "handle": [ + { + "body": "\u003chtml\u003e\n \u003chead\u003e\u003ctitle\u003eFoo\u003c/title\u003e\n \u003cbody\u003eFoo\u003c/body\u003e\n\u003c/html\u003e\n", + "handler": "static_response", + "status_code": 200 + } + ] + } + ] + } + ], + "terminal": true + } + ] + } + } + } + } +} \ No newline at end of file diff --git a/caddytest/integration/caddyfile_adapt/import_args_snippet.txt b/caddytest/integration/caddyfile_adapt/import_args_snippet.txt index 9fce9ab..10d9f4c 100644 --- a/caddytest/integration/caddyfile_adapt/import_args_snippet.txt +++ b/caddytest/integration/caddyfile_adapt/import_args_snippet.txt @@ -1,6 +1,6 @@ (logging) { log { - output file /var/log/caddy/{args.0}.access.log + output file /var/log/caddy/{args[0]}.access.log } } diff --git a/caddytest/integration/caddyfile_adapt/reverse_proxy_options.txt b/caddytest/integration/caddyfile_adapt/reverse_proxy_options.txt index b22333a..f6420ca 100644 --- a/caddytest/integration/caddyfile_adapt/reverse_proxy_options.txt +++ b/caddytest/integration/caddyfile_adapt/reverse_proxy_options.txt @@ -6,7 +6,7 @@ https://example.com { method GET rewrite /rewritten?uri={uri} - buffer_requests + request_buffers 4KB transport http { read_buffer 10MB @@ -54,7 +54,6 @@ https://example.com { { "handle": [ { - "buffer_requests": true, "handler": "reverse_proxy", "headers": { "request": { @@ -68,6 +67,7 @@ https://example.com { } } }, + "request_buffers": 4000, "rewrite": { "method": "GET", "uri": "/rewritten?uri={http.request.uri}" diff --git a/caddytest/integration/testdata/import_respond.txt b/caddytest/integration/testdata/import_respond.txt index 0907fbe..4513088 100644 --- a/caddytest/integration/testdata/import_respond.txt +++ b/caddytest/integration/testdata/import_respond.txt @@ -1 +1 @@ -respond "'I am {args.0}', hears {args.1}" \ No newline at end of file +respond "'I am {args[0]}', hears {args[1]}" \ No newline at end of file -- cgit v1.2.3 From f3379f650a3de0e83903e3aa34d39b4ec647ee50 Mon Sep 17 00:00:00 2001 From: Francis Lavoie Date: Sun, 26 Feb 2023 16:56:48 -0500 Subject: caddyfile: Fix heredoc fuzz crasher, drop trailing newline (#5404) Co-authored-by: Mohammed Al Sahaf --- caddytest/integration/caddyfile_adapt/heredoc.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'caddytest') diff --git a/caddytest/integration/caddyfile_adapt/heredoc.txt b/caddytest/integration/caddyfile_adapt/heredoc.txt index 15f8aef..cc1174d 100644 --- a/caddytest/integration/caddyfile_adapt/heredoc.txt +++ b/caddytest/integration/caddyfile_adapt/heredoc.txt @@ -31,7 +31,7 @@ example.com { { "handle": [ { - "body": "\u003chtml\u003e\n \u003chead\u003e\u003ctitle\u003eFoo\u003c/title\u003e\n \u003cbody\u003eFoo\u003c/body\u003e\n\u003c/html\u003e\n", + "body": "\u003chtml\u003e\n \u003chead\u003e\u003ctitle\u003eFoo\u003c/title\u003e\n \u003cbody\u003eFoo\u003c/body\u003e\n\u003c/html\u003e", "handler": "static_response", "status_code": 200 } -- cgit v1.2.3 From 941eae5f615aeaf038f62002e673a7bf4886f1c7 Mon Sep 17 00:00:00 2001 From: Emily Lange Date: Mon, 27 Feb 2023 18:23:09 +0100 Subject: reverseproxy: allow specifying ip version for dynamic `a` upstream (#5401) Co-authored-by: Francis Lavoie --- .../caddyfile_adapt/reverse_proxy_dynamic_upstreams.txt | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'caddytest') diff --git a/caddytest/integration/caddyfile_adapt/reverse_proxy_dynamic_upstreams.txt b/caddytest/integration/caddyfile_adapt/reverse_proxy_dynamic_upstreams.txt index 2f2cbcd..384cc05 100644 --- a/caddytest/integration/caddyfile_adapt/reverse_proxy_dynamic_upstreams.txt +++ b/caddytest/integration/caddyfile_adapt/reverse_proxy_dynamic_upstreams.txt @@ -11,6 +11,7 @@ resolvers 8.8.8.8 8.8.4.4 dial_timeout 2s dial_fallback_delay 300ms + versions ipv6 } } } @@ -66,7 +67,10 @@ "8.8.4.4" ] }, - "source": "a" + "source": "a", + "versions": { + "ipv6": true + } }, "handler": "reverse_proxy" } @@ -113,4 +117,4 @@ } } } -} \ No newline at end of file +} -- cgit v1.2.3 From 330be2d8c793147d3914f944eecb96c18f2eabff Mon Sep 17 00:00:00 2001 From: Francis Lavoie Date: Mon, 27 Mar 2023 15:43:44 -0400 Subject: httpcaddyfile: Adjust path matcher sorting to solve for specificity (#5462) --- .../map_and_vars_with_raw_types.txt | 8 ++-- .../sort_directives_within_handle.txt | 50 +++++++++++++++++++--- .../caddyfile_adapt/sort_vars_in_reverse.txt | 20 ++++++++- 3 files changed, 65 insertions(+), 13 deletions(-) (limited to 'caddytest') diff --git a/caddytest/integration/caddyfile_adapt/map_and_vars_with_raw_types.txt b/caddytest/integration/caddyfile_adapt/map_and_vars_with_raw_types.txt index af9faf4..cc75630 100644 --- a/caddytest/integration/caddyfile_adapt/map_and_vars_with_raw_types.txt +++ b/caddytest/integration/caddyfile_adapt/map_and_vars_with_raw_types.txt @@ -100,16 +100,16 @@ vars { ], "source": "{http.request.host}" }, - { - "foo": "bar", - "handler": "vars" - }, { "abc": true, "def": 1, "ghi": 2.3, "handler": "vars", "jkl": "mn op" + }, + { + "foo": "bar", + "handler": "vars" } ] } diff --git a/caddytest/integration/caddyfile_adapt/sort_directives_within_handle.txt b/caddytest/integration/caddyfile_adapt/sort_directives_within_handle.txt index 0cf9d88..ac0d53c 100644 --- a/caddytest/integration/caddyfile_adapt/sort_directives_within_handle.txt +++ b/caddytest/integration/caddyfile_adapt/sort_directives_within_handle.txt @@ -1,12 +1,15 @@ *.example.com { @foo host foo.example.com handle @foo { - handle_path /strip* { + handle_path /strip { respond "this should be first" } - handle { + handle_path /strip* { respond "this should be second" } + handle { + respond "this should be last" + } } handle { respond "this should be last" @@ -35,13 +38,13 @@ "handler": "subroute", "routes": [ { - "group": "group5", + "group": "group6", "handle": [ { "handler": "subroute", "routes": [ { - "group": "group2", + "group": "group3", "handle": [ { "handler": "subroute", @@ -68,17 +71,25 @@ "match": [ { "path": [ - "/strip*" + "/strip" ] } ] }, { - "group": "group2", + "group": "group3", "handle": [ { "handler": "subroute", "routes": [ + { + "handle": [ + { + "handler": "rewrite", + "strip_path_prefix": "/strip" + } + ] + }, { "handle": [ { @@ -89,6 +100,31 @@ } ] } + ], + "match": [ + { + "path": [ + "/strip*" + ] + } + ] + }, + { + "group": "group3", + "handle": [ + { + "handler": "subroute", + "routes": [ + { + "handle": [ + { + "body": "this should be last", + "handler": "static_response" + } + ] + } + ] + } ] } ] @@ -103,7 +139,7 @@ ] }, { - "group": "group5", + "group": "group6", "handle": [ { "handler": "subroute", diff --git a/caddytest/integration/caddyfile_adapt/sort_vars_in_reverse.txt b/caddytest/integration/caddyfile_adapt/sort_vars_in_reverse.txt index dff75e1..38a912f 100644 --- a/caddytest/integration/caddyfile_adapt/sort_vars_in_reverse.txt +++ b/caddytest/integration/caddyfile_adapt/sort_vars_in_reverse.txt @@ -1,7 +1,8 @@ :80 vars /foobar foo last -vars /foo foo middle +vars /foo foo middle-last +vars /foo* foo middle-first vars * foo first ---------- { @@ -21,6 +22,21 @@ vars * foo first } ] }, + { + "match": [ + { + "path": [ + "/foo*" + ] + } + ], + "handle": [ + { + "foo": "middle-first", + "handler": "vars" + } + ] + }, { "match": [ { @@ -31,7 +47,7 @@ vars * foo first ], "handle": [ { - "foo": "middle", + "foo": "middle-last", "handler": "vars" } ] -- cgit v1.2.3 From 05e9974570a08df14b1162a1e98315d4ee9ec2ee Mon Sep 17 00:00:00 2001 From: Francis Lavoie Date: Mon, 27 Mar 2023 16:22:59 -0400 Subject: caddyhttp: Determine real client IP if trusted proxies configured (#5104) * caddyhttp: Determine real client IP if trusted proxies configured * Support customizing client IP header * Implement client_ip matcher, deprecate remote_ip's forwarded option --- .../global_server_options_single.txt | 7 ++++++ .../integration/caddyfile_adapt/matcher_syntax.txt | 25 ++++++++++++++++++++++ 2 files changed, 32 insertions(+) (limited to 'caddytest') diff --git a/caddytest/integration/caddyfile_adapt/global_server_options_single.txt b/caddytest/integration/caddyfile_adapt/global_server_options_single.txt index d963604..300b4ac 100644 --- a/caddytest/integration/caddyfile_adapt/global_server_options_single.txt +++ b/caddytest/integration/caddyfile_adapt/global_server_options_single.txt @@ -15,6 +15,8 @@ protocols h1 h2 h2c h3 strict_sni_host trusted_proxies static private_ranges + client_ip_headers Custom-Real-Client-IP X-Forwarded-For + client_ip_headers A-Third-One } } @@ -67,6 +69,11 @@ foo.com { ], "source": "static" }, + "client_ip_headers": [ + "Custom-Real-Client-IP", + "X-Forwarded-For", + "A-Third-One" + ], "logs": { "should_log_credentials": true }, diff --git a/caddytest/integration/caddyfile_adapt/matcher_syntax.txt b/caddytest/integration/caddyfile_adapt/matcher_syntax.txt index fb3dfb6..ffab2c7 100644 --- a/caddytest/integration/caddyfile_adapt/matcher_syntax.txt +++ b/caddytest/integration/caddyfile_adapt/matcher_syntax.txt @@ -43,6 +43,9 @@ @matcher11 remote_ip private_ranges respond @matcher11 "remote_ip matcher with private ranges" + + @matcher12 client_ip private_ranges + respond @matcher12 "client_ip matcher with private ranges" } ---------- { @@ -250,6 +253,28 @@ "handler": "static_response" } ] + }, + { + "match": [ + { + "client_ip": { + "ranges": [ + "192.168.0.0/16", + "172.16.0.0/12", + "10.0.0.0/8", + "127.0.0.1/8", + "fd00::/8", + "::1" + ] + } + } + ], + "handle": [ + { + "body": "client_ip matcher with private ranges", + "handler": "static_response" + } + ] } ] } -- cgit v1.2.3 From 4636109ce17e6ba5f46e73b7b1f3ae82d076a625 Mon Sep 17 00:00:00 2001 From: Francis Lavoie Date: Mon, 10 Apr 2023 16:08:40 -0400 Subject: reverseproxy: Remove deprecated `lookup_srv` (#5396) --- caddytest/integration/reverseproxy_test.go | 95 ++---------------------------- 1 file changed, 4 insertions(+), 91 deletions(-) (limited to 'caddytest') diff --git a/caddytest/integration/reverseproxy_test.go b/caddytest/integration/reverseproxy_test.go index 4333d12..4f4261b 100644 --- a/caddytest/integration/reverseproxy_test.go +++ b/caddytest/integration/reverseproxy_test.go @@ -40,11 +40,10 @@ func TestSRVReverseProxy(t *testing.T) { "handle": [ { "handler": "reverse_proxy", - "upstreams": [ - { - "lookup_srv": "srv.host.service.consul" - } - ] + "dynamic_upstreams": { + "source": "srv", + "name": "srv.host.service.consul" + } } ] } @@ -57,47 +56,6 @@ func TestSRVReverseProxy(t *testing.T) { `, "json") } -func TestSRVWithDial(t *testing.T) { - caddytest.AssertLoadError(t, ` - { - "apps": { - "pki": { - "certificate_authorities": { - "local": { - "install_trust": false - } - } - }, - "http": { - "grace_period": 1, - "servers": { - "srv0": { - "listen": [ - ":18080" - ], - "routes": [ - { - "handle": [ - { - "handler": "reverse_proxy", - "upstreams": [ - { - "dial": "tcp/address.to.upstream:80", - "lookup_srv": "srv.host.service.consul" - } - ] - } - ] - } - ] - } - } - } - } - } - `, "json", `upstream: specifying dial address is incompatible with lookup_srv: 0: {\"dial\": \"tcp/address.to.upstream:80\", \"lookup_srv\": \"srv.host.service.consul\"}`) -} - func TestDialWithPlaceholderUnix(t *testing.T) { if runtime.GOOS == "windows" { @@ -369,51 +327,6 @@ func TestReverseProxyWithPlaceholderTCPDialAddress(t *testing.T) { tester.AssertResponse(req, 200, "Hello, World!") } -func TestSRVWithActiveHealthcheck(t *testing.T) { - caddytest.AssertLoadError(t, ` - { - "apps": { - "pki": { - "certificate_authorities" : { - "local" : { - "install_trust": false - } - } - }, - "http": { - "grace_period": 1, - "servers": { - "srv0": { - "listen": [ - ":18080" - ], - "routes": [ - { - "handle": [ - { - "handler": "reverse_proxy", - "health_checks": { - "active": { - "path": "/ok" - } - }, - "upstreams": [ - { - "lookup_srv": "srv.host.service.consul" - } - ] - } - ] - } - ] - } - } - } - } - } - `, "json", `upstream: lookup_srv is incompatible with active health checks: 0: {\"dial\": \"\", \"lookup_srv\": \"srv.host.service.consul\"}`) -} - func TestReverseProxyHealthCheck(t *testing.T) { tester := caddytest.NewTester(t) tester.InitServer(` -- cgit v1.2.3 From 75b690d248c7681dd974f6179c98a363af417a25 Mon Sep 17 00:00:00 2001 From: Francis Lavoie Date: Mon, 15 May 2023 14:14:50 -0400 Subject: reverseproxy: Expand port ranges to multiple upstreams in CLI + Caddyfile (#5494) * reverseproxy: Expand port ranges to multiple upstreams in CLI + Caddyfile * Add clarifying comment --- .../caddyfile_adapt/reverse_proxy_port_range.txt | 67 ++++++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 caddytest/integration/caddyfile_adapt/reverse_proxy_port_range.txt (limited to 'caddytest') diff --git a/caddytest/integration/caddyfile_adapt/reverse_proxy_port_range.txt b/caddytest/integration/caddyfile_adapt/reverse_proxy_port_range.txt new file mode 100644 index 0000000..978d8c9 --- /dev/null +++ b/caddytest/integration/caddyfile_adapt/reverse_proxy_port_range.txt @@ -0,0 +1,67 @@ +:8884 { + # Port range + reverse_proxy localhost:8001-8002 + + # Port range with placeholder + reverse_proxy {host}:8001-8002 + + # Port range with scheme + reverse_proxy https://localhost:8001-8002 +} +---------- +{ + "apps": { + "http": { + "servers": { + "srv0": { + "listen": [ + ":8884" + ], + "routes": [ + { + "handle": [ + { + "handler": "reverse_proxy", + "upstreams": [ + { + "dial": "localhost:8001" + }, + { + "dial": "localhost:8002" + } + ] + }, + { + "handler": "reverse_proxy", + "upstreams": [ + { + "dial": "{http.request.host}:8001" + }, + { + "dial": "{http.request.host}:8002" + } + ] + }, + { + "handler": "reverse_proxy", + "transport": { + "protocol": "http", + "tls": {} + }, + "upstreams": [ + { + "dial": "localhost:8001" + }, + { + "dial": "localhost:8002" + } + ] + } + ] + } + ] + } + } + } + } +} \ No newline at end of file -- cgit v1.2.3 From e8352aef38642c20ff528836b6581094f087eb99 Mon Sep 17 00:00:00 2001 From: Francis Lavoie Date: Tue, 16 May 2023 01:18:13 -0400 Subject: headers: Add > Caddyfile shortcut for enabling defer (#5535) --- caddytest/integration/caddyfile_adapt/header.txt | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'caddytest') diff --git a/caddytest/integration/caddyfile_adapt/header.txt b/caddytest/integration/caddyfile_adapt/header.txt index 34a044d..95c1474 100644 --- a/caddytest/integration/caddyfile_adapt/header.txt +++ b/caddytest/integration/caddyfile_adapt/header.txt @@ -17,6 +17,7 @@ +Link "Foo" +Link "Bar" } + header >Set Defer } ---------- { @@ -136,6 +137,17 @@ ] } } + }, + { + "handler": "headers", + "response": { + "deferred": true, + "set": { + "Set": [ + "Defer" + ] + } + } } ] } -- cgit v1.2.3 From cbf16f6d9eb77f37d6eb588ff3e54cfdfddecc21 Mon Sep 17 00:00:00 2001 From: Francis Lavoie Date: Tue, 16 May 2023 11:27:52 -0400 Subject: caddyhttp: Implement named routes, `invoke` directive (#5107) * caddyhttp: Implement named routes, `invoke` directive * gofmt * Add experimental marker * Adjust route compile comments --- .../caddyfile_adapt/invoke_named_routes.txt | 154 +++++++++++++++++++++ 1 file changed, 154 insertions(+) create mode 100644 caddytest/integration/caddyfile_adapt/invoke_named_routes.txt (limited to 'caddytest') diff --git a/caddytest/integration/caddyfile_adapt/invoke_named_routes.txt b/caddytest/integration/caddyfile_adapt/invoke_named_routes.txt new file mode 100644 index 0000000..83d9859 --- /dev/null +++ b/caddytest/integration/caddyfile_adapt/invoke_named_routes.txt @@ -0,0 +1,154 @@ +&(first) { + @first path /first + vars @first first 1 + respond "first" +} + +&(second) { + respond "second" +} + +:8881 { + invoke first + route { + invoke second + } +} + +:8882 { + handle { + invoke second + } +} + +:8883 { + respond "no invoke" +} +---------- +{ + "apps": { + "http": { + "servers": { + "srv0": { + "listen": [ + ":8881" + ], + "routes": [ + { + "handle": [ + { + "handler": "invoke", + "name": "first" + }, + { + "handler": "subroute", + "routes": [ + { + "handle": [ + { + "handler": "invoke", + "name": "second" + } + ] + } + ] + } + ] + } + ], + "named_routes": { + "first": { + "handle": [ + { + "handler": "subroute", + "routes": [ + { + "handle": [ + { + "first": 1, + "handler": "vars" + } + ], + "match": [ + { + "path": [ + "/first" + ] + } + ] + }, + { + "handle": [ + { + "body": "first", + "handler": "static_response" + } + ] + } + ] + } + ] + }, + "second": { + "handle": [ + { + "body": "second", + "handler": "static_response" + } + ] + } + } + }, + "srv1": { + "listen": [ + ":8882" + ], + "routes": [ + { + "handle": [ + { + "handler": "subroute", + "routes": [ + { + "handle": [ + { + "handler": "invoke", + "name": "second" + } + ] + } + ] + } + ] + } + ], + "named_routes": { + "second": { + "handle": [ + { + "body": "second", + "handler": "static_response" + } + ] + } + } + }, + "srv2": { + "listen": [ + ":8883" + ], + "routes": [ + { + "handle": [ + { + "body": "no invoke", + "handler": "static_response" + } + ] + } + ] + } + } + } + } +} \ No newline at end of file -- cgit v1.2.3 From 3b19aa2b5a77440f8cb4d11e80937935d187f1cd Mon Sep 17 00:00:00 2001 From: Francis Lavoie Date: Thu, 15 Jun 2023 19:18:55 -0400 Subject: headers: Allow `>` to defer shortcut for replacements (#5574) --- caddytest/integration/caddyfile_adapt/header.txt | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'caddytest') diff --git a/caddytest/integration/caddyfile_adapt/header.txt b/caddytest/integration/caddyfile_adapt/header.txt index 95c1474..ec2a842 100644 --- a/caddytest/integration/caddyfile_adapt/header.txt +++ b/caddytest/integration/caddyfile_adapt/header.txt @@ -18,6 +18,7 @@ +Link "Bar" } header >Set Defer + header >Replace Deferred Replacement } ---------- { @@ -148,6 +149,20 @@ ] } } + }, + { + "handler": "headers", + "response": { + "deferred": true, + "replace": { + "Replace": [ + { + "replace": "Replacement", + "search_regexp": "Deferred" + } + ] + } + } } ] } -- cgit v1.2.3 From 361946eb0c08791ad16ebc3e82a79512895e650f Mon Sep 17 00:00:00 2001 From: Saber Haj Rabiee Date: Tue, 20 Jun 2023 10:42:58 -0700 Subject: reverseproxy: weighted_round_robin load balancing policy (#5579) * added weighted round robin algorithm to load balancer * added an adapt integration test for wrr and fixed a typo * changed args format to Caddyfile args convention * added provisioner and validator for wrr * simplified the code and improved doc --- .../reverse_proxy_load_balance_wrr.txt | 71 ++++++++++++++++++++++ 1 file changed, 71 insertions(+) create mode 100644 caddytest/integration/caddyfile_adapt/reverse_proxy_load_balance_wrr.txt (limited to 'caddytest') diff --git a/caddytest/integration/caddyfile_adapt/reverse_proxy_load_balance_wrr.txt b/caddytest/integration/caddyfile_adapt/reverse_proxy_load_balance_wrr.txt new file mode 100644 index 0000000..d41c4b8 --- /dev/null +++ b/caddytest/integration/caddyfile_adapt/reverse_proxy_load_balance_wrr.txt @@ -0,0 +1,71 @@ +:8884 + +reverse_proxy 127.0.0.1:65535 127.0.0.1:35535 { + lb_policy weighted_round_robin 10 1 + lb_retries 5 + lb_try_duration 10s + lb_try_interval 500ms + lb_retry_match { + path /foo* + method POST + } + lb_retry_match path /bar* +} +---------- +{ + "apps": { + "http": { + "servers": { + "srv0": { + "listen": [ + ":8884" + ], + "routes": [ + { + "handle": [ + { + "handler": "reverse_proxy", + "load_balancing": { + "retries": 5, + "retry_match": [ + { + "method": [ + "POST" + ], + "path": [ + "/foo*" + ] + }, + { + "path": [ + "/bar*" + ] + } + ], + "selection_policy": { + "policy": "weighted_round_robin", + "weights": [ + 10, + 1 + ] + }, + "try_duration": 10000000000, + "try_interval": 500000000 + }, + "upstreams": [ + { + "dial": "127.0.0.1:65535" + }, + { + "dial": "127.0.0.1:35535" + } + ] + } + ] + } + ] + } + } + } + } +} -- cgit v1.2.3 From 5c51c1db2ce450a3fa003834097ad010b3844673 Mon Sep 17 00:00:00 2001 From: Francis Lavoie Date: Wed, 2 Aug 2023 03:13:46 -0400 Subject: httpcaddyfile: Allow `hostnames` & logger name overrides for log directive (#5643) * httpcaddyfile: Allow `hostnames` override for log directive * Implement access logger name overrides * Fix panic & default logger clobbering edgecase --- .../caddyfile_adapt/log_override_hostname.txt | 71 +++++++++++++++++ .../log_override_name_multiaccess.txt | 86 ++++++++++++++++++++ .../log_override_name_multiaccess_debug.txt | 91 ++++++++++++++++++++++ 3 files changed, 248 insertions(+) create mode 100644 caddytest/integration/caddyfile_adapt/log_override_hostname.txt create mode 100644 caddytest/integration/caddyfile_adapt/log_override_name_multiaccess.txt create mode 100644 caddytest/integration/caddyfile_adapt/log_override_name_multiaccess_debug.txt (limited to 'caddytest') diff --git a/caddytest/integration/caddyfile_adapt/log_override_hostname.txt b/caddytest/integration/caddyfile_adapt/log_override_hostname.txt new file mode 100644 index 0000000..4511fd4 --- /dev/null +++ b/caddytest/integration/caddyfile_adapt/log_override_hostname.txt @@ -0,0 +1,71 @@ +*.example.com { + log { + hostnames foo.example.com bar.example.com + output file /foo-bar.txt + } + log { + hostnames baz.example.com + output file /baz.txt + } +} +---------- +{ + "logging": { + "logs": { + "default": { + "exclude": [ + "http.log.access.log0", + "http.log.access.log1" + ] + }, + "log0": { + "writer": { + "filename": "/foo-bar.txt", + "output": "file" + }, + "include": [ + "http.log.access.log0" + ] + }, + "log1": { + "writer": { + "filename": "/baz.txt", + "output": "file" + }, + "include": [ + "http.log.access.log1" + ] + } + } + }, + "apps": { + "http": { + "servers": { + "srv0": { + "listen": [ + ":443" + ], + "routes": [ + { + "match": [ + { + "host": [ + "*.example.com" + ] + } + ], + "terminal": true + } + ], + "logs": { + "logger_names": { + "bar.example.com": "log0", + "baz.example.com": "log1", + "foo.example.com": "log0" + } + } + } + } + } + } +} \ No newline at end of file diff --git a/caddytest/integration/caddyfile_adapt/log_override_name_multiaccess.txt b/caddytest/integration/caddyfile_adapt/log_override_name_multiaccess.txt new file mode 100644 index 0000000..a3b0cec --- /dev/null +++ b/caddytest/integration/caddyfile_adapt/log_override_name_multiaccess.txt @@ -0,0 +1,86 @@ +{ + log access-console { + include http.log.access.foo + output file access-localhost.log + format console + } + + log access-json { + include http.log.access.foo + output file access-localhost.json + format json + } +} + +http://localhost:8881 { + log foo +} +---------- +{ + "logging": { + "logs": { + "access-console": { + "writer": { + "filename": "access-localhost.log", + "output": "file" + }, + "encoder": { + "format": "console" + }, + "include": [ + "http.log.access.foo" + ] + }, + "access-json": { + "writer": { + "filename": "access-localhost.json", + "output": "file" + }, + "encoder": { + "format": "json" + }, + "include": [ + "http.log.access.foo" + ] + }, + "default": { + "exclude": [ + "http.log.access.foo" + ] + } + } + }, + "apps": { + "http": { + "servers": { + "srv0": { + "listen": [ + ":8881" + ], + "routes": [ + { + "match": [ + { + "host": [ + "localhost" + ] + } + ], + "terminal": true + } + ], + "automatic_https": { + "skip": [ + "localhost" + ] + }, + "logs": { + "logger_names": { + "localhost:8881": "foo" + } + } + } + } + } + } +} \ No newline at end of file diff --git a/caddytest/integration/caddyfile_adapt/log_override_name_multiaccess_debug.txt b/caddytest/integration/caddyfile_adapt/log_override_name_multiaccess_debug.txt new file mode 100644 index 0000000..e6698e4 --- /dev/null +++ b/caddytest/integration/caddyfile_adapt/log_override_name_multiaccess_debug.txt @@ -0,0 +1,91 @@ +{ + debug + + log access-console { + include http.log.access.foo + output file access-localhost.log + format console + } + + log access-json { + include http.log.access.foo + output file access-localhost.json + format json + } +} + +http://localhost:8881 { + log foo +} +---------- +{ + "logging": { + "logs": { + "access-console": { + "writer": { + "filename": "access-localhost.log", + "output": "file" + }, + "encoder": { + "format": "console" + }, + "level": "DEBUG", + "include": [ + "http.log.access.foo" + ] + }, + "access-json": { + "writer": { + "filename": "access-localhost.json", + "output": "file" + }, + "encoder": { + "format": "json" + }, + "level": "DEBUG", + "include": [ + "http.log.access.foo" + ] + }, + "default": { + "level": "DEBUG", + "exclude": [ + "http.log.access.foo" + ] + } + } + }, + "apps": { + "http": { + "servers": { + "srv0": { + "listen": [ + ":8881" + ], + "routes": [ + { + "match": [ + { + "host": [ + "localhost" + ] + } + ], + "terminal": true + } + ], + "automatic_https": { + "skip": [ + "localhost" + ] + }, + "logs": { + "logger_names": { + "localhost:8881": "foo" + } + } + } + } + } + } +} \ No newline at end of file -- cgit v1.2.3 From cd486c25d168caf58f4b6fe5d3252df9432901ec Mon Sep 17 00:00:00 2001 From: Francis Lavoie Date: Wed, 2 Aug 2023 16:03:26 -0400 Subject: caddyhttp: Make use of `http.ResponseController` (#5654) * caddyhttp: Make use of http.ResponseController Also syncs the reverseproxy implementation with stdlib's which now uses ResponseController as well https://github.com/golang/go/commit/2449bbb5e614954ce9e99c8a481ea2ee73d72d61 * Enable full-duplex for HTTP/1.1 * Appease linter * Add warning for builds with Go 1.20, so it's less surprising to users * Improved godoc for EnableFullDuplex, copied text from stdlib * Only wrap in encode if not already wrapped --- .../integration/caddyfile_adapt/global_server_options_single.txt | 2 ++ caddytest/integration/stream_test.go | 4 +--- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'caddytest') diff --git a/caddytest/integration/caddyfile_adapt/global_server_options_single.txt b/caddytest/integration/caddyfile_adapt/global_server_options_single.txt index 300b4ac..2f3306f 100644 --- a/caddytest/integration/caddyfile_adapt/global_server_options_single.txt +++ b/caddytest/integration/caddyfile_adapt/global_server_options_single.txt @@ -11,6 +11,7 @@ idle 30s } max_header_size 100MB + enable_full_duplex log_credentials protocols h1 h2 h2c h3 strict_sni_host @@ -45,6 +46,7 @@ foo.com { "write_timeout": 30000000000, "idle_timeout": 30000000000, "max_header_bytes": 100000000, + "enable_full_duplex": true, "routes": [ { "match": [ diff --git a/caddytest/integration/stream_test.go b/caddytest/integration/stream_test.go index 09d4f64..6bc612d 100644 --- a/caddytest/integration/stream_test.go +++ b/caddytest/integration/stream_test.go @@ -176,9 +176,7 @@ func testH2ToH2CStreamServeH2C(t *testing.T) *http.Server { w.Header().Set("Cache-Control", "no-store") w.WriteHeader(200) - if f, ok := w.(http.Flusher); ok { - f.Flush() - } + http.NewResponseController(w).Flush() buf := make([]byte, 4*1024) -- cgit v1.2.3 From 65e33fc1ee4798bb3450f6e291bfc88404982636 Mon Sep 17 00:00:00 2001 From: Mohammed Al Sahaf Date: Sat, 5 Aug 2023 23:30:02 +0200 Subject: reverseproxy: do not parse upstream address too early if it contains replaceble parts (#5695) * reverseproxy: do not parse upstream address too early if it contains replaceble parts * remove unused method * cleanup * accommodate partially replaceable port --- .../caddyfile_adapt/replaceable_upstream.txt | 100 +++++++++++++++++++++ .../replaceable_upstream_partial_port.txt | 100 +++++++++++++++++++++ .../caddyfile_adapt/replaceable_upstream_port.txt | 100 +++++++++++++++++++++ 3 files changed, 300 insertions(+) create mode 100644 caddytest/integration/caddyfile_adapt/replaceable_upstream.txt create mode 100644 caddytest/integration/caddyfile_adapt/replaceable_upstream_partial_port.txt create mode 100644 caddytest/integration/caddyfile_adapt/replaceable_upstream_port.txt (limited to 'caddytest') diff --git a/caddytest/integration/caddyfile_adapt/replaceable_upstream.txt b/caddytest/integration/caddyfile_adapt/replaceable_upstream.txt new file mode 100644 index 0000000..202e330 --- /dev/null +++ b/caddytest/integration/caddyfile_adapt/replaceable_upstream.txt @@ -0,0 +1,100 @@ +*.sandbox.localhost { + @sandboxPort { + header_regexp first_label Host ^([0-9]{3})\.sandbox\. + } + handle @sandboxPort { + reverse_proxy {re.first_label.1} + } + handle { + redir {scheme}://application.localhost + } +} + +---------- +{ + "apps": { + "http": { + "servers": { + "srv0": { + "listen": [ + ":443" + ], + "routes": [ + { + "match": [ + { + "host": [ + "*.sandbox.localhost" + ] + } + ], + "handle": [ + { + "handler": "subroute", + "routes": [ + { + "group": "group2", + "handle": [ + { + "handler": "subroute", + "routes": [ + { + "handle": [ + { + "handler": "reverse_proxy", + "upstreams": [ + { + "dial": "{http.regexp.first_label.1}" + } + ] + } + ] + } + ] + } + ], + "match": [ + { + "header_regexp": { + "Host": { + "name": "first_label", + "pattern": "^([0-9]{3})\\.sandbox\\." + } + } + } + ] + }, + { + "group": "group2", + "handle": [ + { + "handler": "subroute", + "routes": [ + { + "handle": [ + { + "handler": "static_response", + "headers": { + "Location": [ + "{http.request.scheme}://application.localhost" + ] + }, + "status_code": 302 + } + ] + } + ] + } + ] + } + ] + } + ], + "terminal": true + } + ] + } + } + } + } +} \ No newline at end of file diff --git a/caddytest/integration/caddyfile_adapt/replaceable_upstream_partial_port.txt b/caddytest/integration/caddyfile_adapt/replaceable_upstream_partial_port.txt new file mode 100644 index 0000000..7fbcb5c --- /dev/null +++ b/caddytest/integration/caddyfile_adapt/replaceable_upstream_partial_port.txt @@ -0,0 +1,100 @@ +*.sandbox.localhost { + @sandboxPort { + header_regexp port Host ^([0-9]{3})\.sandbox\. + } + handle @sandboxPort { + reverse_proxy app:6{re.port.1} + } + handle { + redir {scheme}://application.localhost + } +} + +---------- +{ + "apps": { + "http": { + "servers": { + "srv0": { + "listen": [ + ":443" + ], + "routes": [ + { + "match": [ + { + "host": [ + "*.sandbox.localhost" + ] + } + ], + "handle": [ + { + "handler": "subroute", + "routes": [ + { + "group": "group2", + "handle": [ + { + "handler": "subroute", + "routes": [ + { + "handle": [ + { + "handler": "reverse_proxy", + "upstreams": [ + { + "dial": "app:6{http.regexp.port.1}" + } + ] + } + ] + } + ] + } + ], + "match": [ + { + "header_regexp": { + "Host": { + "name": "port", + "pattern": "^([0-9]{3})\\.sandbox\\." + } + } + } + ] + }, + { + "group": "group2", + "handle": [ + { + "handler": "subroute", + "routes": [ + { + "handle": [ + { + "handler": "static_response", + "headers": { + "Location": [ + "{http.request.scheme}://application.localhost" + ] + }, + "status_code": 302 + } + ] + } + ] + } + ] + } + ] + } + ], + "terminal": true + } + ] + } + } + } + } +} \ No newline at end of file diff --git a/caddytest/integration/caddyfile_adapt/replaceable_upstream_port.txt b/caddytest/integration/caddyfile_adapt/replaceable_upstream_port.txt new file mode 100644 index 0000000..8f75c5b --- /dev/null +++ b/caddytest/integration/caddyfile_adapt/replaceable_upstream_port.txt @@ -0,0 +1,100 @@ +*.sandbox.localhost { + @sandboxPort { + header_regexp port Host ^([0-9]{3})\.sandbox\. + } + handle @sandboxPort { + reverse_proxy app:{re.port.1} + } + handle { + redir {scheme}://application.localhost + } +} + +---------- +{ + "apps": { + "http": { + "servers": { + "srv0": { + "listen": [ + ":443" + ], + "routes": [ + { + "match": [ + { + "host": [ + "*.sandbox.localhost" + ] + } + ], + "handle": [ + { + "handler": "subroute", + "routes": [ + { + "group": "group2", + "handle": [ + { + "handler": "subroute", + "routes": [ + { + "handle": [ + { + "handler": "reverse_proxy", + "upstreams": [ + { + "dial": "app:{http.regexp.port.1}" + } + ] + } + ] + } + ] + } + ], + "match": [ + { + "header_regexp": { + "Host": { + "name": "port", + "pattern": "^([0-9]{3})\\.sandbox\\." + } + } + } + ] + }, + { + "group": "group2", + "handle": [ + { + "handler": "subroute", + "routes": [ + { + "handle": [ + { + "handler": "static_response", + "headers": { + "Location": [ + "{http.request.scheme}://application.localhost" + ] + }, + "status_code": 302 + } + ] + } + ] + } + ] + } + ] + } + ], + "terminal": true + } + ] + } + } + } + } +} \ No newline at end of file -- cgit v1.2.3 From b32f265ecad60404c3818cc9d42e367a8e4eb7d4 Mon Sep 17 00:00:00 2001 From: Jacob Gadikian Date: Tue, 8 Aug 2023 03:40:31 +0800 Subject: ci: Use gofumpt to format code (#5707) --- caddytest/caddytest.go | 16 ---------------- 1 file changed, 16 deletions(-) (limited to 'caddytest') diff --git a/caddytest/caddytest.go b/caddytest/caddytest.go index 0958e6c..4966548 100644 --- a/caddytest/caddytest.go +++ b/caddytest/caddytest.go @@ -63,7 +63,6 @@ type Tester struct { // NewTester will create a new testing client with an attached cookie jar func NewTester(t *testing.T) *Tester { - jar, err := cookiejar.New(nil) if err != nil { t.Fatalf("failed to create cookiejar: %s", err) @@ -94,7 +93,6 @@ func timeElapsed(start time.Time, name string) { // InitServer this will configure the server with a configurion of a specific // type. The configType must be either "json" or the adapter type. func (tc *Tester) InitServer(rawConfig string, configType string) { - if err := tc.initServer(rawConfig, configType); err != nil { tc.t.Logf("failed to load config: %s", err) tc.t.Fail() @@ -108,7 +106,6 @@ func (tc *Tester) InitServer(rawConfig string, configType string) { // InitServer this will configure the server with a configurion of a specific // type. The configType must be either "json" or the adapter type. func (tc *Tester) initServer(rawConfig string, configType string) error { - if testing.Short() { tc.t.SkipNow() return nil @@ -232,7 +229,6 @@ const initConfig = `{ // validateTestPrerequisites ensures the certificates are available in the // designated path and Caddy sub-process is running. func validateTestPrerequisites(t *testing.T) error { - // check certificates are found for _, certName := range Default.Certifcates { if _, err := os.Stat(getIntegrationDir() + certName); os.IsNotExist(err) { @@ -284,7 +280,6 @@ func isCaddyAdminRunning() error { } func getIntegrationDir() string { - _, filename, _, ok := runtime.Caller(1) if !ok { panic("unable to determine the current file path") @@ -304,7 +299,6 @@ func prependCaddyFilePath(rawConfig string) string { // CreateTestingTransport creates a testing transport that forces call dialing connections to happen locally func CreateTestingTransport() *http.Transport { - dialer := net.Dialer{ Timeout: 5 * time.Second, KeepAlive: 5 * time.Second, @@ -332,7 +326,6 @@ func CreateTestingTransport() *http.Transport { // AssertLoadError will load a config and expect an error func AssertLoadError(t *testing.T, rawConfig string, configType string, expectedError string) { - tc := NewTester(t) err := tc.initServer(rawConfig, configType) @@ -343,7 +336,6 @@ func AssertLoadError(t *testing.T, rawConfig string, configType string, expected // AssertRedirect makes a request and asserts the redirection happens func (tc *Tester) AssertRedirect(requestURI string, expectedToLocation string, expectedStatusCode int) *http.Response { - redirectPolicyFunc := func(req *http.Request, via []*http.Request) error { return http.ErrUseLastResponse } @@ -381,7 +373,6 @@ func (tc *Tester) AssertRedirect(requestURI string, expectedToLocation string, e // CompareAdapt adapts a config and then compares it against an expected result func CompareAdapt(t *testing.T, filename, rawConfig string, adapterName string, expectedResponse string) bool { - cfgAdapter := caddyconfig.GetAdapter(adapterName) if cfgAdapter == nil { t.Logf("unrecognized config adapter '%s'", adapterName) @@ -469,7 +460,6 @@ func applyHeaders(t *testing.T, req *http.Request, requestHeaders []string) { // AssertResponseCode will execute the request and verify the status code, returns a response for additional assertions func (tc *Tester) AssertResponseCode(req *http.Request, expectedStatusCode int) *http.Response { - resp, err := tc.Client.Do(req) if err != nil { tc.t.Fatalf("failed to call server %s", err) @@ -484,7 +474,6 @@ func (tc *Tester) AssertResponseCode(req *http.Request, expectedStatusCode int) // AssertResponse request a URI and assert the status code and the body contains a string func (tc *Tester) AssertResponse(req *http.Request, expectedStatusCode int, expectedBody string) (*http.Response, string) { - resp := tc.AssertResponseCode(req, expectedStatusCode) defer resp.Body.Close() @@ -506,7 +495,6 @@ func (tc *Tester) AssertResponse(req *http.Request, expectedStatusCode int, expe // AssertGetResponse GET a URI and expect a statusCode and body text func (tc *Tester) AssertGetResponse(requestURI string, expectedStatusCode int, expectedBody string) (*http.Response, string) { - req, err := http.NewRequest("GET", requestURI, nil) if err != nil { tc.t.Fatalf("unable to create request %s", err) @@ -517,7 +505,6 @@ func (tc *Tester) AssertGetResponse(requestURI string, expectedStatusCode int, e // AssertDeleteResponse request a URI and expect a statusCode and body text func (tc *Tester) AssertDeleteResponse(requestURI string, expectedStatusCode int, expectedBody string) (*http.Response, string) { - req, err := http.NewRequest("DELETE", requestURI, nil) if err != nil { tc.t.Fatalf("unable to create request %s", err) @@ -528,7 +515,6 @@ func (tc *Tester) AssertDeleteResponse(requestURI string, expectedStatusCode int // AssertPostResponseBody POST to a URI and assert the response code and body func (tc *Tester) AssertPostResponseBody(requestURI string, requestHeaders []string, requestBody *bytes.Buffer, expectedStatusCode int, expectedBody string) (*http.Response, string) { - req, err := http.NewRequest("POST", requestURI, requestBody) if err != nil { tc.t.Errorf("failed to create request %s", err) @@ -542,7 +528,6 @@ func (tc *Tester) AssertPostResponseBody(requestURI string, requestHeaders []str // AssertPutResponseBody PUT to a URI and assert the response code and body func (tc *Tester) AssertPutResponseBody(requestURI string, requestHeaders []string, requestBody *bytes.Buffer, expectedStatusCode int, expectedBody string) (*http.Response, string) { - req, err := http.NewRequest("PUT", requestURI, requestBody) if err != nil { tc.t.Errorf("failed to create request %s", err) @@ -556,7 +541,6 @@ func (tc *Tester) AssertPutResponseBody(requestURI string, requestHeaders []stri // AssertPatchResponseBody PATCH to a URI and assert the response code and body func (tc *Tester) AssertPatchResponseBody(requestURI string, requestHeaders []string, requestBody *bytes.Buffer, expectedStatusCode int, expectedBody string) (*http.Response, string) { - req, err := http.NewRequest("PATCH", requestURI, requestBody) if err != nil { tc.t.Errorf("failed to create request %s", err) -- cgit v1.2.3 From 11166889c5231213c9df7d202a811d1748036129 Mon Sep 17 00:00:00 2001 From: Matthew Holt Date: Wed, 9 Aug 2023 11:25:59 -0600 Subject: Fix tests I thought Go ordered JSON objects when marshaling, but I guess not. --- caddytest/integration/caddyfile_adapt/global_options.txt | 4 ++-- caddytest/integration/caddyfile_adapt/global_options_acme.txt | 4 ++-- caddytest/integration/caddyfile_adapt/global_options_admin.txt | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) (limited to 'caddytest') diff --git a/caddytest/integration/caddyfile_adapt/global_options.txt b/caddytest/integration/caddyfile_adapt/global_options.txt index 57831a4..6032098 100644 --- a/caddytest/integration/caddyfile_adapt/global_options.txt +++ b/caddytest/integration/caddyfile_adapt/global_options.txt @@ -69,11 +69,11 @@ } ], "on_demand": { + "ask": "https://example.com", "rate_limit": { "interval": 30000000000, "burst": 20 - }, - "ask": "https://example.com" + } } }, "disable_ocsp_stapling": true diff --git a/caddytest/integration/caddyfile_adapt/global_options_acme.txt b/caddytest/integration/caddyfile_adapt/global_options_acme.txt index 1949d17..03aee2c 100644 --- a/caddytest/integration/caddyfile_adapt/global_options_acme.txt +++ b/caddytest/integration/caddyfile_adapt/global_options_acme.txt @@ -78,11 +78,11 @@ } ], "on_demand": { + "ask": "https://example.com", "rate_limit": { "interval": 30000000000, "burst": 20 - }, - "ask": "https://example.com" + } }, "ocsp_interval": 172800000000000, "renew_interval": 86400000000000, diff --git a/caddytest/integration/caddyfile_adapt/global_options_admin.txt b/caddytest/integration/caddyfile_adapt/global_options_admin.txt index 67cf5ad..2b90d6d 100644 --- a/caddytest/integration/caddyfile_adapt/global_options_admin.txt +++ b/caddytest/integration/caddyfile_adapt/global_options_admin.txt @@ -71,11 +71,11 @@ } ], "on_demand": { + "ask": "https://example.com", "rate_limit": { "interval": 30000000000, "burst": 20 - }, - "ask": "https://example.com" + } } } } -- cgit v1.2.3 From d6f86cccf5fa5b4eb30141da390cf2439746c5da Mon Sep 17 00:00:00 2001 From: Jacob Gadikian Date: Mon, 14 Aug 2023 23:41:15 +0800 Subject: ci: use gci linter (#5708) * use gofmput to format code * use gci to format imports * reconfigure gci * linter autofixes * rearrange imports a little * export GOOS=windows golangci-lint run ./... --fix --- caddytest/caddytest.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'caddytest') diff --git a/caddytest/caddytest.go b/caddytest/caddytest.go index 4966548..9c17070 100644 --- a/caddytest/caddytest.go +++ b/caddytest/caddytest.go @@ -22,9 +22,10 @@ import ( "time" "github.com/aryann/difflib" - "github.com/caddyserver/caddy/v2/caddyconfig" + caddycmd "github.com/caddyserver/caddy/v2/cmd" + "github.com/caddyserver/caddy/v2/caddyconfig" // plug in Caddy modules here _ "github.com/caddyserver/caddy/v2/modules/standard" ) -- cgit v1.2.3 From 288216e1fbf25ebe11fcea7c71be526c4cd0dcce Mon Sep 17 00:00:00 2001 From: Karun Agarwal <113603846+singhalkarun@users.noreply.github.com> Date: Sat, 19 Aug 2023 16:58:25 +0530 Subject: httpcaddyfile: Stricter errors for site and upstream address schemes (#5757) Co-authored-by: Mohammed Al Sahaf Co-authored-by: Francis Lavoie --- caddytest/integration/caddyfile_test.go | 349 ++++++++++++++++++++++++++++++++ 1 file changed, 349 insertions(+) (limited to 'caddytest') diff --git a/caddytest/integration/caddyfile_test.go b/caddytest/integration/caddyfile_test.go index 3f3ba0a..205bc5b 100644 --- a/caddytest/integration/caddyfile_test.go +++ b/caddytest/integration/caddyfile_test.go @@ -135,3 +135,352 @@ func TestReplIndex(t *testing.T) { // act and assert tester.AssertGetResponse("http://localhost:9080/", 200, "") } + +func TestInvalidPrefix(t *testing.T) { + type testCase struct { + config, expectedError string + } + + failureCases := []testCase{ + { + config: `wss://localhost`, + expectedError: `the scheme wss:// is only supported in browsers; use https:// instead`, + }, + { + config: `ws://localhost`, + expectedError: `the scheme ws:// is only supported in browsers; use http:// instead`, + }, + { + config: `someInvalidPrefix://localhost`, + expectedError: "unsupported URL scheme someinvalidprefix://", + }, + { + config: `h2c://localhost`, + expectedError: `unsupported URL scheme h2c://`, + }, + { + config: `localhost, wss://localhost`, + expectedError: `the scheme wss:// is only supported in browsers; use https:// instead`, + }, + { + config: `localhost { + reverse_proxy ws://localhost" + }`, + expectedError: `the scheme ws:// is only supported in browsers; use http:// instead`, + }, + { + config: `localhost { + reverse_proxy someInvalidPrefix://localhost" + }`, + expectedError: `unsupported URL scheme someinvalidprefix://`, + }, + } + + for _, failureCase := range failureCases { + caddytest.AssertLoadError(t, failureCase.config, "caddyfile", failureCase.expectedError) + } +} + +func TestValidPrefix(t *testing.T) { + type testCase struct { + rawConfig, expectedResponse string + } + + successCases := []testCase{ + { + "localhost", + `{ + "apps": { + "http": { + "servers": { + "srv0": { + "listen": [ + ":443" + ], + "routes": [ + { + "match": [ + { + "host": [ + "localhost" + ] + } + ], + "terminal": true + } + ] + } + } + } + } +}`, + }, + { + "https://localhost", + `{ + "apps": { + "http": { + "servers": { + "srv0": { + "listen": [ + ":443" + ], + "routes": [ + { + "match": [ + { + "host": [ + "localhost" + ] + } + ], + "terminal": true + } + ] + } + } + } + } +}`, + }, + { + "http://localhost", + `{ + "apps": { + "http": { + "servers": { + "srv0": { + "listen": [ + ":80" + ], + "routes": [ + { + "match": [ + { + "host": [ + "localhost" + ] + } + ], + "terminal": true + } + ] + } + } + } + } +}`, + }, + { + `localhost { + reverse_proxy http://localhost:3000 + }`, + `{ + "apps": { + "http": { + "servers": { + "srv0": { + "listen": [ + ":443" + ], + "routes": [ + { + "match": [ + { + "host": [ + "localhost" + ] + } + ], + "handle": [ + { + "handler": "subroute", + "routes": [ + { + "handle": [ + { + "handler": "reverse_proxy", + "upstreams": [ + { + "dial": "localhost:3000" + } + ] + } + ] + } + ] + } + ], + "terminal": true + } + ] + } + } + } + } +}`, + }, + { + `localhost { + reverse_proxy https://localhost:3000 + }`, + `{ + "apps": { + "http": { + "servers": { + "srv0": { + "listen": [ + ":443" + ], + "routes": [ + { + "match": [ + { + "host": [ + "localhost" + ] + } + ], + "handle": [ + { + "handler": "subroute", + "routes": [ + { + "handle": [ + { + "handler": "reverse_proxy", + "transport": { + "protocol": "http", + "tls": {} + }, + "upstreams": [ + { + "dial": "localhost:3000" + } + ] + } + ] + } + ] + } + ], + "terminal": true + } + ] + } + } + } + } +}`, + }, + { + `localhost { + reverse_proxy h2c://localhost:3000 + }`, + `{ + "apps": { + "http": { + "servers": { + "srv0": { + "listen": [ + ":443" + ], + "routes": [ + { + "match": [ + { + "host": [ + "localhost" + ] + } + ], + "handle": [ + { + "handler": "subroute", + "routes": [ + { + "handle": [ + { + "handler": "reverse_proxy", + "transport": { + "protocol": "http", + "versions": [ + "h2c", + "2" + ] + }, + "upstreams": [ + { + "dial": "localhost:3000" + } + ] + } + ] + } + ] + } + ], + "terminal": true + } + ] + } + } + } + } +}`, + }, + { + `localhost { + reverse_proxy localhost:3000 + }`, + `{ + "apps": { + "http": { + "servers": { + "srv0": { + "listen": [ + ":443" + ], + "routes": [ + { + "match": [ + { + "host": [ + "localhost" + ] + } + ], + "handle": [ + { + "handler": "subroute", + "routes": [ + { + "handle": [ + { + "handler": "reverse_proxy", + "upstreams": [ + { + "dial": "localhost:3000" + } + ] + } + ] + } + ] + } + ], + "terminal": true + } + ] + } + } + } + } +}`, + }, + } + + for _, successCase := range successCases { + caddytest.AssertAdapt(t, successCase.rawConfig, "caddyfile", successCase.expectedResponse) + } +} -- cgit v1.2.3 From 82c356f2548ca62b75f76104bef44915482e8fd9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Mon, 2 Oct 2023 22:55:09 +0200 Subject: fix: caddytest.AssertResponseCode error message (#5853) --- caddytest/caddytest.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'caddytest') diff --git a/caddytest/caddytest.go b/caddytest/caddytest.go index 9c17070..39aca23 100644 --- a/caddytest/caddytest.go +++ b/caddytest/caddytest.go @@ -467,7 +467,7 @@ func (tc *Tester) AssertResponseCode(req *http.Request, expectedStatusCode int) } if expectedStatusCode != resp.StatusCode { - tc.t.Errorf("requesting \"%s\" expected status code: %d but got %d", req.RequestURI, expectedStatusCode, resp.StatusCode) + tc.t.Errorf("requesting \"%s\" expected status code: %d but got %d", req.URL.RequestURI(), expectedStatusCode, resp.StatusCode) } return resp -- cgit v1.2.3 From e0aaefab80d75293783a5551b094cf57b49da8d5 Mon Sep 17 00:00:00 2001 From: Christoph Date: Tue, 10 Oct 2023 23:18:37 +0200 Subject: encode: Add `application/wasm*` to the default content types (#5869) --- caddytest/integration/caddyfile_adapt/encode_options.txt | 2 ++ 1 file changed, 2 insertions(+) (limited to 'caddytest') diff --git a/caddytest/integration/caddyfile_adapt/encode_options.txt b/caddytest/integration/caddyfile_adapt/encode_options.txt index 6f811ab..181bc22 100644 --- a/caddytest/integration/caddyfile_adapt/encode_options.txt +++ b/caddytest/integration/caddyfile_adapt/encode_options.txt @@ -11,6 +11,7 @@ encode gzip zstd { header Content-Type application/xhtml+xml* header Content-Type application/atom+xml* header Content-Type application/rss+xml* + header Content-Type application/wasm* header Content-Type image/svg+xml* } } @@ -47,6 +48,7 @@ encode { "application/xhtml+xml*", "application/atom+xml*", "application/rss+xml*", + "application/wasm*", "image/svg+xml*" ] }, -- cgit v1.2.3 From df9950297793fbe3930cd3151b6f1a3cea893a38 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C4=90=E1=BB=97=20Tr=E1=BB=8Dng=20H=E1=BA=A3i?= <41283691+hainenber@users.noreply.github.com> Date: Wed, 11 Oct 2023 04:46:39 +0700 Subject: httpcaddyfile: Enable TLS for catch-all site if `tls` directive is specified (#5808) --- .../enable_tls_for_catch_all_site.txt | 37 ++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 caddytest/integration/caddyfile_adapt/enable_tls_for_catch_all_site.txt (limited to 'caddytest') diff --git a/caddytest/integration/caddyfile_adapt/enable_tls_for_catch_all_site.txt b/caddytest/integration/caddyfile_adapt/enable_tls_for_catch_all_site.txt new file mode 100644 index 0000000..b37b40c --- /dev/null +++ b/caddytest/integration/caddyfile_adapt/enable_tls_for_catch_all_site.txt @@ -0,0 +1,37 @@ +:8443 { + tls internal { + on_demand + } +} +---------- +{ + "apps": { + "http": { + "servers": { + "srv0": { + "listen": [ + ":8443" + ], + "tls_connection_policies": [ + {} + ] + } + } + }, + "tls": { + "automation": { + "policies": [ + { + "issuers": [ + { + "module": "internal" + } + ], + "on_demand": true + } + ] + } + } + } +} + -- cgit v1.2.3 From b245ecd325428966ac4e4c208e268967d0e0cb83 Mon Sep 17 00:00:00 2001 From: Fred Cox Date: Wed, 11 Oct 2023 09:42:40 +0100 Subject: reverseproxy: fix parsing Caddyfile fails for unlimited request/response buffers (#5828) --- .../caddyfile_adapt/reverse_proxy_buffers.txt | 58 ++++++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 caddytest/integration/caddyfile_adapt/reverse_proxy_buffers.txt (limited to 'caddytest') diff --git a/caddytest/integration/caddyfile_adapt/reverse_proxy_buffers.txt b/caddytest/integration/caddyfile_adapt/reverse_proxy_buffers.txt new file mode 100644 index 0000000..3178994 --- /dev/null +++ b/caddytest/integration/caddyfile_adapt/reverse_proxy_buffers.txt @@ -0,0 +1,58 @@ +https://example.com { + reverse_proxy https://localhost:54321 { + request_buffers unlimited + response_buffers unlimited + } +} + +---------- +{ + "apps": { + "http": { + "servers": { + "srv0": { + "listen": [ + ":443" + ], + "routes": [ + { + "match": [ + { + "host": [ + "example.com" + ] + } + ], + "handle": [ + { + "handler": "subroute", + "routes": [ + { + "handle": [ + { + "handler": "reverse_proxy", + "request_buffers": -1, + "response_buffers": -1, + "transport": { + "protocol": "http", + "tls": {} + }, + "upstreams": [ + { + "dial": "localhost:54321" + } + ] + } + ] + } + ] + } + ], + "terminal": true + } + ] + } + } + } + } +} -- cgit v1.2.3 From 05dbe1c171846b0b683dedbe2c4c20683e867ba0 Mon Sep 17 00:00:00 2001 From: Francis Lavoie Date: Wed, 11 Oct 2023 11:50:28 -0400 Subject: reverseproxy: Replace health header placeholders (#5861) --- .../caddyfile_adapt/reverse_proxy_health_headers.txt | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'caddytest') diff --git a/caddytest/integration/caddyfile_adapt/reverse_proxy_health_headers.txt b/caddytest/integration/caddyfile_adapt/reverse_proxy_health_headers.txt index 17adcaa..800c11f 100644 --- a/caddytest/integration/caddyfile_adapt/reverse_proxy_health_headers.txt +++ b/caddytest/integration/caddyfile_adapt/reverse_proxy_health_headers.txt @@ -6,6 +6,9 @@ reverse_proxy 127.0.0.1:65535 { X-Header-Key 95ca39e3cbe7 X-Header-Keys VbG4NZwWnipo 335Q9/MhqcNU3s2TO X-Empty-Value + Same-Key 1 + Same-Key 2 + X-System-Hostname {system.hostname} } health_uri /health } @@ -29,6 +32,10 @@ reverse_proxy 127.0.0.1:65535 { "Host": [ "example.com" ], + "Same-Key": [ + "1", + "2" + ], "X-Empty-Value": [ "" ], @@ -38,6 +45,9 @@ reverse_proxy 127.0.0.1:65535 { "X-Header-Keys": [ "VbG4NZwWnipo", "335Q9/MhqcNU3s2TO" + ], + "X-System-Hostname": [ + "{system.hostname}" ] }, "uri": "/health" -- cgit v1.2.3