| 
									
										
										
										
											2019-12-12 14:32:35 -07:00
										 |  |  | // Copyright 2015 Matthew Holt and The Caddy Authors | 
					
						
							|  |  |  | // | 
					
						
							|  |  |  | // Licensed under the Apache License, Version 2.0 (the "License"); | 
					
						
							|  |  |  | // you may not use this file except in compliance with the License. | 
					
						
							|  |  |  | // You may obtain a copy of the License at | 
					
						
							|  |  |  | // | 
					
						
							|  |  |  | //     http://www.apache.org/licenses/LICENSE-2.0 | 
					
						
							|  |  |  | // | 
					
						
							|  |  |  | // Unless required by applicable law or agreed to in writing, software | 
					
						
							|  |  |  | // distributed under the License is distributed on an "AS IS" BASIS, | 
					
						
							|  |  |  | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
					
						
							|  |  |  | // See the License for the specific language governing permissions and | 
					
						
							|  |  |  | // limitations under the License. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | package rewrite | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							|  |  |  | 	"net/http" | 
					
						
							| 
									
										
										
										
											2021-03-01 18:27:59 -07:00
										 |  |  | 	"regexp" | 
					
						
							| 
									
										
										
										
											2019-12-12 14:32:35 -07:00
										 |  |  | 	"testing" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	"github.com/caddyserver/caddy/v2" | 
					
						
							|  |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func TestRewrite(t *testing.T) { | 
					
						
							|  |  |  | 	repl := caddy.NewReplacer() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for i, tc := range []struct { | 
					
						
							|  |  |  | 		input, expect *http.Request | 
					
						
							|  |  |  | 		rule          Rewrite | 
					
						
							|  |  |  | 	}{ | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			input:  newRequest(t, "GET", "/"), | 
					
						
							|  |  |  | 			expect: newRequest(t, "GET", "/"), | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			rule:   Rewrite{Method: "GET", URI: "/"}, | 
					
						
							|  |  |  | 			input:  newRequest(t, "GET", "/"), | 
					
						
							|  |  |  | 			expect: newRequest(t, "GET", "/"), | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			rule:   Rewrite{Method: "POST"}, | 
					
						
							|  |  |  | 			input:  newRequest(t, "GET", "/"), | 
					
						
							|  |  |  | 			expect: newRequest(t, "POST", "/"), | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			rule:   Rewrite{URI: "/foo"}, | 
					
						
							|  |  |  | 			input:  newRequest(t, "GET", "/"), | 
					
						
							|  |  |  | 			expect: newRequest(t, "GET", "/foo"), | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			rule:   Rewrite{URI: "/foo"}, | 
					
						
							|  |  |  | 			input:  newRequest(t, "GET", "/bar"), | 
					
						
							|  |  |  | 			expect: newRequest(t, "GET", "/foo"), | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			rule:   Rewrite{URI: "foo"}, | 
					
						
							|  |  |  | 			input:  newRequest(t, "GET", "/"), | 
					
						
							|  |  |  | 			expect: newRequest(t, "GET", "foo"), | 
					
						
							|  |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2023-05-16 22:16:07 +07:00
										 |  |  | 		{ | 
					
						
							|  |  |  | 			rule:   Rewrite{URI: "{http.request.uri}"}, | 
					
						
							|  |  |  | 			input:  newRequest(t, "GET", "/bar%3Fbaz?c=d"), | 
					
						
							|  |  |  | 			expect: newRequest(t, "GET", "/bar%3Fbaz?c=d"), | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			rule:   Rewrite{URI: "{http.request.uri.path}"}, | 
					
						
							|  |  |  | 			input:  newRequest(t, "GET", "/bar%3Fbaz"), | 
					
						
							|  |  |  | 			expect: newRequest(t, "GET", "/bar%3Fbaz"), | 
					
						
							|  |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2019-12-12 14:32:35 -07:00
										 |  |  | 		{ | 
					
						
							|  |  |  | 			rule:   Rewrite{URI: "/foo{http.request.uri.path}"}, | 
					
						
							|  |  |  | 			input:  newRequest(t, "GET", "/bar"), | 
					
						
							|  |  |  | 			expect: newRequest(t, "GET", "/foo/bar"), | 
					
						
							|  |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2020-01-15 11:44:21 -07:00
										 |  |  | 		{ | 
					
						
							|  |  |  | 			rule:   Rewrite{URI: "/index.php?p={http.request.uri.path}"}, | 
					
						
							|  |  |  | 			input:  newRequest(t, "GET", "/foo/bar"), | 
					
						
							|  |  |  | 			expect: newRequest(t, "GET", "/index.php?p=%2Ffoo%2Fbar"), | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			rule:   Rewrite{URI: "?a=b&{http.request.uri.query}"}, | 
					
						
							|  |  |  | 			input:  newRequest(t, "GET", "/"), | 
					
						
							|  |  |  | 			expect: newRequest(t, "GET", "/?a=b"), | 
					
						
							|  |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2019-12-12 14:32:35 -07:00
										 |  |  | 		{ | 
					
						
							|  |  |  | 			rule:   Rewrite{URI: "/?c=d"}, | 
					
						
							|  |  |  | 			input:  newRequest(t, "GET", "/"), | 
					
						
							|  |  |  | 			expect: newRequest(t, "GET", "/?c=d"), | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			rule:   Rewrite{URI: "/?c=d"}, | 
					
						
							|  |  |  | 			input:  newRequest(t, "GET", "/?a=b"), | 
					
						
							|  |  |  | 			expect: newRequest(t, "GET", "/?c=d"), | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			rule:   Rewrite{URI: "?c=d"}, | 
					
						
							|  |  |  | 			input:  newRequest(t, "GET", "/foo"), | 
					
						
							|  |  |  | 			expect: newRequest(t, "GET", "/foo?c=d"), | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			rule:   Rewrite{URI: "/?c=d"}, | 
					
						
							|  |  |  | 			input:  newRequest(t, "GET", "/foo"), | 
					
						
							|  |  |  | 			expect: newRequest(t, "GET", "/?c=d"), | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			rule:   Rewrite{URI: "/?{http.request.uri.query}&c=d"}, | 
					
						
							|  |  |  | 			input:  newRequest(t, "GET", "/"), | 
					
						
							|  |  |  | 			expect: newRequest(t, "GET", "/?c=d"), | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			rule:   Rewrite{URI: "/foo?{http.request.uri.query}&c=d"}, | 
					
						
							|  |  |  | 			input:  newRequest(t, "GET", "/"), | 
					
						
							|  |  |  | 			expect: newRequest(t, "GET", "/foo?c=d"), | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			rule:   Rewrite{URI: "?{http.request.uri.query}&c=d"}, | 
					
						
							|  |  |  | 			input:  newRequest(t, "GET", "/foo"), | 
					
						
							|  |  |  | 			expect: newRequest(t, "GET", "/foo?c=d"), | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			rule:   Rewrite{URI: "{http.request.uri.path}?{http.request.uri.query}&c=d"}, | 
					
						
							|  |  |  | 			input:  newRequest(t, "GET", "/foo"), | 
					
						
							|  |  |  | 			expect: newRequest(t, "GET", "/foo?c=d"), | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2020-01-10 16:59:57 -07:00
										 |  |  | 			rule:   Rewrite{URI: "{http.request.uri.path}?{http.request.uri.query}&c=d"}, | 
					
						
							| 
									
										
										
										
											2019-12-12 14:32:35 -07:00
										 |  |  | 			input:  newRequest(t, "GET", "/foo"), | 
					
						
							|  |  |  | 			expect: newRequest(t, "GET", "/foo?c=d"), | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			rule:   Rewrite{URI: "/index.php?{http.request.uri.query}&c=d"}, | 
					
						
							|  |  |  | 			input:  newRequest(t, "GET", "/foo"), | 
					
						
							|  |  |  | 			expect: newRequest(t, "GET", "/index.php?c=d"), | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			rule:   Rewrite{URI: "?a=b&c=d"}, | 
					
						
							|  |  |  | 			input:  newRequest(t, "GET", "/foo"), | 
					
						
							|  |  |  | 			expect: newRequest(t, "GET", "/foo?a=b&c=d"), | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			rule:   Rewrite{URI: "/index.php?{http.request.uri.query}&c=d"}, | 
					
						
							|  |  |  | 			input:  newRequest(t, "GET", "/?a=b"), | 
					
						
							|  |  |  | 			expect: newRequest(t, "GET", "/index.php?a=b&c=d"), | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			rule:   Rewrite{URI: "/index.php?c=d&{http.request.uri.query}"}, | 
					
						
							|  |  |  | 			input:  newRequest(t, "GET", "/?a=b"), | 
					
						
							| 
									
										
										
										
											2020-01-10 16:59:57 -07:00
										 |  |  | 			expect: newRequest(t, "GET", "/index.php?c=d&a=b"), | 
					
						
							| 
									
										
										
										
											2019-12-12 14:32:35 -07:00
										 |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			rule:   Rewrite{URI: "/index.php?{http.request.uri.query}&p={http.request.uri.path}"}, | 
					
						
							|  |  |  | 			input:  newRequest(t, "GET", "/foo/bar?a=b"), | 
					
						
							| 
									
										
										
										
											2019-12-17 16:30:26 -07:00
										 |  |  | 			expect: newRequest(t, "GET", "/index.php?a=b&p=%2Ffoo%2Fbar"), | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			rule:   Rewrite{URI: "{http.request.uri.path}?"}, | 
					
						
							|  |  |  | 			input:  newRequest(t, "GET", "/foo/bar?a=b&c=d"), | 
					
						
							|  |  |  | 			expect: newRequest(t, "GET", "/foo/bar"), | 
					
						
							| 
									
										
										
										
											2019-12-12 14:32:35 -07:00
										 |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2020-01-11 11:40:03 -07:00
										 |  |  | 		{ | 
					
						
							|  |  |  | 			rule:   Rewrite{URI: "?qs={http.request.uri.query}"}, | 
					
						
							|  |  |  | 			input:  newRequest(t, "GET", "/foo?a=b&c=d"), | 
					
						
							|  |  |  | 			expect: newRequest(t, "GET", "/foo?qs=a%3Db%26c%3Dd"), | 
					
						
							|  |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2020-01-10 16:59:57 -07:00
										 |  |  | 		{ | 
					
						
							|  |  |  | 			rule:   Rewrite{URI: "/foo?{http.request.uri.query}#frag"}, | 
					
						
							|  |  |  | 			input:  newRequest(t, "GET", "/foo/bar?a=b"), | 
					
						
							|  |  |  | 			expect: newRequest(t, "GET", "/foo?a=b#frag"), | 
					
						
							|  |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2020-04-01 00:43:40 -06:00
										 |  |  | 		{ | 
					
						
							|  |  |  | 			rule:   Rewrite{URI: "/foo{http.request.uri}"}, | 
					
						
							|  |  |  | 			input:  newRequest(t, "GET", "/bar?a=b"), | 
					
						
							|  |  |  | 			expect: newRequest(t, "GET", "/foo/bar?a=b"), | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			rule:   Rewrite{URI: "/foo{http.request.uri}"}, | 
					
						
							|  |  |  | 			input:  newRequest(t, "GET", "/bar"), | 
					
						
							|  |  |  | 			expect: newRequest(t, "GET", "/foo/bar"), | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			rule:   Rewrite{URI: "/foo{http.request.uri}?c=d"}, | 
					
						
							|  |  |  | 			input:  newRequest(t, "GET", "/bar?a=b"), | 
					
						
							|  |  |  | 			expect: newRequest(t, "GET", "/foo/bar?c=d"), | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			rule:   Rewrite{URI: "/foo{http.request.uri}?{http.request.uri.query}&c=d"}, | 
					
						
							|  |  |  | 			input:  newRequest(t, "GET", "/bar?a=b"), | 
					
						
							|  |  |  | 			expect: newRequest(t, "GET", "/foo/bar?a=b&c=d"), | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			rule:   Rewrite{URI: "{http.request.uri}"}, | 
					
						
							|  |  |  | 			input:  newRequest(t, "GET", "/bar?a=b"), | 
					
						
							|  |  |  | 			expect: newRequest(t, "GET", "/bar?a=b"), | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			rule:   Rewrite{URI: "{http.request.uri.path}bar?c=d"}, | 
					
						
							|  |  |  | 			input:  newRequest(t, "GET", "/foo/?a=b"), | 
					
						
							|  |  |  | 			expect: newRequest(t, "GET", "/foo/bar?c=d"), | 
					
						
							|  |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2022-01-13 12:17:15 -05:00
										 |  |  | 		{ | 
					
						
							|  |  |  | 			rule:   Rewrite{URI: "/i{http.request.uri}"}, | 
					
						
							|  |  |  | 			input:  newRequest(t, "GET", "/%C2%B7%E2%88%B5.png"), | 
					
						
							|  |  |  | 			expect: newRequest(t, "GET", "/i/%C2%B7%E2%88%B5.png"), | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			rule:   Rewrite{URI: "/i{http.request.uri}"}, | 
					
						
							|  |  |  | 			input:  newRequest(t, "GET", "/·∵.png?a=b"), | 
					
						
							|  |  |  | 			expect: newRequest(t, "GET", "/i/%C2%B7%E2%88%B5.png?a=b"), | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			rule:   Rewrite{URI: "/i{http.request.uri}"}, | 
					
						
							|  |  |  | 			input:  newRequest(t, "GET", "/%C2%B7%E2%88%B5.png?a=b"), | 
					
						
							|  |  |  | 			expect: newRequest(t, "GET", "/i/%C2%B7%E2%88%B5.png?a=b"), | 
					
						
							|  |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2022-05-09 11:09:42 -06:00
										 |  |  | 		{ | 
					
						
							|  |  |  | 			rule:   Rewrite{URI: "/bar#?"}, | 
					
						
							|  |  |  | 			input:  newRequest(t, "GET", "/foo#fragFirst?c=d"), // not a valid query string (is part of fragment) | 
					
						
							|  |  |  | 			expect: newRequest(t, "GET", "/bar#?"),             // I think this is right? but who knows; std lib drops fragment when parsing | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			rule:   Rewrite{URI: "/bar"}, | 
					
						
							|  |  |  | 			input:  newRequest(t, "GET", "/foo#fragFirst?c=d"), | 
					
						
							|  |  |  | 			expect: newRequest(t, "GET", "/bar#fragFirst?c=d"), | 
					
						
							|  |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2019-12-12 14:32:35 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2020-01-11 13:47:42 -07:00
										 |  |  | 			rule:   Rewrite{StripPathPrefix: "/prefix"}, | 
					
						
							| 
									
										
										
										
											2019-12-12 14:32:35 -07:00
										 |  |  | 			input:  newRequest(t, "GET", "/foo/bar"), | 
					
						
							|  |  |  | 			expect: newRequest(t, "GET", "/foo/bar"), | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2020-01-11 13:47:42 -07:00
										 |  |  | 			rule:   Rewrite{StripPathPrefix: "/prefix"}, | 
					
						
							| 
									
										
										
										
											2024-11-05 12:15:31 -05:00
										 |  |  | 			input:  newRequest(t, "GET", "/prefix/foo/bar"), | 
					
						
							|  |  |  | 			expect: newRequest(t, "GET", "/foo/bar"), | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			rule:   Rewrite{StripPathPrefix: "prefix"}, | 
					
						
							| 
									
										
										
										
											2019-12-12 14:32:35 -07:00
										 |  |  | 			input:  newRequest(t, "GET", "/prefix/foo/bar"), | 
					
						
							|  |  |  | 			expect: newRequest(t, "GET", "/foo/bar"), | 
					
						
							|  |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2022-09-28 00:13:12 -06:00
										 |  |  | 		{ | 
					
						
							|  |  |  | 			rule:   Rewrite{StripPathPrefix: "/prefix"}, | 
					
						
							|  |  |  | 			input:  newRequest(t, "GET", "/prefix"), | 
					
						
							|  |  |  | 			expect: newRequest(t, "GET", ""), | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			rule:   Rewrite{StripPathPrefix: "/prefix"}, | 
					
						
							|  |  |  | 			input:  newRequest(t, "GET", "/"), | 
					
						
							|  |  |  | 			expect: newRequest(t, "GET", "/"), | 
					
						
							|  |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2021-01-11 17:18:53 +01:00
										 |  |  | 		{ | 
					
						
							|  |  |  | 			rule:   Rewrite{StripPathPrefix: "/prefix"}, | 
					
						
							|  |  |  | 			input:  newRequest(t, "GET", "/prefix/foo%2Fbar"), | 
					
						
							|  |  |  | 			expect: newRequest(t, "GET", "/foo%2Fbar"), | 
					
						
							|  |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2019-12-12 14:32:35 -07:00
										 |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2020-01-11 13:47:42 -07:00
										 |  |  | 			rule:   Rewrite{StripPathPrefix: "/prefix"}, | 
					
						
							| 
									
										
										
										
											2019-12-12 14:32:35 -07:00
										 |  |  | 			input:  newRequest(t, "GET", "/foo/prefix/bar"), | 
					
						
							|  |  |  | 			expect: newRequest(t, "GET", "/foo/prefix/bar"), | 
					
						
							|  |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2022-08-16 08:48:57 -06:00
										 |  |  | 		{ | 
					
						
							|  |  |  | 			rule: Rewrite{StripPathPrefix: "//prefix"}, | 
					
						
							|  |  |  | 			// scheme and host needed for URL parser to succeed in setting up test | 
					
						
							|  |  |  | 			input:  newRequest(t, "GET", "http://host//prefix/foo/bar"), | 
					
						
							|  |  |  | 			expect: newRequest(t, "GET", "http://host/foo/bar"), | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			rule:   Rewrite{StripPathPrefix: "//prefix"}, | 
					
						
							|  |  |  | 			input:  newRequest(t, "GET", "/prefix/foo/bar"), | 
					
						
							|  |  |  | 			expect: newRequest(t, "GET", "/prefix/foo/bar"), | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			rule:   Rewrite{StripPathPrefix: "/a%2Fb/c"}, | 
					
						
							|  |  |  | 			input:  newRequest(t, "GET", "/a%2Fb/c/d"), | 
					
						
							|  |  |  | 			expect: newRequest(t, "GET", "/d"), | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			rule:   Rewrite{StripPathPrefix: "/a%2Fb/c"}, | 
					
						
							|  |  |  | 			input:  newRequest(t, "GET", "/a%2fb/c/d"), | 
					
						
							|  |  |  | 			expect: newRequest(t, "GET", "/d"), | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			rule:   Rewrite{StripPathPrefix: "/a/b/c"}, | 
					
						
							|  |  |  | 			input:  newRequest(t, "GET", "/a%2Fb/c/d"), | 
					
						
							|  |  |  | 			expect: newRequest(t, "GET", "/d"), | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			rule:   Rewrite{StripPathPrefix: "/a%2Fb/c"}, | 
					
						
							|  |  |  | 			input:  newRequest(t, "GET", "/a/b/c/d"), | 
					
						
							|  |  |  | 			expect: newRequest(t, "GET", "/a/b/c/d"), | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			rule:   Rewrite{StripPathPrefix: "//a%2Fb/c"}, | 
					
						
							|  |  |  | 			input:  newRequest(t, "GET", "/a/b/c/d"), | 
					
						
							|  |  |  | 			expect: newRequest(t, "GET", "/a/b/c/d"), | 
					
						
							|  |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2019-12-12 14:32:35 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2020-01-11 13:47:42 -07:00
										 |  |  | 			rule:   Rewrite{StripPathSuffix: "/suffix"}, | 
					
						
							| 
									
										
										
										
											2019-12-12 14:32:35 -07:00
										 |  |  | 			input:  newRequest(t, "GET", "/foo/bar"), | 
					
						
							|  |  |  | 			expect: newRequest(t, "GET", "/foo/bar"), | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2020-01-11 13:47:42 -07:00
										 |  |  | 			rule:   Rewrite{StripPathSuffix: "suffix"}, | 
					
						
							| 
									
										
										
										
											2019-12-12 14:32:35 -07:00
										 |  |  | 			input:  newRequest(t, "GET", "/foo/bar/suffix"), | 
					
						
							|  |  |  | 			expect: newRequest(t, "GET", "/foo/bar/"), | 
					
						
							|  |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2021-01-11 17:18:53 +01:00
										 |  |  | 		{ | 
					
						
							|  |  |  | 			rule:   Rewrite{StripPathSuffix: "suffix"}, | 
					
						
							|  |  |  | 			input:  newRequest(t, "GET", "/foo%2Fbar/suffix"), | 
					
						
							|  |  |  | 			expect: newRequest(t, "GET", "/foo%2Fbar/"), | 
					
						
							|  |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2022-08-16 08:48:57 -06:00
										 |  |  | 		{ | 
					
						
							|  |  |  | 			rule:   Rewrite{StripPathSuffix: "%2fsuffix"}, | 
					
						
							|  |  |  | 			input:  newRequest(t, "GET", "/foo%2Fbar%2fsuffix"), | 
					
						
							|  |  |  | 			expect: newRequest(t, "GET", "/foo%2Fbar"), | 
					
						
							|  |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2019-12-12 14:32:35 -07:00
										 |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2020-01-11 13:47:42 -07:00
										 |  |  | 			rule:   Rewrite{StripPathSuffix: "/suffix"}, | 
					
						
							| 
									
										
										
										
											2019-12-12 14:32:35 -07:00
										 |  |  | 			input:  newRequest(t, "GET", "/foo/suffix/bar"), | 
					
						
							|  |  |  | 			expect: newRequest(t, "GET", "/foo/suffix/bar"), | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2021-03-01 18:27:59 -07:00
										 |  |  | 			rule:   Rewrite{URISubstring: []substrReplacer{{Find: "findme", Replace: "replaced"}}}, | 
					
						
							| 
									
										
										
										
											2019-12-12 14:32:35 -07:00
										 |  |  | 			input:  newRequest(t, "GET", "/foo/bar"), | 
					
						
							|  |  |  | 			expect: newRequest(t, "GET", "/foo/bar"), | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2021-03-01 18:27:59 -07:00
										 |  |  | 			rule:   Rewrite{URISubstring: []substrReplacer{{Find: "findme", Replace: "replaced"}}}, | 
					
						
							| 
									
										
										
										
											2019-12-12 14:32:35 -07:00
										 |  |  | 			input:  newRequest(t, "GET", "/foo/findme/bar"), | 
					
						
							|  |  |  | 			expect: newRequest(t, "GET", "/foo/replaced/bar"), | 
					
						
							|  |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2021-01-11 17:18:53 +01:00
										 |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2021-03-01 18:27:59 -07:00
										 |  |  | 			rule:   Rewrite{URISubstring: []substrReplacer{{Find: "findme", Replace: "replaced"}}}, | 
					
						
							| 
									
										
										
										
											2021-01-11 17:18:53 +01:00
										 |  |  | 			input:  newRequest(t, "GET", "/foo/findme%2Fbar"), | 
					
						
							|  |  |  | 			expect: newRequest(t, "GET", "/foo/replaced%2Fbar"), | 
					
						
							|  |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2024-01-13 14:12:43 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-03-01 18:27:59 -07:00
										 |  |  | 		{ | 
					
						
							|  |  |  | 			rule:   Rewrite{PathRegexp: []*regexReplacer{{Find: "/{2,}", Replace: "/"}}}, | 
					
						
							|  |  |  | 			input:  newRequest(t, "GET", "/foo//bar///baz?a=b//c"), | 
					
						
							|  |  |  | 			expect: newRequest(t, "GET", "/foo/bar/baz?a=b//c"), | 
					
						
							|  |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2019-12-12 14:32:35 -07:00
										 |  |  | 	} { | 
					
						
							|  |  |  | 		// copy the original input just enough so that we can | 
					
						
							|  |  |  | 		// compare it after the rewrite to see if it changed | 
					
						
							| 
									
										
										
										
											2022-05-09 11:09:42 -06:00
										 |  |  | 		urlCopy := *tc.input.URL | 
					
						
							| 
									
										
										
										
											2019-12-12 14:32:35 -07:00
										 |  |  | 		originalInput := &http.Request{ | 
					
						
							|  |  |  | 			Method:     tc.input.Method, | 
					
						
							|  |  |  | 			RequestURI: tc.input.RequestURI, | 
					
						
							| 
									
										
										
										
											2022-05-09 11:09:42 -06:00
										 |  |  | 			URL:        &urlCopy, | 
					
						
							| 
									
										
										
										
											2019-12-12 14:32:35 -07:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// populate the replacer just enough for our tests | 
					
						
							| 
									
										
										
										
											2020-04-01 00:43:40 -06:00
										 |  |  | 		repl.Set("http.request.uri", tc.input.RequestURI) | 
					
						
							| 
									
										
										
										
											2019-12-12 14:32:35 -07:00
										 |  |  | 		repl.Set("http.request.uri.path", tc.input.URL.Path) | 
					
						
							|  |  |  | 		repl.Set("http.request.uri.query", tc.input.URL.RawQuery) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-03-01 18:27:59 -07:00
										 |  |  | 		// we can't directly call Provision() without a valid caddy.Context | 
					
						
							|  |  |  | 		// (TODO: fix that) so here we ad-hoc compile the regex | 
					
						
							|  |  |  | 		for _, rep := range tc.rule.PathRegexp { | 
					
						
							|  |  |  | 			re, err := regexp.Compile(rep.Find) | 
					
						
							|  |  |  | 			if err != nil { | 
					
						
							|  |  |  | 				t.Fatal(err) | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			rep.re = re | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-06 10:50:26 -04:00
										 |  |  | 		changed := tc.rule.Rewrite(tc.input, repl) | 
					
						
							| 
									
										
										
										
											2019-12-12 14:32:35 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		if expected, actual := !reqEqual(originalInput, tc.input), changed; expected != actual { | 
					
						
							|  |  |  | 			t.Errorf("Test %d: Expected changed=%t but was %t", i, expected, actual) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		if expected, actual := tc.expect.Method, tc.input.Method; expected != actual { | 
					
						
							|  |  |  | 			t.Errorf("Test %d: Expected Method='%s' but got '%s'", i, expected, actual) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		if expected, actual := tc.expect.RequestURI, tc.input.RequestURI; expected != actual { | 
					
						
							|  |  |  | 			t.Errorf("Test %d: Expected RequestURI='%s' but got '%s'", i, expected, actual) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		if expected, actual := tc.expect.URL.String(), tc.input.URL.String(); expected != actual { | 
					
						
							|  |  |  | 			t.Errorf("Test %d: Expected URL='%s' but got '%s'", i, expected, actual) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		if expected, actual := tc.expect.URL.RequestURI(), tc.input.URL.RequestURI(); expected != actual { | 
					
						
							|  |  |  | 			t.Errorf("Test %d: Expected URL.RequestURI()='%s' but got '%s'", i, expected, actual) | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2020-01-11 11:40:03 -07:00
										 |  |  | 		if expected, actual := tc.expect.URL.Fragment, tc.input.URL.Fragment; expected != actual { | 
					
						
							|  |  |  | 			t.Errorf("Test %d: Expected URL.Fragment='%s' but got '%s'", i, expected, actual) | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2019-12-12 14:32:35 -07:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func newRequest(t *testing.T, method, uri string) *http.Request { | 
					
						
							|  |  |  | 	req, err := http.NewRequest(method, uri, nil) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Fatalf("error creating request: %v", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	req.RequestURI = req.URL.RequestURI() // simulate incoming request | 
					
						
							|  |  |  | 	return req | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // reqEqual if r1 and r2 are equal enough for our purposes. | 
					
						
							|  |  |  | func reqEqual(r1, r2 *http.Request) bool { | 
					
						
							|  |  |  | 	if r1.Method != r2.Method { | 
					
						
							|  |  |  | 		return false | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if r1.RequestURI != r2.RequestURI { | 
					
						
							|  |  |  | 		return false | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if (r1.URL == nil && r2.URL != nil) || (r1.URL != nil && r2.URL == nil) { | 
					
						
							|  |  |  | 		return false | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if r1.URL == nil && r2.URL == nil { | 
					
						
							|  |  |  | 		return true | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return r1.URL.Scheme == r2.URL.Scheme && | 
					
						
							|  |  |  | 		r1.URL.Host == r2.URL.Host && | 
					
						
							|  |  |  | 		r1.URL.Path == r2.URL.Path && | 
					
						
							|  |  |  | 		r1.URL.RawPath == r2.URL.RawPath && | 
					
						
							|  |  |  | 		r1.URL.RawQuery == r2.URL.RawQuery && | 
					
						
							|  |  |  | 		r1.URL.Fragment == r2.URL.Fragment | 
					
						
							|  |  |  | } |