| 
									
										
										
										
											2023-02-08 18:05:09 +01: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 reverseproxy | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import "testing" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func TestParseUpstreamDialAddress(t *testing.T) { | 
					
						
							|  |  |  | 	for i, tc := range []struct { | 
					
						
							|  |  |  | 		input          string | 
					
						
							|  |  |  | 		expectHostPort string | 
					
						
							|  |  |  | 		expectScheme   string | 
					
						
							|  |  |  | 		expectErr      bool | 
					
						
							|  |  |  | 	}{ | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			input:          "foo", | 
					
						
							|  |  |  | 			expectHostPort: "foo:80", | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			input:          "foo:1234", | 
					
						
							|  |  |  | 			expectHostPort: "foo:1234", | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			input:          "127.0.0.1", | 
					
						
							|  |  |  | 			expectHostPort: "127.0.0.1:80", | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			input:          "127.0.0.1:1234", | 
					
						
							|  |  |  | 			expectHostPort: "127.0.0.1:1234", | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			input:          "[::1]", | 
					
						
							|  |  |  | 			expectHostPort: "[::1]:80", | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			input:          "[::1]:1234", | 
					
						
							|  |  |  | 			expectHostPort: "[::1]:1234", | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			input:          "{foo}", | 
					
						
							|  |  |  | 			expectHostPort: "{foo}", | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			input:          "{foo}:80", | 
					
						
							|  |  |  | 			expectHostPort: "{foo}:80", | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			input:          "{foo}:{bar}", | 
					
						
							|  |  |  | 			expectHostPort: "{foo}:{bar}", | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			input:          "http://foo", | 
					
						
							|  |  |  | 			expectHostPort: "foo:80", | 
					
						
							|  |  |  | 			expectScheme:   "http", | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			input:          "http://foo:1234", | 
					
						
							|  |  |  | 			expectHostPort: "foo:1234", | 
					
						
							|  |  |  | 			expectScheme:   "http", | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			input:          "http://127.0.0.1", | 
					
						
							|  |  |  | 			expectHostPort: "127.0.0.1:80", | 
					
						
							|  |  |  | 			expectScheme:   "http", | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			input:          "http://127.0.0.1:1234", | 
					
						
							|  |  |  | 			expectHostPort: "127.0.0.1:1234", | 
					
						
							|  |  |  | 			expectScheme:   "http", | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			input:          "http://[::1]", | 
					
						
							|  |  |  | 			expectHostPort: "[::1]:80", | 
					
						
							|  |  |  | 			expectScheme:   "http", | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			input:          "http://[::1]:80", | 
					
						
							|  |  |  | 			expectHostPort: "[::1]:80", | 
					
						
							|  |  |  | 			expectScheme:   "http", | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			input:          "https://foo", | 
					
						
							|  |  |  | 			expectHostPort: "foo:443", | 
					
						
							|  |  |  | 			expectScheme:   "https", | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			input:          "https://foo:1234", | 
					
						
							|  |  |  | 			expectHostPort: "foo:1234", | 
					
						
							|  |  |  | 			expectScheme:   "https", | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			input:          "https://127.0.0.1", | 
					
						
							|  |  |  | 			expectHostPort: "127.0.0.1:443", | 
					
						
							|  |  |  | 			expectScheme:   "https", | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			input:          "https://127.0.0.1:1234", | 
					
						
							|  |  |  | 			expectHostPort: "127.0.0.1:1234", | 
					
						
							|  |  |  | 			expectScheme:   "https", | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			input:          "https://[::1]", | 
					
						
							|  |  |  | 			expectHostPort: "[::1]:443", | 
					
						
							|  |  |  | 			expectScheme:   "https", | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			input:          "https://[::1]:1234", | 
					
						
							|  |  |  | 			expectHostPort: "[::1]:1234", | 
					
						
							|  |  |  | 			expectScheme:   "https", | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			input:          "h2c://foo", | 
					
						
							|  |  |  | 			expectHostPort: "foo:80", | 
					
						
							|  |  |  | 			expectScheme:   "h2c", | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			input:          "h2c://foo:1234", | 
					
						
							|  |  |  | 			expectHostPort: "foo:1234", | 
					
						
							|  |  |  | 			expectScheme:   "h2c", | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			input:          "h2c://127.0.0.1", | 
					
						
							|  |  |  | 			expectHostPort: "127.0.0.1:80", | 
					
						
							|  |  |  | 			expectScheme:   "h2c", | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			input:          "h2c://127.0.0.1:1234", | 
					
						
							|  |  |  | 			expectHostPort: "127.0.0.1:1234", | 
					
						
							|  |  |  | 			expectScheme:   "h2c", | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			input:          "h2c://[::1]", | 
					
						
							|  |  |  | 			expectHostPort: "[::1]:80", | 
					
						
							|  |  |  | 			expectScheme:   "h2c", | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			input:          "h2c://[::1]:1234", | 
					
						
							|  |  |  | 			expectHostPort: "[::1]:1234", | 
					
						
							|  |  |  | 			expectScheme:   "h2c", | 
					
						
							|  |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2023-05-15 14:14:50 -04:00
										 |  |  | 		{ | 
					
						
							|  |  |  | 			input:          "localhost:1001-1009", | 
					
						
							|  |  |  | 			expectHostPort: "localhost:1001-1009", | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			input:          "{host}:1001-1009", | 
					
						
							|  |  |  | 			expectHostPort: "{host}:1001-1009", | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			input:          "http://localhost:1001-1009", | 
					
						
							|  |  |  | 			expectHostPort: "localhost:1001-1009", | 
					
						
							|  |  |  | 			expectScheme:   "http", | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			input:          "https://localhost:1001-1009", | 
					
						
							|  |  |  | 			expectHostPort: "localhost:1001-1009", | 
					
						
							|  |  |  | 			expectScheme:   "https", | 
					
						
							|  |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2023-02-08 18:05:09 +01:00
										 |  |  | 		{ | 
					
						
							|  |  |  | 			input:          "unix//var/php.sock", | 
					
						
							|  |  |  | 			expectHostPort: "unix//var/php.sock", | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			input:          "unix+h2c//var/grpc.sock", | 
					
						
							|  |  |  | 			expectHostPort: "unix//var/grpc.sock", | 
					
						
							|  |  |  | 			expectScheme:   "h2c", | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			input:          "unix/{foo}", | 
					
						
							|  |  |  | 			expectHostPort: "unix/{foo}", | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			input:          "unix+h2c/{foo}", | 
					
						
							|  |  |  | 			expectHostPort: "unix/{foo}", | 
					
						
							|  |  |  | 			expectScheme:   "h2c", | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			input:          "unix//foo/{foo}/bar", | 
					
						
							|  |  |  | 			expectHostPort: "unix//foo/{foo}/bar", | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			input:          "unix+h2c//foo/{foo}/bar", | 
					
						
							|  |  |  | 			expectHostPort: "unix//foo/{foo}/bar", | 
					
						
							|  |  |  | 			expectScheme:   "h2c", | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			input:     "http://{foo}", | 
					
						
							|  |  |  | 			expectErr: true, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			input:     "http:// :80", | 
					
						
							|  |  |  | 			expectErr: true, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			input:     "http://localhost/path", | 
					
						
							|  |  |  | 			expectErr: true, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			input:     "http://localhost?key=value", | 
					
						
							|  |  |  | 			expectErr: true, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			input:     "http://localhost#fragment", | 
					
						
							|  |  |  | 			expectErr: true, | 
					
						
							|  |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2023-05-15 14:14:50 -04:00
										 |  |  | 		{ | 
					
						
							|  |  |  | 			input:     "http://localhost:8001-8002-8003", | 
					
						
							|  |  |  | 			expectErr: true, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			input:     "http://localhost:8001-8002/foo:bar", | 
					
						
							|  |  |  | 			expectErr: true, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			input:     "http://localhost:8001-8002/foo:1", | 
					
						
							|  |  |  | 			expectErr: true, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			input:     "http://localhost:8001-8002/foo:1-2", | 
					
						
							|  |  |  | 			expectErr: true, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			input:     "http://localhost:8001-8002#foo:1", | 
					
						
							|  |  |  | 			expectErr: true, | 
					
						
							|  |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2023-02-08 18:05:09 +01:00
										 |  |  | 		{ | 
					
						
							|  |  |  | 			input:     "http://foo:443", | 
					
						
							|  |  |  | 			expectErr: true, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			input:     "https://foo:80", | 
					
						
							|  |  |  | 			expectErr: true, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			input:     "h2c://foo:443", | 
					
						
							|  |  |  | 			expectErr: true, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			input:          `unix/c:\absolute\path`, | 
					
						
							|  |  |  | 			expectHostPort: `unix/c:\absolute\path`, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			input:          `unix+h2c/c:\absolute\path`, | 
					
						
							|  |  |  | 			expectHostPort: `unix/c:\absolute\path`, | 
					
						
							|  |  |  | 			expectScheme:   "h2c", | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			input:          "unix/c:/absolute/path", | 
					
						
							|  |  |  | 			expectHostPort: "unix/c:/absolute/path", | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			input:          "unix+h2c/c:/absolute/path", | 
					
						
							|  |  |  | 			expectHostPort: "unix/c:/absolute/path", | 
					
						
							|  |  |  | 			expectScheme:   "h2c", | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 	} { | 
					
						
							|  |  |  | 		actualHostPort, actualScheme, err := parseUpstreamDialAddress(tc.input) | 
					
						
							|  |  |  | 		if tc.expectErr && err == nil { | 
					
						
							|  |  |  | 			t.Errorf("Test %d: Expected error but got %v", i, err) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		if !tc.expectErr && err != nil { | 
					
						
							|  |  |  | 			t.Errorf("Test %d: Expected no error but got %v", i, err) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		if actualHostPort != tc.expectHostPort { | 
					
						
							|  |  |  | 			t.Errorf("Test %d: Expected host and port '%s' but got '%s'", i, tc.expectHostPort, actualHostPort) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		if actualScheme != tc.expectScheme { | 
					
						
							|  |  |  | 			t.Errorf("Test %d: Expected scheme '%s' but got '%s'", i, tc.expectScheme, actualScheme) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } |