|
1 | 1 | /* |
2 | | - * Copyright (c) 2022, FusionAuth, All Rights Reserved |
| 2 | + * Copyright (c) 2022-2024, FusionAuth, All Rights Reserved |
3 | 3 | * |
4 | 4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
5 | 5 | * you may not use this file except in compliance with the License. |
|
18 | 18 | import java.nio.charset.StandardCharsets; |
19 | 19 | import java.util.List; |
20 | 20 | import java.util.Map; |
| 21 | +import java.util.function.Consumer; |
21 | 22 |
|
22 | 23 | import io.fusionauth.http.HTTPValues.Headers; |
23 | 24 | import io.fusionauth.http.server.HTTPRequest; |
24 | 25 | import org.testng.annotations.Test; |
25 | 26 | import static org.testng.Assert.assertEquals; |
26 | 27 | import static org.testng.Assert.assertTrue; |
| 28 | +import static org.testng.Assert.fail; |
27 | 29 |
|
28 | 30 | /** |
29 | 31 | * Tests the HTTPRequest. |
@@ -51,6 +53,57 @@ public void decodeHeaders() { |
51 | 53 | assertEquals(request.getCharacterEncoding(), StandardCharsets.UTF_8); |
52 | 54 | } |
53 | 55 |
|
| 56 | + @Test |
| 57 | + public void getBaseURL() { |
| 58 | + // Use case 1: missing X-Forwarded-Port, infer it from https |
| 59 | + assertBaseURL("https://acme.com", |
| 60 | + "X-Forwarded-Host", "acme.com", |
| 61 | + "X-Forwarded-Proto", "https"); |
| 62 | + |
| 63 | + // Use case 2: Set a port on the Host, we will use that. |
| 64 | + assertBaseURL("https://acme.com:8192", |
| 65 | + "X-Forwarded-Host", "acme.com:8192", |
| 66 | + "X-Forwarded-Proto", "https"); |
| 67 | + |
| 68 | + // Use case 3: Set port from the X-Forwarded-Port header |
| 69 | + assertBaseURL("https://acme.com", |
| 70 | + "X-Forwarded-Host", "acme.com", |
| 71 | + "X-Forwarded-Port", "443", |
| 72 | + "X-Forwarded-Proto", "https"); |
| 73 | + |
| 74 | + // Use case 4: Set port from the X-Forwarded-Port header, non-standard |
| 75 | + assertBaseURL("https://acme.com:8192", |
| 76 | + "X-Forwarded-Host", "acme.com", |
| 77 | + "X-Forwarded-Port", "8192", |
| 78 | + "X-Forwarded-Proto", "https"); |
| 79 | + |
| 80 | + // Use case 5: Missing X-Forwarded-Proto header, cannot infer 443 |
| 81 | + assertBaseURL("http://acme.com:8080", |
| 82 | + "X-Forwarded-Host", "acme.com"); |
| 83 | + |
| 84 | + // Use case 6: Malformed X-Forwarded-Host header, so we'll ignore the port on the -Host header. |
| 85 | + assertBaseURL("https://acme.com:8080", |
| 86 | + "X-Forwarded-Host", "acme.com:##", |
| 87 | + "X-Forwarded-Proto", "https"); |
| 88 | + |
| 89 | + // Use case 7: Missing X-Forwarded-Host |
| 90 | + assertBaseURL("https://localhost:8080", |
| 91 | + "X-Forwarded-Proto", "https"); |
| 92 | + |
| 93 | + // Use case 8: http and port 80 |
| 94 | + assertBaseURL("https://localhost", |
| 95 | + request -> request.setPort(80), |
| 96 | + "X-Forwarded-Proto", "https"); |
| 97 | + |
| 98 | + // Use case 9: https and port 80 |
| 99 | + assertBaseURL("http://localhost", |
| 100 | + request -> { |
| 101 | + request.setPort(80); |
| 102 | + request.setScheme("https"); |
| 103 | + }, |
| 104 | + "X-Forwarded-Proto", "http"); |
| 105 | + } |
| 106 | + |
54 | 107 | @Test |
55 | 108 | public void hostHeaderPortHandling() { |
56 | 109 | // positive cases |
@@ -124,6 +177,32 @@ public void queryString() { |
124 | 177 | assertEquals(request.getURLParameters(), Map.of("name", List.of(""))); |
125 | 178 | } |
126 | 179 |
|
| 180 | + private void assertBaseURL(String expected, Consumer<HTTPRequest> consumer, String... headers) { |
| 181 | + HTTPRequest request = new HTTPRequest(); |
| 182 | + |
| 183 | + request.setScheme("http"); |
| 184 | + request.setHost("localhost"); |
| 185 | + request.setPort(8080); |
| 186 | + |
| 187 | + if (consumer != null) { |
| 188 | + consumer.accept(request); |
| 189 | + } |
| 190 | + |
| 191 | + if (headers.length % 2 != 0) { |
| 192 | + fail("You need to provide pairs."); |
| 193 | + } |
| 194 | + |
| 195 | + for (int i = 0; i < headers.length; i = i + 2) { |
| 196 | + request.setHeader(headers[i], headers[i + 1]); |
| 197 | + } |
| 198 | + |
| 199 | + assertEquals(request.getBaseURL(), expected); |
| 200 | + } |
| 201 | + |
| 202 | + private void assertBaseURL(String expected, String... headers) { |
| 203 | + assertBaseURL(expected, null, headers); |
| 204 | + } |
| 205 | + |
127 | 206 | private void assertURLs(String scheme, String source, String host, int port, String baseURL) { |
128 | 207 | HTTPRequest request = new HTTPRequest(); |
129 | 208 | request.setScheme(scheme); |
|
0 commit comments