parent
							
								
									cc7f3101b7
								
							
						
					
					
						commit
						793581ebde
					
				| 
						 | 
				
			
			@ -1,5 +1,5 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright 2002-2022 the original author or authors.
 | 
			
		||||
 * Copyright 2002-2023 the original author or authors.
 | 
			
		||||
 *
 | 
			
		||||
 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
 * you may not use this file except in compliance with the License.
 | 
			
		||||
| 
						 | 
				
			
			@ -97,37 +97,47 @@ public class ServletServerHttpRequest implements ServerHttpRequest {
 | 
			
		|||
	@Override
 | 
			
		||||
	public URI getURI() {
 | 
			
		||||
		if (this.uri == null) {
 | 
			
		||||
			String urlString = null;
 | 
			
		||||
			boolean hasQuery = false;
 | 
			
		||||
			try {
 | 
			
		||||
				StringBuffer url = this.servletRequest.getRequestURL();
 | 
			
		||||
				String query = this.servletRequest.getQueryString();
 | 
			
		||||
				hasQuery = StringUtils.hasText(query);
 | 
			
		||||
				if (hasQuery) {
 | 
			
		||||
					url.append('?').append(query);
 | 
			
		||||
				}
 | 
			
		||||
				urlString = url.toString();
 | 
			
		||||
				this.uri = new URI(urlString);
 | 
			
		||||
			}
 | 
			
		||||
			catch (URISyntaxException ex) {
 | 
			
		||||
				if (!hasQuery) {
 | 
			
		||||
					throw new IllegalStateException(
 | 
			
		||||
							"Could not resolve HttpServletRequest as URI: " + urlString, ex);
 | 
			
		||||
				}
 | 
			
		||||
				// Maybe a malformed query string... try plain request URL
 | 
			
		||||
				try {
 | 
			
		||||
					urlString = this.servletRequest.getRequestURL().toString();
 | 
			
		||||
					this.uri = new URI(urlString);
 | 
			
		||||
				}
 | 
			
		||||
				catch (URISyntaxException ex2) {
 | 
			
		||||
					throw new IllegalStateException(
 | 
			
		||||
							"Could not resolve HttpServletRequest as URI: " + urlString, ex2);
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			this.uri = initURI(this.servletRequest);
 | 
			
		||||
		}
 | 
			
		||||
		return this.uri;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Initialize a URI from the given Servet request.
 | 
			
		||||
	 * @param servletRequest the request
 | 
			
		||||
	 * @return the initialized URI
 | 
			
		||||
	 * @since 6.1
 | 
			
		||||
	 */
 | 
			
		||||
	public static URI initURI(HttpServletRequest servletRequest) {
 | 
			
		||||
		String urlString = null;
 | 
			
		||||
		boolean hasQuery = false;
 | 
			
		||||
		try {
 | 
			
		||||
			StringBuffer url = servletRequest.getRequestURL();
 | 
			
		||||
			String query = servletRequest.getQueryString();
 | 
			
		||||
			hasQuery = StringUtils.hasText(query);
 | 
			
		||||
			if (hasQuery) {
 | 
			
		||||
				url.append('?').append(query);
 | 
			
		||||
			}
 | 
			
		||||
			urlString = url.toString();
 | 
			
		||||
			return new URI(urlString);
 | 
			
		||||
		}
 | 
			
		||||
		catch (URISyntaxException ex) {
 | 
			
		||||
			if (!hasQuery) {
 | 
			
		||||
				throw new IllegalStateException(
 | 
			
		||||
						"Could not resolve HttpServletRequest as URI: " + urlString, ex);
 | 
			
		||||
			}
 | 
			
		||||
			// Maybe a malformed query string... try plain request URL
 | 
			
		||||
			try {
 | 
			
		||||
				urlString = servletRequest.getRequestURL().toString();
 | 
			
		||||
				return new URI(urlString);
 | 
			
		||||
			}
 | 
			
		||||
			catch (URISyntaxException ex2) {
 | 
			
		||||
				throw new IllegalStateException(
 | 
			
		||||
						"Could not resolve HttpServletRequest as URI: " + urlString, ex2);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Override
 | 
			
		||||
	public HttpHeaders getHeaders() {
 | 
			
		||||
		if (this.headers == null) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,5 +1,5 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright 2002-2021 the original author or authors.
 | 
			
		||||
 * Copyright 2002-2023 the original author or authors.
 | 
			
		||||
 *
 | 
			
		||||
 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
 * you may not use this file except in compliance with the License.
 | 
			
		||||
| 
						 | 
				
			
			@ -18,6 +18,7 @@ package org.springframework.web.filter;
 | 
			
		|||
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.net.InetSocketAddress;
 | 
			
		||||
import java.net.URI;
 | 
			
		||||
import java.util.Collections;
 | 
			
		||||
import java.util.Enumeration;
 | 
			
		||||
import java.util.Locale;
 | 
			
		||||
| 
						 | 
				
			
			@ -31,12 +32,14 @@ import jakarta.servlet.http.HttpServletRequestWrapper;
 | 
			
		|||
import jakarta.servlet.http.HttpServletResponse;
 | 
			
		||||
import jakarta.servlet.http.HttpServletResponseWrapper;
 | 
			
		||||
 | 
			
		||||
import org.springframework.http.HttpHeaders;
 | 
			
		||||
import org.springframework.http.HttpStatus;
 | 
			
		||||
import org.springframework.http.server.ServerHttpRequest;
 | 
			
		||||
import org.springframework.http.server.ServletServerHttpRequest;
 | 
			
		||||
import org.springframework.lang.Nullable;
 | 
			
		||||
import org.springframework.util.LinkedCaseInsensitiveMap;
 | 
			
		||||
import org.springframework.util.StringUtils;
 | 
			
		||||
import org.springframework.web.util.ForwardedHeaderUtils;
 | 
			
		||||
import org.springframework.web.util.UriComponents;
 | 
			
		||||
import org.springframework.web.util.UriComponentsBuilder;
 | 
			
		||||
import org.springframework.web.util.UrlPathHelper;
 | 
			
		||||
| 
						 | 
				
			
			@ -236,7 +239,9 @@ public class ForwardedHeaderFilter extends OncePerRequestFilter {
 | 
			
		|||
			super(servletRequest);
 | 
			
		||||
 | 
			
		||||
			ServerHttpRequest request = new ServletServerHttpRequest(servletRequest);
 | 
			
		||||
			UriComponents uriComponents = UriComponentsBuilder.fromHttpRequest(request).build();
 | 
			
		||||
			URI uri = request.getURI();
 | 
			
		||||
			HttpHeaders headers = request.getHeaders();
 | 
			
		||||
			UriComponents uriComponents = ForwardedHeaderUtils.adaptFromForwardedHeaders(uri, headers).build();
 | 
			
		||||
			int port = uriComponents.getPort();
 | 
			
		||||
 | 
			
		||||
			this.scheme = uriComponents.getScheme();
 | 
			
		||||
| 
						 | 
				
			
			@ -244,7 +249,7 @@ public class ForwardedHeaderFilter extends OncePerRequestFilter {
 | 
			
		|||
			this.host = uriComponents.getHost();
 | 
			
		||||
			this.port = (port == -1 ? (this.secure ? 443 : 80) : port);
 | 
			
		||||
 | 
			
		||||
			this.remoteAddress = UriComponentsBuilder.parseForwardedFor(request, request.getRemoteAddress());
 | 
			
		||||
			this.remoteAddress = ForwardedHeaderUtils.parseForwardedFor(uri, headers, request.getRemoteAddress());
 | 
			
		||||
 | 
			
		||||
			String baseUrl = this.scheme + "://" + this.host + (port == -1 ? "" : ":" + port);
 | 
			
		||||
			Supplier<HttpServletRequest> delegateRequest = () -> (HttpServletRequest) getRequest();
 | 
			
		||||
| 
						 | 
				
			
			@ -453,8 +458,11 @@ public class ForwardedHeaderFilter extends OncePerRequestFilter {
 | 
			
		|||
						StringUtils.applyRelativePath(this.request.getRequestURI(), path));
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			String result = UriComponentsBuilder
 | 
			
		||||
					.fromHttpRequest(new ServletServerHttpRequest(this.request))
 | 
			
		||||
			ServletServerHttpRequest httpRequest = new ServletServerHttpRequest(this.request);
 | 
			
		||||
			URI uri = httpRequest.getURI();
 | 
			
		||||
			HttpHeaders headers = httpRequest.getHeaders();
 | 
			
		||||
 | 
			
		||||
			String result = ForwardedHeaderUtils.adaptFromForwardedHeaders(uri, headers)
 | 
			
		||||
					.replacePath(path)
 | 
			
		||||
					.replaceQuery(uriComponents.getQuery())
 | 
			
		||||
					.fragment(uriComponents.getFragment())
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,5 +1,5 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright 2002-2020 the original author or authors.
 | 
			
		||||
 * Copyright 2002-2023 the original author or authors.
 | 
			
		||||
 *
 | 
			
		||||
 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
 * you may not use this file except in compliance with the License.
 | 
			
		||||
| 
						 | 
				
			
			@ -29,7 +29,7 @@ import org.springframework.http.server.reactive.ServerHttpRequest;
 | 
			
		|||
import org.springframework.lang.Nullable;
 | 
			
		||||
import org.springframework.util.LinkedCaseInsensitiveMap;
 | 
			
		||||
import org.springframework.util.StringUtils;
 | 
			
		||||
import org.springframework.web.util.UriComponentsBuilder;
 | 
			
		||||
import org.springframework.web.util.ForwardedHeaderUtils;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Extract values from "Forwarded" and "X-Forwarded-*" headers to override
 | 
			
		||||
| 
						 | 
				
			
			@ -100,7 +100,9 @@ public class ForwardedHeaderTransformer implements Function<ServerHttpRequest, S
 | 
			
		|||
		if (hasForwardedHeaders(request)) {
 | 
			
		||||
			ServerHttpRequest.Builder builder = request.mutate();
 | 
			
		||||
			if (!this.removeOnly) {
 | 
			
		||||
				URI uri = UriComponentsBuilder.fromHttpRequest(request).build(true).toUri();
 | 
			
		||||
				URI originalUri = request.getURI();
 | 
			
		||||
				HttpHeaders headers = request.getHeaders();
 | 
			
		||||
				URI uri = ForwardedHeaderUtils.adaptFromForwardedHeaders(originalUri, headers).build(true).toUri();
 | 
			
		||||
				builder.uri(uri);
 | 
			
		||||
				String prefix = getForwardedPrefix(request);
 | 
			
		||||
				if (prefix != null) {
 | 
			
		||||
| 
						 | 
				
			
			@ -108,7 +110,7 @@ public class ForwardedHeaderTransformer implements Function<ServerHttpRequest, S
 | 
			
		|||
					builder.contextPath(prefix);
 | 
			
		||||
				}
 | 
			
		||||
				InetSocketAddress remoteAddress = request.getRemoteAddress();
 | 
			
		||||
				remoteAddress = UriComponentsBuilder.parseForwardedFor(request, remoteAddress);
 | 
			
		||||
				remoteAddress = ForwardedHeaderUtils.parseForwardedFor(originalUri, headers, remoteAddress);
 | 
			
		||||
				if (remoteAddress != null) {
 | 
			
		||||
					builder.remoteAddress(remoteAddress);
 | 
			
		||||
				}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,190 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright 2002-2023 the original author or 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
 | 
			
		||||
 *
 | 
			
		||||
 *      https://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 org.springframework.web.util;
 | 
			
		||||
 | 
			
		||||
import java.net.InetSocketAddress;
 | 
			
		||||
import java.net.URI;
 | 
			
		||||
import java.util.regex.Matcher;
 | 
			
		||||
import java.util.regex.Pattern;
 | 
			
		||||
 | 
			
		||||
import org.springframework.http.HttpHeaders;
 | 
			
		||||
import org.springframework.lang.Nullable;
 | 
			
		||||
import org.springframework.util.StringUtils;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Utility class to assist with processing "Forwarded" and "X-Forwarded-*" headers.
 | 
			
		||||
 *
 | 
			
		||||
 * <p><strong>Note:</strong>There are security considerations surrounding the use
 | 
			
		||||
 * of forwarded headers. Those should not be used unless the application is
 | 
			
		||||
 * behind a trusted proxy that inserts them and also explicitly removes any such
 | 
			
		||||
 * headers coming from an external source.
 | 
			
		||||
 *
 | 
			
		||||
 * <p>In most cases, should not use this class directly but rely on
 | 
			
		||||
 * {@link org.springframework.web.filter.ForwardedHeaderFilter} for Spring MVC, or
 | 
			
		||||
 * {@link org.springframework.web.server.adapter.ForwardedHeaderTransformer} in
 | 
			
		||||
 * order to extract the information from them as early as possible, and discard
 | 
			
		||||
 * such headers. Underlying servers such as Tomcat, Jetty, Reactor Netty, also
 | 
			
		||||
 * provides options to handle forwarded headers even earlier.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Rossen Stoyanchev
 | 
			
		||||
 * @since 6.1
 | 
			
		||||
 */
 | 
			
		||||
public abstract class ForwardedHeaderUtils {
 | 
			
		||||
 | 
			
		||||
	private static final String FORWARDED_VALUE = "\"?([^;,\"]+)\"?";
 | 
			
		||||
 | 
			
		||||
	private static final Pattern FORWARDED_HOST_PATTERN = Pattern.compile("(?i:host)=" + FORWARDED_VALUE);
 | 
			
		||||
 | 
			
		||||
	private static final Pattern FORWARDED_PROTO_PATTERN = Pattern.compile("(?i:proto)=" + FORWARDED_VALUE);
 | 
			
		||||
 | 
			
		||||
	private static final Pattern FORWARDED_FOR_PATTERN = Pattern.compile("(?i:for)=" + FORWARDED_VALUE);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Adapt the scheme+host+port of the given {@link URI} from the "Forwarded" header,
 | 
			
		||||
	 * see <a href="https://tools.ietf.org/html/rfc7239">RFC 7239</a>, or
 | 
			
		||||
	 * "X-Forwarded-Host", "X-Forwarded-Port", and "X-Forwarded-Proto" if "Forwarded"
 | 
			
		||||
	 * is not present.
 | 
			
		||||
	 * @param headers the HTTP headers to consider
 | 
			
		||||
	 * @return a {@link UriComponentsBuilder} that reflects the request URI and
 | 
			
		||||
	 * additional updates from forwarded headers
 | 
			
		||||
	 */
 | 
			
		||||
	public static UriComponentsBuilder adaptFromForwardedHeaders(URI uri, HttpHeaders headers) {
 | 
			
		||||
		UriComponentsBuilder uriComponentsBuilder = UriComponentsBuilder.fromUri(uri);
 | 
			
		||||
		try {
 | 
			
		||||
			String forwardedHeader = headers.getFirst("Forwarded");
 | 
			
		||||
			if (StringUtils.hasText(forwardedHeader)) {
 | 
			
		||||
				Matcher matcher = FORWARDED_PROTO_PATTERN.matcher(forwardedHeader);
 | 
			
		||||
				if (matcher.find()) {
 | 
			
		||||
					uriComponentsBuilder.scheme(matcher.group(1).trim());
 | 
			
		||||
					uriComponentsBuilder.port(null);
 | 
			
		||||
				}
 | 
			
		||||
				else if (isForwardedSslOn(headers)) {
 | 
			
		||||
					uriComponentsBuilder.scheme("https");
 | 
			
		||||
					uriComponentsBuilder.port(null);
 | 
			
		||||
				}
 | 
			
		||||
				matcher = FORWARDED_HOST_PATTERN.matcher(forwardedHeader);
 | 
			
		||||
				if (matcher.find()) {
 | 
			
		||||
					adaptForwardedHost(uriComponentsBuilder, matcher.group(1).trim());
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			else {
 | 
			
		||||
				String protocolHeader = headers.getFirst("X-Forwarded-Proto");
 | 
			
		||||
				if (StringUtils.hasText(protocolHeader)) {
 | 
			
		||||
					uriComponentsBuilder.scheme(StringUtils.tokenizeToStringArray(protocolHeader, ",")[0]);
 | 
			
		||||
					uriComponentsBuilder.port(null);
 | 
			
		||||
				}
 | 
			
		||||
				else if (isForwardedSslOn(headers)) {
 | 
			
		||||
					uriComponentsBuilder.scheme("https");
 | 
			
		||||
					uriComponentsBuilder.port(null);
 | 
			
		||||
				}
 | 
			
		||||
				String hostHeader = headers.getFirst("X-Forwarded-Host");
 | 
			
		||||
				if (StringUtils.hasText(hostHeader)) {
 | 
			
		||||
					adaptForwardedHost(uriComponentsBuilder, StringUtils.tokenizeToStringArray(hostHeader, ",")[0]);
 | 
			
		||||
				}
 | 
			
		||||
				String portHeader = headers.getFirst("X-Forwarded-Port");
 | 
			
		||||
				if (StringUtils.hasText(portHeader)) {
 | 
			
		||||
					uriComponentsBuilder.port(Integer.parseInt(StringUtils.tokenizeToStringArray(portHeader, ",")[0]));
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		catch (NumberFormatException ex) {
 | 
			
		||||
			throw new IllegalArgumentException("Failed to parse a port from \"forwarded\"-type headers. " +
 | 
			
		||||
					"If not behind a trusted proxy, consider using ForwardedHeaderFilter " +
 | 
			
		||||
					"with the removeOnly=true. Request headers: " + headers);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		uriComponentsBuilder.resetPortIfDefaultForScheme();
 | 
			
		||||
 | 
			
		||||
		return uriComponentsBuilder;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	private static boolean isForwardedSslOn(HttpHeaders headers) {
 | 
			
		||||
		String forwardedSsl = headers.getFirst("X-Forwarded-Ssl");
 | 
			
		||||
		return StringUtils.hasText(forwardedSsl) && forwardedSsl.equalsIgnoreCase("on");
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	private static void adaptForwardedHost(UriComponentsBuilder uriComponentsBuilder, String rawValue) {
 | 
			
		||||
		int portSeparatorIdx = rawValue.lastIndexOf(':');
 | 
			
		||||
		int squareBracketIdx = rawValue.lastIndexOf(']');
 | 
			
		||||
		if (portSeparatorIdx > squareBracketIdx) {
 | 
			
		||||
			if (squareBracketIdx == -1 && rawValue.indexOf(':') != portSeparatorIdx) {
 | 
			
		||||
				throw new IllegalArgumentException("Invalid IPv4 address: " + rawValue);
 | 
			
		||||
			}
 | 
			
		||||
			uriComponentsBuilder.host(rawValue.substring(0, portSeparatorIdx));
 | 
			
		||||
			uriComponentsBuilder.port(Integer.parseInt(rawValue, portSeparatorIdx + 1, rawValue.length(), 10));
 | 
			
		||||
		}
 | 
			
		||||
		else {
 | 
			
		||||
			uriComponentsBuilder.host(rawValue);
 | 
			
		||||
			uriComponentsBuilder.port(null);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Parse the first "Forwarded: for=..." or "X-Forwarded-For" header value to
 | 
			
		||||
	 * an {@code InetSocketAddress} representing the address of the client.
 | 
			
		||||
	 * @param uri the request URI
 | 
			
		||||
	 * @param headers the request headers that may contain forwarded headers
 | 
			
		||||
	 * @param remoteAddress the current remoteAddress
 | 
			
		||||
	 * @return an {@code InetSocketAddress} with the extracted host and port, or
 | 
			
		||||
	 * {@code null} if the headers are not present.
 | 
			
		||||
	 * @see <a href="https://tools.ietf.org/html/rfc7239#section-5.2">RFC 7239, Section 5.2</a>
 | 
			
		||||
	 */
 | 
			
		||||
	@Nullable
 | 
			
		||||
	public static InetSocketAddress parseForwardedFor(
 | 
			
		||||
			URI uri, HttpHeaders headers, @Nullable InetSocketAddress remoteAddress) {
 | 
			
		||||
 | 
			
		||||
		int port = (remoteAddress != null ?
 | 
			
		||||
				remoteAddress.getPort() : "https".equals(uri.getScheme()) ? 443 : 80);
 | 
			
		||||
 | 
			
		||||
		String forwardedHeader = headers.getFirst("Forwarded");
 | 
			
		||||
		if (StringUtils.hasText(forwardedHeader)) {
 | 
			
		||||
			String forwardedToUse = StringUtils.tokenizeToStringArray(forwardedHeader, ",")[0];
 | 
			
		||||
			Matcher matcher = FORWARDED_FOR_PATTERN.matcher(forwardedToUse);
 | 
			
		||||
			if (matcher.find()) {
 | 
			
		||||
				String value = matcher.group(1).trim();
 | 
			
		||||
				String host = value;
 | 
			
		||||
				int portSeparatorIdx = value.lastIndexOf(':');
 | 
			
		||||
				int squareBracketIdx = value.lastIndexOf(']');
 | 
			
		||||
				if (portSeparatorIdx > squareBracketIdx) {
 | 
			
		||||
					if (squareBracketIdx == -1 && value.indexOf(':') != portSeparatorIdx) {
 | 
			
		||||
						throw new IllegalArgumentException("Invalid IPv4 address: " + value);
 | 
			
		||||
					}
 | 
			
		||||
					host = value.substring(0, portSeparatorIdx);
 | 
			
		||||
					try {
 | 
			
		||||
						port = Integer.parseInt(value, portSeparatorIdx + 1, value.length(), 10);
 | 
			
		||||
					}
 | 
			
		||||
					catch (NumberFormatException ex) {
 | 
			
		||||
						throw new IllegalArgumentException(
 | 
			
		||||
								"Failed to parse a port from \"forwarded\"-type header value: " + value);
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
				return InetSocketAddress.createUnresolved(host, port);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		String forHeader = headers.getFirst("X-Forwarded-For");
 | 
			
		||||
		if (StringUtils.hasText(forHeader)) {
 | 
			
		||||
			String host = StringUtils.tokenizeToStringArray(forHeader, ",")[0];
 | 
			
		||||
			return InetSocketAddress.createUnresolved(host, port);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		return null;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,5 +1,5 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright 2002-2022 the original author or authors.
 | 
			
		||||
 * Copyright 2002-2023 the original author or authors.
 | 
			
		||||
 *
 | 
			
		||||
 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
 * you may not use this file except in compliance with the License.
 | 
			
		||||
| 
						 | 
				
			
			@ -104,12 +104,6 @@ public class UriComponentsBuilder implements UriBuilder, Cloneable {
 | 
			
		|||
 | 
			
		||||
	private static final String FORWARDED_VALUE = "\"?([^;,\"]+)\"?";
 | 
			
		||||
 | 
			
		||||
	private static final Pattern FORWARDED_HOST_PATTERN = Pattern.compile("(?i:host)=" + FORWARDED_VALUE);
 | 
			
		||||
 | 
			
		||||
	private static final Pattern FORWARDED_PROTO_PATTERN = Pattern.compile("(?i:proto)=" + FORWARDED_VALUE);
 | 
			
		||||
 | 
			
		||||
	private static final Pattern FORWARDED_FOR_PATTERN = Pattern.compile("(?i:for)=" + FORWARDED_VALUE);
 | 
			
		||||
 | 
			
		||||
	private static final Object[] EMPTY_VALUES = new Object[0];
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -326,10 +320,12 @@ public class UriComponentsBuilder implements UriBuilder, Cloneable {
 | 
			
		|||
	 * @param request the source request
 | 
			
		||||
	 * @return the URI components of the URI
 | 
			
		||||
	 * @since 4.1.5
 | 
			
		||||
	 * @see #parseForwardedFor(HttpRequest, InetSocketAddress)
 | 
			
		||||
	 * @deprecated in favor of {@link ForwardedHeaderUtils#adaptFromForwardedHeaders};
 | 
			
		||||
	 * to be removed in 6.2
 | 
			
		||||
	 */
 | 
			
		||||
	@Deprecated(since = "6.1", forRemoval = true)
 | 
			
		||||
	public static UriComponentsBuilder fromHttpRequest(HttpRequest request) {
 | 
			
		||||
		return fromUri(request.getURI()).adaptFromForwardedHeaders(request.getHeaders());
 | 
			
		||||
		return ForwardedHeaderUtils.adaptFromForwardedHeaders(request.getURI(), request.getHeaders());
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
| 
						 | 
				
			
			@ -340,48 +336,16 @@ public class UriComponentsBuilder implements UriBuilder, Cloneable {
 | 
			
		|||
	 * @return an {@code InetSocketAddress} with the extracted host and port, or
 | 
			
		||||
	 * {@code null} if the headers are not present.
 | 
			
		||||
	 * @since 5.3
 | 
			
		||||
	 * @see <a href="https://tools.ietf.org/html/rfc7239#section-5.2">RFC 7239, Section 5.2</a>
 | 
			
		||||
	 * @deprecated in favor of {@link ForwardedHeaderUtils#adaptFromForwardedHeaders};
 | 
			
		||||
	 * to be removed in 6.2
 | 
			
		||||
	 */
 | 
			
		||||
	@Deprecated(since = "6.1", forRemoval = true)
 | 
			
		||||
	@Nullable
 | 
			
		||||
	public static InetSocketAddress parseForwardedFor(
 | 
			
		||||
			HttpRequest request, @Nullable InetSocketAddress remoteAddress) {
 | 
			
		||||
 | 
			
		||||
		int port = (remoteAddress != null ?
 | 
			
		||||
				remoteAddress.getPort() : "https".equals(request.getURI().getScheme()) ? 443 : 80);
 | 
			
		||||
 | 
			
		||||
		String forwardedHeader = request.getHeaders().getFirst("Forwarded");
 | 
			
		||||
		if (StringUtils.hasText(forwardedHeader)) {
 | 
			
		||||
			String forwardedToUse = StringUtils.tokenizeToStringArray(forwardedHeader, ",")[0];
 | 
			
		||||
			Matcher matcher = FORWARDED_FOR_PATTERN.matcher(forwardedToUse);
 | 
			
		||||
			if (matcher.find()) {
 | 
			
		||||
				String value = matcher.group(1).trim();
 | 
			
		||||
				String host = value;
 | 
			
		||||
				int portSeparatorIdx = value.lastIndexOf(':');
 | 
			
		||||
				int squareBracketIdx = value.lastIndexOf(']');
 | 
			
		||||
				if (portSeparatorIdx > squareBracketIdx) {
 | 
			
		||||
					if (squareBracketIdx == -1 && value.indexOf(':') != portSeparatorIdx) {
 | 
			
		||||
						throw new IllegalArgumentException("Invalid IPv4 address: " + value);
 | 
			
		||||
					}
 | 
			
		||||
					host = value.substring(0, portSeparatorIdx);
 | 
			
		||||
					try {
 | 
			
		||||
						port = Integer.parseInt(value, portSeparatorIdx + 1, value.length(), 10);
 | 
			
		||||
					}
 | 
			
		||||
					catch (NumberFormatException ex) {
 | 
			
		||||
						throw new IllegalArgumentException(
 | 
			
		||||
								"Failed to parse a port from \"forwarded\"-type header value: " + value);
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
				return InetSocketAddress.createUnresolved(host, port);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		String forHeader = request.getHeaders().getFirst("X-Forwarded-For");
 | 
			
		||||
		if (StringUtils.hasText(forHeader)) {
 | 
			
		||||
			String host = StringUtils.tokenizeToStringArray(forHeader, ",")[0];
 | 
			
		||||
			return InetSocketAddress.createUnresolved(host, port);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		return null;
 | 
			
		||||
		return ForwardedHeaderUtils.parseForwardedFor(
 | 
			
		||||
				request.getURI(), request.getHeaders(), remoteAddress);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
| 
						 | 
				
			
			@ -824,94 +788,6 @@ public class UriComponentsBuilder implements UriBuilder, Cloneable {
 | 
			
		|||
		return this;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Adapt this builder's scheme+host+port from the given headers, specifically
 | 
			
		||||
	 * "Forwarded" (<a href="https://tools.ietf.org/html/rfc7239">RFC 7239</a>,
 | 
			
		||||
	 * or "X-Forwarded-Host", "X-Forwarded-Port", and "X-Forwarded-Proto" if
 | 
			
		||||
	 * "Forwarded" is not found.
 | 
			
		||||
	 * <p><strong>Note:</strong> this method uses values from forwarded headers,
 | 
			
		||||
	 * if present, in order to reflect the client-originated protocol and address.
 | 
			
		||||
	 * Consider using the {@code ForwardedHeaderFilter} in order to choose from a
 | 
			
		||||
	 * central place whether to extract and use, or to discard such headers.
 | 
			
		||||
	 * See the Spring Framework reference for more on this filter.
 | 
			
		||||
	 * @param headers the HTTP headers to consider
 | 
			
		||||
	 * @return this UriComponentsBuilder
 | 
			
		||||
	 * @since 4.2.7
 | 
			
		||||
	 */
 | 
			
		||||
	UriComponentsBuilder adaptFromForwardedHeaders(HttpHeaders headers) {
 | 
			
		||||
		try {
 | 
			
		||||
			String forwardedHeader = headers.getFirst("Forwarded");
 | 
			
		||||
			if (StringUtils.hasText(forwardedHeader)) {
 | 
			
		||||
				Matcher matcher = FORWARDED_PROTO_PATTERN.matcher(forwardedHeader);
 | 
			
		||||
				if (matcher.find()) {
 | 
			
		||||
					scheme(matcher.group(1).trim());
 | 
			
		||||
					port(null);
 | 
			
		||||
				}
 | 
			
		||||
				else if (isForwardedSslOn(headers)) {
 | 
			
		||||
					scheme("https");
 | 
			
		||||
					port(null);
 | 
			
		||||
				}
 | 
			
		||||
				matcher = FORWARDED_HOST_PATTERN.matcher(forwardedHeader);
 | 
			
		||||
				if (matcher.find()) {
 | 
			
		||||
					adaptForwardedHost(matcher.group(1).trim());
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			else {
 | 
			
		||||
				String protocolHeader = headers.getFirst("X-Forwarded-Proto");
 | 
			
		||||
				if (StringUtils.hasText(protocolHeader)) {
 | 
			
		||||
					scheme(StringUtils.tokenizeToStringArray(protocolHeader, ",")[0]);
 | 
			
		||||
					port(null);
 | 
			
		||||
				}
 | 
			
		||||
				else if (isForwardedSslOn(headers)) {
 | 
			
		||||
					scheme("https");
 | 
			
		||||
					port(null);
 | 
			
		||||
				}
 | 
			
		||||
				String hostHeader = headers.getFirst("X-Forwarded-Host");
 | 
			
		||||
				if (StringUtils.hasText(hostHeader)) {
 | 
			
		||||
					adaptForwardedHost(StringUtils.tokenizeToStringArray(hostHeader, ",")[0]);
 | 
			
		||||
				}
 | 
			
		||||
				String portHeader = headers.getFirst("X-Forwarded-Port");
 | 
			
		||||
				if (StringUtils.hasText(portHeader)) {
 | 
			
		||||
					port(Integer.parseInt(StringUtils.tokenizeToStringArray(portHeader, ",")[0]));
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		catch (NumberFormatException ex) {
 | 
			
		||||
			throw new IllegalArgumentException("Failed to parse a port from \"forwarded\"-type headers. " +
 | 
			
		||||
					"If not behind a trusted proxy, consider using ForwardedHeaderFilter " +
 | 
			
		||||
					"with the removeOnly=true. Request headers: " + headers);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (this.scheme != null &&
 | 
			
		||||
				(((this.scheme.equals("http") || this.scheme.equals("ws")) && "80".equals(this.port)) ||
 | 
			
		||||
				((this.scheme.equals("https") || this.scheme.equals("wss")) && "443".equals(this.port)))) {
 | 
			
		||||
			port(null);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		return this;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	private boolean isForwardedSslOn(HttpHeaders headers) {
 | 
			
		||||
		String forwardedSsl = headers.getFirst("X-Forwarded-Ssl");
 | 
			
		||||
		return StringUtils.hasText(forwardedSsl) && forwardedSsl.equalsIgnoreCase("on");
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	private void adaptForwardedHost(String rawValue) {
 | 
			
		||||
		int portSeparatorIdx = rawValue.lastIndexOf(':');
 | 
			
		||||
		int squareBracketIdx = rawValue.lastIndexOf(']');
 | 
			
		||||
		if (portSeparatorIdx > squareBracketIdx) {
 | 
			
		||||
			if (squareBracketIdx == -1 && rawValue.indexOf(':') != portSeparatorIdx) {
 | 
			
		||||
				throw new IllegalArgumentException("Invalid IPv4 address: " + rawValue);
 | 
			
		||||
			}
 | 
			
		||||
			host(rawValue.substring(0, portSeparatorIdx));
 | 
			
		||||
			port(Integer.parseInt(rawValue, portSeparatorIdx + 1, rawValue.length(), 10));
 | 
			
		||||
		}
 | 
			
		||||
		else {
 | 
			
		||||
			host(rawValue);
 | 
			
		||||
			port(null);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	private void resetHierarchicalComponents() {
 | 
			
		||||
		this.userInfo = null;
 | 
			
		||||
		this.host = null;
 | 
			
		||||
| 
						 | 
				
			
			@ -924,6 +800,14 @@ public class UriComponentsBuilder implements UriBuilder, Cloneable {
 | 
			
		|||
		this.ssp = null;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	void resetPortIfDefaultForScheme() {
 | 
			
		||||
		if (this.scheme != null &&
 | 
			
		||||
				(((this.scheme.equals("http") || this.scheme.equals("ws")) && "80".equals(this.port)) ||
 | 
			
		||||
						((this.scheme.equals("https") || this.scheme.equals("wss")) && "443".equals(this.port)))) {
 | 
			
		||||
			port(null);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Public declaration of Object's {@code clone()} method.
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,534 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright 2002-2023 the original author or 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
 | 
			
		||||
 *
 | 
			
		||||
 *      https://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 org.springframework.web.util;
 | 
			
		||||
 | 
			
		||||
import java.net.URI;
 | 
			
		||||
 | 
			
		||||
import org.junit.jupiter.api.Test;
 | 
			
		||||
import org.junit.jupiter.params.ParameterizedTest;
 | 
			
		||||
import org.junit.jupiter.params.provider.ValueSource;
 | 
			
		||||
 | 
			
		||||
import org.springframework.http.HttpHeaders;
 | 
			
		||||
import org.springframework.http.HttpMethod;
 | 
			
		||||
import org.springframework.http.HttpRequest;
 | 
			
		||||
import org.springframework.http.server.ServletServerHttpRequest;
 | 
			
		||||
import org.springframework.web.testfixture.servlet.MockHttpServletRequest;
 | 
			
		||||
 | 
			
		||||
import static org.assertj.core.api.Assertions.assertThat;
 | 
			
		||||
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Unit tests for {@link UriComponentsBuilder}.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Rossen Stoyanchev
 | 
			
		||||
 */
 | 
			
		||||
class ForwardedHeaderUtilsTests {
 | 
			
		||||
 | 
			
		||||
	@Test
 | 
			
		||||
	void fromHttpRequest() {
 | 
			
		||||
		MockHttpServletRequest request = new MockHttpServletRequest();
 | 
			
		||||
		request.setScheme("http");
 | 
			
		||||
		request.setServerName("localhost");
 | 
			
		||||
		request.setServerPort(-1);
 | 
			
		||||
		request.setRequestURI("/path");
 | 
			
		||||
		request.setQueryString("a=1");
 | 
			
		||||
 | 
			
		||||
		ServletServerHttpRequest httpRequest = new ServletServerHttpRequest(request);
 | 
			
		||||
		UriComponents result = ForwardedHeaderUtils.adaptFromForwardedHeaders(httpRequest.getURI(), httpRequest.getHeaders()).build();
 | 
			
		||||
		assertThat(result.getScheme()).isEqualTo("http");
 | 
			
		||||
		assertThat(result.getHost()).isEqualTo("localhost");
 | 
			
		||||
		assertThat(result.getPort()).isEqualTo(-1);
 | 
			
		||||
		assertThat(result.getPath()).isEqualTo("/path");
 | 
			
		||||
		assertThat(result.getQuery()).isEqualTo("a=1");
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@ParameterizedTest // gh-17368, gh-27097
 | 
			
		||||
	@ValueSource(strings = {"https", "wss"})
 | 
			
		||||
	void fromHttpRequestResetsPort443(String protocol) {
 | 
			
		||||
		MockHttpServletRequest request = new MockHttpServletRequest();
 | 
			
		||||
		request.addHeader("X-Forwarded-Proto", protocol);
 | 
			
		||||
		request.addHeader("X-Forwarded-Host", "84.198.58.199");
 | 
			
		||||
		request.addHeader("X-Forwarded-Port", 443);
 | 
			
		||||
		request.setScheme("http");
 | 
			
		||||
		request.setServerName("example.com");
 | 
			
		||||
		request.setServerPort(80);
 | 
			
		||||
		request.setRequestURI("/rest/mobile/users/1");
 | 
			
		||||
 | 
			
		||||
		HttpRequest httpRequest = new ServletServerHttpRequest(request);
 | 
			
		||||
		UriComponents result = ForwardedHeaderUtils.adaptFromForwardedHeaders(httpRequest.getURI(), httpRequest.getHeaders()).build();
 | 
			
		||||
 | 
			
		||||
		assertThat(result.getScheme()).isEqualTo(protocol);
 | 
			
		||||
		assertThat(result.getHost()).isEqualTo("84.198.58.199");
 | 
			
		||||
		assertThat(result.getPort()).isEqualTo(-1);
 | 
			
		||||
		assertThat(result.getPath()).isEqualTo("/rest/mobile/users/1");
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@ParameterizedTest // gh-27097
 | 
			
		||||
	@ValueSource(strings = {"http", "ws"})
 | 
			
		||||
	void fromHttpRequestResetsPort80(String protocol) {
 | 
			
		||||
		MockHttpServletRequest request = new MockHttpServletRequest();
 | 
			
		||||
		request.addHeader("X-Forwarded-Proto", protocol);
 | 
			
		||||
		request.addHeader("X-Forwarded-Host", "84.198.58.199");
 | 
			
		||||
		request.addHeader("X-Forwarded-Port", 80);
 | 
			
		||||
		request.setScheme("http");
 | 
			
		||||
		request.setServerName("example.com");
 | 
			
		||||
		request.setServerPort(80);
 | 
			
		||||
		request.setRequestURI("/path");
 | 
			
		||||
 | 
			
		||||
		HttpRequest httpRequest = new ServletServerHttpRequest(request);
 | 
			
		||||
		UriComponents result = ForwardedHeaderUtils.adaptFromForwardedHeaders(httpRequest.getURI(), httpRequest.getHeaders()).build();
 | 
			
		||||
 | 
			
		||||
		assertThat(result.getScheme()).isEqualTo(protocol);
 | 
			
		||||
		assertThat(result.getHost()).isEqualTo("84.198.58.199");
 | 
			
		||||
		assertThat(result.getPort()).isEqualTo(-1);
 | 
			
		||||
		assertThat(result.getPath()).isEqualTo("/path");
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Test  // SPR-14761
 | 
			
		||||
	void fromHttpRequestWithForwardedIPv4Host() {
 | 
			
		||||
		MockHttpServletRequest request = new MockHttpServletRequest();
 | 
			
		||||
		request.setScheme("https");
 | 
			
		||||
		request.setServerName("localhost");
 | 
			
		||||
		request.setServerPort(-1);
 | 
			
		||||
		request.setRequestURI("/mvc-showcase");
 | 
			
		||||
		request.addHeader("Forwarded", "host=192.168.0.1");
 | 
			
		||||
 | 
			
		||||
		HttpRequest httpRequest = new ServletServerHttpRequest(request);
 | 
			
		||||
		UriComponents result = ForwardedHeaderUtils.adaptFromForwardedHeaders(httpRequest.getURI(), httpRequest.getHeaders()).build();
 | 
			
		||||
 | 
			
		||||
		assertThat(result.toString()).isEqualTo("https://192.168.0.1/mvc-showcase");
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Test  // SPR-14761
 | 
			
		||||
	void fromHttpRequestWithForwardedIPv6() {
 | 
			
		||||
		MockHttpServletRequest request = new MockHttpServletRequest();
 | 
			
		||||
		request.setScheme("http");
 | 
			
		||||
		request.setServerName("localhost");
 | 
			
		||||
		request.setServerPort(-1);
 | 
			
		||||
		request.setRequestURI("/mvc-showcase");
 | 
			
		||||
		request.addHeader("Forwarded", "host=[1abc:2abc:3abc::5ABC:6abc]");
 | 
			
		||||
 | 
			
		||||
		HttpRequest httpRequest = new ServletServerHttpRequest(request);
 | 
			
		||||
		UriComponents result = ForwardedHeaderUtils.adaptFromForwardedHeaders(httpRequest.getURI(), httpRequest.getHeaders()).build();
 | 
			
		||||
 | 
			
		||||
		assertThat(result.toString()).isEqualTo("http://[1abc:2abc:3abc::5ABC:6abc]/mvc-showcase");
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Test  // SPR-14761
 | 
			
		||||
	void fromHttpRequestWithForwardedIPv6Host() {
 | 
			
		||||
		MockHttpServletRequest request = new MockHttpServletRequest();
 | 
			
		||||
		request.setScheme("http");
 | 
			
		||||
		request.setServerName("localhost");
 | 
			
		||||
		request.setServerPort(-1);
 | 
			
		||||
		request.setRequestURI("/mvc-showcase");
 | 
			
		||||
		request.addHeader("X-Forwarded-Host", "[1abc:2abc:3abc::5ABC:6abc]");
 | 
			
		||||
 | 
			
		||||
		HttpRequest httpRequest = new ServletServerHttpRequest(request);
 | 
			
		||||
		UriComponents result = ForwardedHeaderUtils.adaptFromForwardedHeaders(httpRequest.getURI(), httpRequest.getHeaders()).build();
 | 
			
		||||
 | 
			
		||||
		assertThat(result.toString()).isEqualTo("http://[1abc:2abc:3abc::5ABC:6abc]/mvc-showcase");
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Test  // SPR-14761
 | 
			
		||||
	void fromHttpRequestWithForwardedIPv6HostAndPort() {
 | 
			
		||||
		MockHttpServletRequest request = new MockHttpServletRequest();
 | 
			
		||||
		request.setScheme("http");
 | 
			
		||||
		request.setServerName("localhost");
 | 
			
		||||
		request.setServerPort(-1);
 | 
			
		||||
		request.setRequestURI("/mvc-showcase");
 | 
			
		||||
		request.addHeader("X-Forwarded-Host", "[1abc:2abc:3abc::5ABC:6abc]:8080");
 | 
			
		||||
 | 
			
		||||
		HttpRequest httpRequest = new ServletServerHttpRequest(request);
 | 
			
		||||
		UriComponents result = ForwardedHeaderUtils.adaptFromForwardedHeaders(httpRequest.getURI(), httpRequest.getHeaders()).build();
 | 
			
		||||
 | 
			
		||||
		assertThat(result.toString()).isEqualTo("http://[1abc:2abc:3abc::5ABC:6abc]:8080/mvc-showcase");
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Test  // gh-26748
 | 
			
		||||
	void fromHttpRequestWithForwardedInvalidIPv6Address() {
 | 
			
		||||
		MockHttpServletRequest request = new MockHttpServletRequest();
 | 
			
		||||
		request.setScheme("http");
 | 
			
		||||
		request.setServerName("localhost");
 | 
			
		||||
		request.setServerPort(-1);
 | 
			
		||||
		request.setRequestURI("/mvc-showcase");
 | 
			
		||||
		request.addHeader("X-Forwarded-Host", "2a02:918:175:ab60:45ee:c12c:dac1:808b");
 | 
			
		||||
 | 
			
		||||
		HttpRequest httpRequest = new ServletServerHttpRequest(request);
 | 
			
		||||
 | 
			
		||||
		assertThatIllegalArgumentException().isThrownBy(() ->
 | 
			
		||||
				ForwardedHeaderUtils.adaptFromForwardedHeaders(httpRequest.getURI(), httpRequest.getHeaders()).build());
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Test
 | 
			
		||||
	void fromHttpRequestWithForwardedHost() {
 | 
			
		||||
		MockHttpServletRequest request = new MockHttpServletRequest();
 | 
			
		||||
		request.setScheme("https");
 | 
			
		||||
		request.setServerName("localhost");
 | 
			
		||||
		request.setServerPort(-1);
 | 
			
		||||
		request.setRequestURI("/mvc-showcase");
 | 
			
		||||
		request.addHeader("X-Forwarded-Host", "anotherHost");
 | 
			
		||||
 | 
			
		||||
		HttpRequest httpRequest = new ServletServerHttpRequest(request);
 | 
			
		||||
		UriComponents result = ForwardedHeaderUtils.adaptFromForwardedHeaders(httpRequest.getURI(), httpRequest.getHeaders()).build();
 | 
			
		||||
 | 
			
		||||
		assertThat(result.toString()).isEqualTo("https://anotherHost/mvc-showcase");
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Test  // SPR-10701
 | 
			
		||||
	void fromHttpRequestWithForwardedHostIncludingPort() {
 | 
			
		||||
		MockHttpServletRequest request = new MockHttpServletRequest();
 | 
			
		||||
		request.setScheme("http");
 | 
			
		||||
		request.setServerName("localhost");
 | 
			
		||||
		request.setServerPort(-1);
 | 
			
		||||
		request.setRequestURI("/mvc-showcase");
 | 
			
		||||
		request.addHeader("X-Forwarded-Host", "webtest.foo.bar.com:443");
 | 
			
		||||
 | 
			
		||||
		HttpRequest httpRequest = new ServletServerHttpRequest(request);
 | 
			
		||||
		UriComponents result = ForwardedHeaderUtils.adaptFromForwardedHeaders(httpRequest.getURI(), httpRequest.getHeaders()).build();
 | 
			
		||||
 | 
			
		||||
		assertThat(result.getHost()).isEqualTo("webtest.foo.bar.com");
 | 
			
		||||
		assertThat(result.getPort()).isEqualTo(443);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Test  // SPR-11140
 | 
			
		||||
	void fromHttpRequestWithForwardedHostMultiValuedHeader() {
 | 
			
		||||
		MockHttpServletRequest request = new MockHttpServletRequest();
 | 
			
		||||
		request.setScheme("http");
 | 
			
		||||
		request.setServerName("localhost");
 | 
			
		||||
		request.setServerPort(-1);
 | 
			
		||||
		request.addHeader("X-Forwarded-Host", "a.example.org, b.example.org, c.example.org");
 | 
			
		||||
 | 
			
		||||
		HttpRequest httpRequest = new ServletServerHttpRequest(request);
 | 
			
		||||
		UriComponents result = ForwardedHeaderUtils.adaptFromForwardedHeaders(httpRequest.getURI(), httpRequest.getHeaders()).build();
 | 
			
		||||
 | 
			
		||||
		assertThat(result.getHost()).isEqualTo("a.example.org");
 | 
			
		||||
		assertThat(result.getPort()).isEqualTo(-1);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Test  // SPR-11855
 | 
			
		||||
	void fromHttpRequestWithForwardedHostAndPort() {
 | 
			
		||||
		MockHttpServletRequest request = new MockHttpServletRequest();
 | 
			
		||||
		request.setScheme("http");
 | 
			
		||||
		request.setServerName("localhost");
 | 
			
		||||
		request.setServerPort(8080);
 | 
			
		||||
		request.addHeader("X-Forwarded-Host", "foobarhost");
 | 
			
		||||
		request.addHeader("X-Forwarded-Port", "9090");
 | 
			
		||||
 | 
			
		||||
		HttpRequest httpRequest = new ServletServerHttpRequest(request);
 | 
			
		||||
		UriComponents result = ForwardedHeaderUtils.adaptFromForwardedHeaders(httpRequest.getURI(), httpRequest.getHeaders()).build();
 | 
			
		||||
 | 
			
		||||
		assertThat(result.getHost()).isEqualTo("foobarhost");
 | 
			
		||||
		assertThat(result.getPort()).isEqualTo(9090);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Test  // SPR-11872
 | 
			
		||||
	void fromHttpRequestWithForwardedHostWithDefaultPort() {
 | 
			
		||||
		MockHttpServletRequest request = new MockHttpServletRequest();
 | 
			
		||||
		request.setScheme("http");
 | 
			
		||||
		request.setServerName("localhost");
 | 
			
		||||
		request.setServerPort(10080);
 | 
			
		||||
		request.addHeader("X-Forwarded-Host", "example.org");
 | 
			
		||||
 | 
			
		||||
		HttpRequest httpRequest = new ServletServerHttpRequest(request);
 | 
			
		||||
		UriComponents result = ForwardedHeaderUtils.adaptFromForwardedHeaders(httpRequest.getURI(), httpRequest.getHeaders()).build();
 | 
			
		||||
 | 
			
		||||
		assertThat(result.getHost()).isEqualTo("example.org");
 | 
			
		||||
		assertThat(result.getPort()).isEqualTo(-1);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Test  // SPR-16262
 | 
			
		||||
	void fromHttpRequestWithForwardedProtoWithDefaultPort() {
 | 
			
		||||
		MockHttpServletRequest request = new MockHttpServletRequest();
 | 
			
		||||
		request.setScheme("http");
 | 
			
		||||
		request.setServerName("example.org");
 | 
			
		||||
		request.setServerPort(10080);
 | 
			
		||||
		request.addHeader("X-Forwarded-Proto", "https");
 | 
			
		||||
 | 
			
		||||
		HttpRequest httpRequest = new ServletServerHttpRequest(request);
 | 
			
		||||
		UriComponents result = ForwardedHeaderUtils.adaptFromForwardedHeaders(httpRequest.getURI(), httpRequest.getHeaders()).build();
 | 
			
		||||
 | 
			
		||||
		assertThat(result.getScheme()).isEqualTo("https");
 | 
			
		||||
		assertThat(result.getHost()).isEqualTo("example.org");
 | 
			
		||||
		assertThat(result.getPort()).isEqualTo(-1);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Test  // SPR-16863
 | 
			
		||||
	void fromHttpRequestWithForwardedSsl() {
 | 
			
		||||
		MockHttpServletRequest request = new MockHttpServletRequest();
 | 
			
		||||
		request.setScheme("http");
 | 
			
		||||
		request.setServerName("example.org");
 | 
			
		||||
		request.setServerPort(10080);
 | 
			
		||||
		request.addHeader("X-Forwarded-Ssl", "on");
 | 
			
		||||
 | 
			
		||||
		HttpRequest httpRequest = new ServletServerHttpRequest(request);
 | 
			
		||||
		UriComponents result = ForwardedHeaderUtils.adaptFromForwardedHeaders(httpRequest.getURI(), httpRequest.getHeaders()).build();
 | 
			
		||||
 | 
			
		||||
		assertThat(result.getScheme()).isEqualTo("https");
 | 
			
		||||
		assertThat(result.getHost()).isEqualTo("example.org");
 | 
			
		||||
		assertThat(result.getPort()).isEqualTo(-1);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Test
 | 
			
		||||
	void fromHttpRequestWithForwardedHostWithForwardedScheme() {
 | 
			
		||||
		MockHttpServletRequest request = new MockHttpServletRequest();
 | 
			
		||||
		request.setScheme("http");
 | 
			
		||||
		request.setServerName("localhost");
 | 
			
		||||
		request.setServerPort(10080);
 | 
			
		||||
		request.addHeader("X-Forwarded-Host", "example.org");
 | 
			
		||||
		request.addHeader("X-Forwarded-Proto", "https");
 | 
			
		||||
 | 
			
		||||
		HttpRequest httpRequest = new ServletServerHttpRequest(request);
 | 
			
		||||
		UriComponents result = ForwardedHeaderUtils.adaptFromForwardedHeaders(httpRequest.getURI(), httpRequest.getHeaders()).build();
 | 
			
		||||
 | 
			
		||||
		assertThat(result.getHost()).isEqualTo("example.org");
 | 
			
		||||
		assertThat(result.getScheme()).isEqualTo("https");
 | 
			
		||||
		assertThat(result.getPort()).isEqualTo(-1);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Test  // SPR-12771
 | 
			
		||||
	void fromHttpRequestWithForwardedProtoAndDefaultPort() {
 | 
			
		||||
		MockHttpServletRequest request = new MockHttpServletRequest();
 | 
			
		||||
		request.setScheme("http");
 | 
			
		||||
		request.setServerName("localhost");
 | 
			
		||||
		request.setServerPort(80);
 | 
			
		||||
		request.setRequestURI("/mvc-showcase");
 | 
			
		||||
		request.addHeader("X-Forwarded-Proto", "https");
 | 
			
		||||
		request.addHeader("X-Forwarded-Host", "84.198.58.199");
 | 
			
		||||
		request.addHeader("X-Forwarded-Port", "443");
 | 
			
		||||
 | 
			
		||||
		HttpRequest httpRequest = new ServletServerHttpRequest(request);
 | 
			
		||||
		UriComponents result = ForwardedHeaderUtils.adaptFromForwardedHeaders(httpRequest.getURI(), httpRequest.getHeaders()).build();
 | 
			
		||||
 | 
			
		||||
		assertThat(result.toString()).isEqualTo("https://84.198.58.199/mvc-showcase");
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Test  // SPR-12813
 | 
			
		||||
	void fromHttpRequestWithForwardedPortMultiValueHeader() {
 | 
			
		||||
		MockHttpServletRequest request = new MockHttpServletRequest();
 | 
			
		||||
		request.setScheme("http");
 | 
			
		||||
		request.setServerName("localhost");
 | 
			
		||||
		request.setServerPort(9090);
 | 
			
		||||
		request.setRequestURI("/mvc-showcase");
 | 
			
		||||
		request.addHeader("X-Forwarded-Host", "a.example.org");
 | 
			
		||||
		request.addHeader("X-Forwarded-Port", "80,52022");
 | 
			
		||||
 | 
			
		||||
		HttpRequest httpRequest = new ServletServerHttpRequest(request);
 | 
			
		||||
		UriComponents result = ForwardedHeaderUtils.adaptFromForwardedHeaders(httpRequest.getURI(), httpRequest.getHeaders()).build();
 | 
			
		||||
 | 
			
		||||
		assertThat(result.toString()).isEqualTo("http://a.example.org/mvc-showcase");
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Test  // SPR-12816
 | 
			
		||||
	void fromHttpRequestWithForwardedProtoMultiValueHeader() {
 | 
			
		||||
		MockHttpServletRequest request = new MockHttpServletRequest();
 | 
			
		||||
		request.setScheme("http");
 | 
			
		||||
		request.setServerName("localhost");
 | 
			
		||||
		request.setServerPort(8080);
 | 
			
		||||
		request.setRequestURI("/mvc-showcase");
 | 
			
		||||
		request.addHeader("X-Forwarded-Host", "a.example.org");
 | 
			
		||||
		request.addHeader("X-Forwarded-Port", "443");
 | 
			
		||||
		request.addHeader("X-Forwarded-Proto", "https,https");
 | 
			
		||||
 | 
			
		||||
		HttpRequest httpRequest = new ServletServerHttpRequest(request);
 | 
			
		||||
		UriComponents result = ForwardedHeaderUtils.adaptFromForwardedHeaders(httpRequest.getURI(), httpRequest.getHeaders()).build();
 | 
			
		||||
 | 
			
		||||
		assertThat(result.toString()).isEqualTo("https://a.example.org/mvc-showcase");
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Test  // gh-19890
 | 
			
		||||
	void fromHttpRequestWithEmptyScheme() {
 | 
			
		||||
		HttpRequest request = new HttpRequest() {
 | 
			
		||||
			@Override
 | 
			
		||||
			public HttpMethod getMethod() {
 | 
			
		||||
				return HttpMethod.GET;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			@Override
 | 
			
		||||
			public URI getURI() {
 | 
			
		||||
				return UriComponentsBuilder.fromUriString("/").build().toUri();
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			@Override
 | 
			
		||||
			public HttpHeaders getHeaders() {
 | 
			
		||||
				return new HttpHeaders();
 | 
			
		||||
			}
 | 
			
		||||
		};
 | 
			
		||||
		UriComponents result = ForwardedHeaderUtils.adaptFromForwardedHeaders(request.getURI(), request.getHeaders()).build();
 | 
			
		||||
 | 
			
		||||
		assertThat(result.toString()).isEqualTo("/");
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Test  // SPR-11856
 | 
			
		||||
	void fromHttpRequestForwardedHeader()  {
 | 
			
		||||
		MockHttpServletRequest request = new MockHttpServletRequest();
 | 
			
		||||
		request.addHeader("Forwarded", "proto=https; host=84.198.58.199");
 | 
			
		||||
		request.setScheme("http");
 | 
			
		||||
		request.setServerName("example.com");
 | 
			
		||||
		request.setRequestURI("/rest/mobile/users/1");
 | 
			
		||||
 | 
			
		||||
		HttpRequest httpRequest = new ServletServerHttpRequest(request);
 | 
			
		||||
		UriComponents result = ForwardedHeaderUtils.adaptFromForwardedHeaders(httpRequest.getURI(), httpRequest.getHeaders()).build();
 | 
			
		||||
 | 
			
		||||
		assertThat(result.getScheme()).isEqualTo("https");
 | 
			
		||||
		assertThat(result.getHost()).isEqualTo("84.198.58.199");
 | 
			
		||||
		assertThat(result.getPath()).isEqualTo("/rest/mobile/users/1");
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Test
 | 
			
		||||
	void fromHttpRequestForwardedHeaderQuoted()  {
 | 
			
		||||
		MockHttpServletRequest request = new MockHttpServletRequest();
 | 
			
		||||
		request.addHeader("Forwarded", "proto=\"https\"; host=\"84.198.58.199\"");
 | 
			
		||||
		request.setScheme("http");
 | 
			
		||||
		request.setServerName("example.com");
 | 
			
		||||
		request.setRequestURI("/rest/mobile/users/1");
 | 
			
		||||
 | 
			
		||||
		HttpRequest httpRequest = new ServletServerHttpRequest(request);
 | 
			
		||||
		UriComponents result = ForwardedHeaderUtils.adaptFromForwardedHeaders(httpRequest.getURI(), httpRequest.getHeaders()).build();
 | 
			
		||||
 | 
			
		||||
		assertThat(result.getScheme()).isEqualTo("https");
 | 
			
		||||
		assertThat(result.getHost()).isEqualTo("84.198.58.199");
 | 
			
		||||
		assertThat(result.getPath()).isEqualTo("/rest/mobile/users/1");
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Test
 | 
			
		||||
	void fromHttpRequestMultipleForwardedHeader()  {
 | 
			
		||||
		MockHttpServletRequest request = new MockHttpServletRequest();
 | 
			
		||||
		request.addHeader("Forwarded", "host=84.198.58.199;proto=https");
 | 
			
		||||
		request.addHeader("Forwarded", "proto=ftp; host=1.2.3.4");
 | 
			
		||||
		request.setScheme("http");
 | 
			
		||||
		request.setServerName("example.com");
 | 
			
		||||
		request.setRequestURI("/rest/mobile/users/1");
 | 
			
		||||
 | 
			
		||||
		HttpRequest httpRequest = new ServletServerHttpRequest(request);
 | 
			
		||||
		UriComponents result = ForwardedHeaderUtils.adaptFromForwardedHeaders(httpRequest.getURI(), httpRequest.getHeaders()).build();
 | 
			
		||||
 | 
			
		||||
		assertThat(result.getScheme()).isEqualTo("https");
 | 
			
		||||
		assertThat(result.getHost()).isEqualTo("84.198.58.199");
 | 
			
		||||
		assertThat(result.getPath()).isEqualTo("/rest/mobile/users/1");
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Test
 | 
			
		||||
	void fromHttpRequestMultipleForwardedHeaderComma()  {
 | 
			
		||||
		MockHttpServletRequest request = new MockHttpServletRequest();
 | 
			
		||||
		request.addHeader("Forwarded", "host=84.198.58.199 ;proto=https, proto=ftp; host=1.2.3.4");
 | 
			
		||||
		request.setScheme("http");
 | 
			
		||||
		request.setServerName("example.com");
 | 
			
		||||
		request.setRequestURI("/rest/mobile/users/1");
 | 
			
		||||
 | 
			
		||||
		HttpRequest httpRequest = new ServletServerHttpRequest(request);
 | 
			
		||||
		UriComponents result = ForwardedHeaderUtils.adaptFromForwardedHeaders(httpRequest.getURI(), httpRequest.getHeaders()).build();
 | 
			
		||||
 | 
			
		||||
		assertThat(result.getScheme()).isEqualTo("https");
 | 
			
		||||
		assertThat(result.getHost()).isEqualTo("84.198.58.199");
 | 
			
		||||
		assertThat(result.getPath()).isEqualTo("/rest/mobile/users/1");
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Test
 | 
			
		||||
	void fromHttpRequestForwardedHeaderWithHostPortAndWithoutServerPort()  {
 | 
			
		||||
		MockHttpServletRequest request = new MockHttpServletRequest();
 | 
			
		||||
		request.addHeader("Forwarded", "proto=https; host=84.198.58.199:9090");
 | 
			
		||||
		request.setScheme("http");
 | 
			
		||||
		request.setServerName("example.com");
 | 
			
		||||
		request.setRequestURI("/rest/mobile/users/1");
 | 
			
		||||
 | 
			
		||||
		HttpRequest httpRequest = new ServletServerHttpRequest(request);
 | 
			
		||||
		UriComponents result = ForwardedHeaderUtils.adaptFromForwardedHeaders(httpRequest.getURI(), httpRequest.getHeaders()).build();
 | 
			
		||||
 | 
			
		||||
		assertThat(result.getScheme()).isEqualTo("https");
 | 
			
		||||
		assertThat(result.getHost()).isEqualTo("84.198.58.199");
 | 
			
		||||
		assertThat(result.getPath()).isEqualTo("/rest/mobile/users/1");
 | 
			
		||||
		assertThat(result.getPort()).isEqualTo(9090);
 | 
			
		||||
		assertThat(result.toUriString()).isEqualTo("https://84.198.58.199:9090/rest/mobile/users/1");
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Test
 | 
			
		||||
	void fromHttpRequestForwardedHeaderWithHostPortAndServerPort()  {
 | 
			
		||||
		MockHttpServletRequest request = new MockHttpServletRequest();
 | 
			
		||||
		request.addHeader("Forwarded", "proto=https; host=84.198.58.199:9090");
 | 
			
		||||
		request.setScheme("http");
 | 
			
		||||
		request.setServerPort(8080);
 | 
			
		||||
		request.setServerName("example.com");
 | 
			
		||||
		request.setRequestURI("/rest/mobile/users/1");
 | 
			
		||||
 | 
			
		||||
		HttpRequest httpRequest = new ServletServerHttpRequest(request);
 | 
			
		||||
		UriComponents result = ForwardedHeaderUtils.adaptFromForwardedHeaders(httpRequest.getURI(), httpRequest.getHeaders()).build();
 | 
			
		||||
 | 
			
		||||
		assertThat(result.getScheme()).isEqualTo("https");
 | 
			
		||||
		assertThat(result.getHost()).isEqualTo("84.198.58.199");
 | 
			
		||||
		assertThat(result.getPath()).isEqualTo("/rest/mobile/users/1");
 | 
			
		||||
		assertThat(result.getPort()).isEqualTo(9090);
 | 
			
		||||
		assertThat(result.toUriString()).isEqualTo("https://84.198.58.199:9090/rest/mobile/users/1");
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Test
 | 
			
		||||
	void fromHttpRequestForwardedHeaderWithoutHostPortAndWithServerPort()  {
 | 
			
		||||
		MockHttpServletRequest request = new MockHttpServletRequest();
 | 
			
		||||
		request.addHeader("Forwarded", "proto=https; host=84.198.58.199");
 | 
			
		||||
		request.setScheme("http");
 | 
			
		||||
		request.setServerPort(8080);
 | 
			
		||||
		request.setServerName("example.com");
 | 
			
		||||
		request.setRequestURI("/rest/mobile/users/1");
 | 
			
		||||
 | 
			
		||||
		HttpRequest httpRequest = new ServletServerHttpRequest(request);
 | 
			
		||||
		UriComponents result = ForwardedHeaderUtils.adaptFromForwardedHeaders(httpRequest.getURI(), httpRequest.getHeaders()).build();
 | 
			
		||||
 | 
			
		||||
		assertThat(result.getScheme()).isEqualTo("https");
 | 
			
		||||
		assertThat(result.getHost()).isEqualTo("84.198.58.199");
 | 
			
		||||
		assertThat(result.getPath()).isEqualTo("/rest/mobile/users/1");
 | 
			
		||||
		assertThat(result.getPort()).isEqualTo(-1);
 | 
			
		||||
		assertThat(result.toUriString()).isEqualTo("https://84.198.58.199/rest/mobile/users/1");
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Test  // SPR-16262
 | 
			
		||||
	void fromHttpRequestForwardedHeaderWithProtoAndServerPort()  {
 | 
			
		||||
		MockHttpServletRequest request = new MockHttpServletRequest();
 | 
			
		||||
		request.addHeader("Forwarded", "proto=https");
 | 
			
		||||
		request.setScheme("http");
 | 
			
		||||
		request.setServerPort(8080);
 | 
			
		||||
		request.setServerName("example.com");
 | 
			
		||||
		request.setRequestURI("/rest/mobile/users/1");
 | 
			
		||||
 | 
			
		||||
		HttpRequest httpRequest = new ServletServerHttpRequest(request);
 | 
			
		||||
		UriComponents result = ForwardedHeaderUtils.adaptFromForwardedHeaders(httpRequest.getURI(), httpRequest.getHeaders()).build();
 | 
			
		||||
 | 
			
		||||
		assertThat(result.getScheme()).isEqualTo("https");
 | 
			
		||||
		assertThat(result.getHost()).isEqualTo("example.com");
 | 
			
		||||
		assertThat(result.getPath()).isEqualTo("/rest/mobile/users/1");
 | 
			
		||||
		assertThat(result.getPort()).isEqualTo(-1);
 | 
			
		||||
		assertThat(result.toUriString()).isEqualTo("https://example.com/rest/mobile/users/1");
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Test  // gh-25737
 | 
			
		||||
	void fromHttpRequestForwardedHeaderComma() {
 | 
			
		||||
		MockHttpServletRequest request = new MockHttpServletRequest();
 | 
			
		||||
		request.addHeader("Forwarded", "for=192.0.2.0,for=192.0.2.1;proto=https;host=192.0.2.3:9090");
 | 
			
		||||
		request.setScheme("http");
 | 
			
		||||
		request.setServerPort(8080);
 | 
			
		||||
		request.setServerName("example.com");
 | 
			
		||||
		request.setRequestURI("/rest/mobile/users/1");
 | 
			
		||||
 | 
			
		||||
		HttpRequest httpRequest = new ServletServerHttpRequest(request);
 | 
			
		||||
		UriComponents result = ForwardedHeaderUtils.adaptFromForwardedHeaders(httpRequest.getURI(), httpRequest.getHeaders()).build();
 | 
			
		||||
 | 
			
		||||
		assertThat(result.getScheme()).isEqualTo("https");
 | 
			
		||||
		assertThat(result.getHost()).isEqualTo("192.0.2.3");
 | 
			
		||||
		assertThat(result.getPath()).isEqualTo("/rest/mobile/users/1");
 | 
			
		||||
		assertThat(result.getPort()).isEqualTo(9090);
 | 
			
		||||
		assertThat(result.toUriString()).isEqualTo("https://192.0.2.3:9090/rest/mobile/users/1");
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -27,16 +27,9 @@ import java.util.Optional;
 | 
			
		|||
import java.util.function.BiConsumer;
 | 
			
		||||
 | 
			
		||||
import org.junit.jupiter.api.Test;
 | 
			
		||||
import org.junit.jupiter.params.ParameterizedTest;
 | 
			
		||||
import org.junit.jupiter.params.provider.ValueSource;
 | 
			
		||||
 | 
			
		||||
import org.springframework.http.HttpHeaders;
 | 
			
		||||
import org.springframework.http.HttpMethod;
 | 
			
		||||
import org.springframework.http.HttpRequest;
 | 
			
		||||
import org.springframework.http.server.ServletServerHttpRequest;
 | 
			
		||||
import org.springframework.util.LinkedMultiValueMap;
 | 
			
		||||
import org.springframework.util.MultiValueMap;
 | 
			
		||||
import org.springframework.web.testfixture.servlet.MockHttpServletRequest;
 | 
			
		||||
 | 
			
		||||
import static org.assertj.core.api.Assertions.assertThat;
 | 
			
		||||
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
 | 
			
		||||
| 
						 | 
				
			
			@ -359,316 +352,6 @@ class UriComponentsBuilderTests {
 | 
			
		|||
		assertThat(uriComponents.toUri().toString()).isEqualTo(httpUrl);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Test
 | 
			
		||||
	void fromHttpRequest() {
 | 
			
		||||
		MockHttpServletRequest request = new MockHttpServletRequest();
 | 
			
		||||
		request.setScheme("http");
 | 
			
		||||
		request.setServerName("localhost");
 | 
			
		||||
		request.setServerPort(-1);
 | 
			
		||||
		request.setRequestURI("/path");
 | 
			
		||||
		request.setQueryString("a=1");
 | 
			
		||||
 | 
			
		||||
		UriComponents result = UriComponentsBuilder.fromHttpRequest(new ServletServerHttpRequest(request)).build();
 | 
			
		||||
		assertThat(result.getScheme()).isEqualTo("http");
 | 
			
		||||
		assertThat(result.getHost()).isEqualTo("localhost");
 | 
			
		||||
		assertThat(result.getPort()).isEqualTo(-1);
 | 
			
		||||
		assertThat(result.getPath()).isEqualTo("/path");
 | 
			
		||||
		assertThat(result.getQuery()).isEqualTo("a=1");
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@ParameterizedTest // gh-17368, gh-27097
 | 
			
		||||
	@ValueSource(strings = {"https", "wss"})
 | 
			
		||||
	void fromHttpRequestResetsPort443(String protocol) {
 | 
			
		||||
		MockHttpServletRequest request = new MockHttpServletRequest();
 | 
			
		||||
		request.addHeader("X-Forwarded-Proto", protocol);
 | 
			
		||||
		request.addHeader("X-Forwarded-Host", "84.198.58.199");
 | 
			
		||||
		request.addHeader("X-Forwarded-Port", 443);
 | 
			
		||||
		request.setScheme("http");
 | 
			
		||||
		request.setServerName("example.com");
 | 
			
		||||
		request.setServerPort(80);
 | 
			
		||||
		request.setRequestURI("/rest/mobile/users/1");
 | 
			
		||||
 | 
			
		||||
		HttpRequest httpRequest = new ServletServerHttpRequest(request);
 | 
			
		||||
		UriComponents result = UriComponentsBuilder.fromHttpRequest(httpRequest).build();
 | 
			
		||||
 | 
			
		||||
		assertThat(result.getScheme()).isEqualTo(protocol);
 | 
			
		||||
		assertThat(result.getHost()).isEqualTo("84.198.58.199");
 | 
			
		||||
		assertThat(result.getPort()).isEqualTo(-1);
 | 
			
		||||
		assertThat(result.getPath()).isEqualTo("/rest/mobile/users/1");
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@ParameterizedTest // gh-27097
 | 
			
		||||
	@ValueSource(strings = {"http", "ws"})
 | 
			
		||||
	void fromHttpRequestResetsPort80(String protocol) {
 | 
			
		||||
		MockHttpServletRequest request = new MockHttpServletRequest();
 | 
			
		||||
		request.addHeader("X-Forwarded-Proto", protocol);
 | 
			
		||||
		request.addHeader("X-Forwarded-Host", "84.198.58.199");
 | 
			
		||||
		request.addHeader("X-Forwarded-Port", 80);
 | 
			
		||||
		request.setScheme("http");
 | 
			
		||||
		request.setServerName("example.com");
 | 
			
		||||
		request.setServerPort(80);
 | 
			
		||||
		request.setRequestURI("/path");
 | 
			
		||||
 | 
			
		||||
		HttpRequest httpRequest = new ServletServerHttpRequest(request);
 | 
			
		||||
		UriComponents result = UriComponentsBuilder.fromHttpRequest(httpRequest).build();
 | 
			
		||||
 | 
			
		||||
		assertThat(result.getScheme()).isEqualTo(protocol);
 | 
			
		||||
		assertThat(result.getHost()).isEqualTo("84.198.58.199");
 | 
			
		||||
		assertThat(result.getPort()).isEqualTo(-1);
 | 
			
		||||
		assertThat(result.getPath()).isEqualTo("/path");
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Test  // SPR-14761
 | 
			
		||||
	void fromHttpRequestWithForwardedIPv4Host() {
 | 
			
		||||
		MockHttpServletRequest request = new MockHttpServletRequest();
 | 
			
		||||
		request.setScheme("https");
 | 
			
		||||
		request.setServerName("localhost");
 | 
			
		||||
		request.setServerPort(-1);
 | 
			
		||||
		request.setRequestURI("/mvc-showcase");
 | 
			
		||||
		request.addHeader("Forwarded", "host=192.168.0.1");
 | 
			
		||||
 | 
			
		||||
		HttpRequest httpRequest = new ServletServerHttpRequest(request);
 | 
			
		||||
		UriComponents result = UriComponentsBuilder.fromHttpRequest(httpRequest).build();
 | 
			
		||||
 | 
			
		||||
		assertThat(result.toString()).isEqualTo("https://192.168.0.1/mvc-showcase");
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Test  // SPR-14761
 | 
			
		||||
	void fromHttpRequestWithForwardedIPv6() {
 | 
			
		||||
		MockHttpServletRequest request = new MockHttpServletRequest();
 | 
			
		||||
		request.setScheme("http");
 | 
			
		||||
		request.setServerName("localhost");
 | 
			
		||||
		request.setServerPort(-1);
 | 
			
		||||
		request.setRequestURI("/mvc-showcase");
 | 
			
		||||
		request.addHeader("Forwarded", "host=[1abc:2abc:3abc::5ABC:6abc]");
 | 
			
		||||
 | 
			
		||||
		HttpRequest httpRequest = new ServletServerHttpRequest(request);
 | 
			
		||||
		UriComponents result = UriComponentsBuilder.fromHttpRequest(httpRequest).build();
 | 
			
		||||
 | 
			
		||||
		assertThat(result.toString()).isEqualTo("http://[1abc:2abc:3abc::5ABC:6abc]/mvc-showcase");
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Test  // SPR-14761
 | 
			
		||||
	void fromHttpRequestWithForwardedIPv6Host() {
 | 
			
		||||
		MockHttpServletRequest request = new MockHttpServletRequest();
 | 
			
		||||
		request.setScheme("http");
 | 
			
		||||
		request.setServerName("localhost");
 | 
			
		||||
		request.setServerPort(-1);
 | 
			
		||||
		request.setRequestURI("/mvc-showcase");
 | 
			
		||||
		request.addHeader("X-Forwarded-Host", "[1abc:2abc:3abc::5ABC:6abc]");
 | 
			
		||||
 | 
			
		||||
		HttpRequest httpRequest = new ServletServerHttpRequest(request);
 | 
			
		||||
		UriComponents result = UriComponentsBuilder.fromHttpRequest(httpRequest).build();
 | 
			
		||||
 | 
			
		||||
		assertThat(result.toString()).isEqualTo("http://[1abc:2abc:3abc::5ABC:6abc]/mvc-showcase");
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Test  // SPR-14761
 | 
			
		||||
	void fromHttpRequestWithForwardedIPv6HostAndPort() {
 | 
			
		||||
		MockHttpServletRequest request = new MockHttpServletRequest();
 | 
			
		||||
		request.setScheme("http");
 | 
			
		||||
		request.setServerName("localhost");
 | 
			
		||||
		request.setServerPort(-1);
 | 
			
		||||
		request.setRequestURI("/mvc-showcase");
 | 
			
		||||
		request.addHeader("X-Forwarded-Host", "[1abc:2abc:3abc::5ABC:6abc]:8080");
 | 
			
		||||
 | 
			
		||||
		HttpRequest httpRequest = new ServletServerHttpRequest(request);
 | 
			
		||||
		UriComponents result = UriComponentsBuilder.fromHttpRequest(httpRequest).build();
 | 
			
		||||
 | 
			
		||||
		assertThat(result.toString()).isEqualTo("http://[1abc:2abc:3abc::5ABC:6abc]:8080/mvc-showcase");
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Test  // gh-26748
 | 
			
		||||
	void fromHttpRequestWithForwardedInvalidIPv6Address() {
 | 
			
		||||
		MockHttpServletRequest request = new MockHttpServletRequest();
 | 
			
		||||
		request.setScheme("http");
 | 
			
		||||
		request.setServerName("localhost");
 | 
			
		||||
		request.setServerPort(-1);
 | 
			
		||||
		request.setRequestURI("/mvc-showcase");
 | 
			
		||||
		request.addHeader("X-Forwarded-Host", "2a02:918:175:ab60:45ee:c12c:dac1:808b");
 | 
			
		||||
 | 
			
		||||
		HttpRequest httpRequest = new ServletServerHttpRequest(request);
 | 
			
		||||
 | 
			
		||||
		assertThatIllegalArgumentException().isThrownBy(() ->
 | 
			
		||||
				UriComponentsBuilder.fromHttpRequest(httpRequest).build());
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Test
 | 
			
		||||
	void fromHttpRequestWithForwardedHost() {
 | 
			
		||||
		MockHttpServletRequest request = new MockHttpServletRequest();
 | 
			
		||||
		request.setScheme("https");
 | 
			
		||||
		request.setServerName("localhost");
 | 
			
		||||
		request.setServerPort(-1);
 | 
			
		||||
		request.setRequestURI("/mvc-showcase");
 | 
			
		||||
		request.addHeader("X-Forwarded-Host", "anotherHost");
 | 
			
		||||
 | 
			
		||||
		HttpRequest httpRequest = new ServletServerHttpRequest(request);
 | 
			
		||||
		UriComponents result = UriComponentsBuilder.fromHttpRequest(httpRequest).build();
 | 
			
		||||
 | 
			
		||||
		assertThat(result.toString()).isEqualTo("https://anotherHost/mvc-showcase");
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Test  // SPR-10701
 | 
			
		||||
	void fromHttpRequestWithForwardedHostIncludingPort() {
 | 
			
		||||
		MockHttpServletRequest request = new MockHttpServletRequest();
 | 
			
		||||
		request.setScheme("http");
 | 
			
		||||
		request.setServerName("localhost");
 | 
			
		||||
		request.setServerPort(-1);
 | 
			
		||||
		request.setRequestURI("/mvc-showcase");
 | 
			
		||||
		request.addHeader("X-Forwarded-Host", "webtest.foo.bar.com:443");
 | 
			
		||||
 | 
			
		||||
		HttpRequest httpRequest = new ServletServerHttpRequest(request);
 | 
			
		||||
		UriComponents result = UriComponentsBuilder.fromHttpRequest(httpRequest).build();
 | 
			
		||||
 | 
			
		||||
		assertThat(result.getHost()).isEqualTo("webtest.foo.bar.com");
 | 
			
		||||
		assertThat(result.getPort()).isEqualTo(443);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Test  // SPR-11140
 | 
			
		||||
	void fromHttpRequestWithForwardedHostMultiValuedHeader() {
 | 
			
		||||
		MockHttpServletRequest request = new MockHttpServletRequest();
 | 
			
		||||
		request.setScheme("http");
 | 
			
		||||
		request.setServerName("localhost");
 | 
			
		||||
		request.setServerPort(-1);
 | 
			
		||||
		request.addHeader("X-Forwarded-Host", "a.example.org, b.example.org, c.example.org");
 | 
			
		||||
 | 
			
		||||
		HttpRequest httpRequest = new ServletServerHttpRequest(request);
 | 
			
		||||
		UriComponents result = UriComponentsBuilder.fromHttpRequest(httpRequest).build();
 | 
			
		||||
 | 
			
		||||
		assertThat(result.getHost()).isEqualTo("a.example.org");
 | 
			
		||||
		assertThat(result.getPort()).isEqualTo(-1);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Test  // SPR-11855
 | 
			
		||||
	void fromHttpRequestWithForwardedHostAndPort() {
 | 
			
		||||
		MockHttpServletRequest request = new MockHttpServletRequest();
 | 
			
		||||
		request.setScheme("http");
 | 
			
		||||
		request.setServerName("localhost");
 | 
			
		||||
		request.setServerPort(8080);
 | 
			
		||||
		request.addHeader("X-Forwarded-Host", "foobarhost");
 | 
			
		||||
		request.addHeader("X-Forwarded-Port", "9090");
 | 
			
		||||
 | 
			
		||||
		HttpRequest httpRequest = new ServletServerHttpRequest(request);
 | 
			
		||||
		UriComponents result = UriComponentsBuilder.fromHttpRequest(httpRequest).build();
 | 
			
		||||
 | 
			
		||||
		assertThat(result.getHost()).isEqualTo("foobarhost");
 | 
			
		||||
		assertThat(result.getPort()).isEqualTo(9090);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Test  // SPR-11872
 | 
			
		||||
	void fromHttpRequestWithForwardedHostWithDefaultPort() {
 | 
			
		||||
		MockHttpServletRequest request = new MockHttpServletRequest();
 | 
			
		||||
		request.setScheme("http");
 | 
			
		||||
		request.setServerName("localhost");
 | 
			
		||||
		request.setServerPort(10080);
 | 
			
		||||
		request.addHeader("X-Forwarded-Host", "example.org");
 | 
			
		||||
 | 
			
		||||
		HttpRequest httpRequest = new ServletServerHttpRequest(request);
 | 
			
		||||
		UriComponents result = UriComponentsBuilder.fromHttpRequest(httpRequest).build();
 | 
			
		||||
 | 
			
		||||
		assertThat(result.getHost()).isEqualTo("example.org");
 | 
			
		||||
		assertThat(result.getPort()).isEqualTo(-1);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Test  // SPR-16262
 | 
			
		||||
	void fromHttpRequestWithForwardedProtoWithDefaultPort() {
 | 
			
		||||
		MockHttpServletRequest request = new MockHttpServletRequest();
 | 
			
		||||
		request.setScheme("http");
 | 
			
		||||
		request.setServerName("example.org");
 | 
			
		||||
		request.setServerPort(10080);
 | 
			
		||||
		request.addHeader("X-Forwarded-Proto", "https");
 | 
			
		||||
 | 
			
		||||
		HttpRequest httpRequest = new ServletServerHttpRequest(request);
 | 
			
		||||
		UriComponents result = UriComponentsBuilder.fromHttpRequest(httpRequest).build();
 | 
			
		||||
 | 
			
		||||
		assertThat(result.getScheme()).isEqualTo("https");
 | 
			
		||||
		assertThat(result.getHost()).isEqualTo("example.org");
 | 
			
		||||
		assertThat(result.getPort()).isEqualTo(-1);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Test  // SPR-16863
 | 
			
		||||
	void fromHttpRequestWithForwardedSsl() {
 | 
			
		||||
		MockHttpServletRequest request = new MockHttpServletRequest();
 | 
			
		||||
		request.setScheme("http");
 | 
			
		||||
		request.setServerName("example.org");
 | 
			
		||||
		request.setServerPort(10080);
 | 
			
		||||
		request.addHeader("X-Forwarded-Ssl", "on");
 | 
			
		||||
 | 
			
		||||
		HttpRequest httpRequest = new ServletServerHttpRequest(request);
 | 
			
		||||
		UriComponents result = UriComponentsBuilder.fromHttpRequest(httpRequest).build();
 | 
			
		||||
 | 
			
		||||
		assertThat(result.getScheme()).isEqualTo("https");
 | 
			
		||||
		assertThat(result.getHost()).isEqualTo("example.org");
 | 
			
		||||
		assertThat(result.getPort()).isEqualTo(-1);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Test
 | 
			
		||||
	void fromHttpRequestWithForwardedHostWithForwardedScheme() {
 | 
			
		||||
		MockHttpServletRequest request = new MockHttpServletRequest();
 | 
			
		||||
		request.setScheme("http");
 | 
			
		||||
		request.setServerName("localhost");
 | 
			
		||||
		request.setServerPort(10080);
 | 
			
		||||
		request.addHeader("X-Forwarded-Host", "example.org");
 | 
			
		||||
		request.addHeader("X-Forwarded-Proto", "https");
 | 
			
		||||
 | 
			
		||||
		HttpRequest httpRequest = new ServletServerHttpRequest(request);
 | 
			
		||||
		UriComponents result = UriComponentsBuilder.fromHttpRequest(httpRequest).build();
 | 
			
		||||
 | 
			
		||||
		assertThat(result.getHost()).isEqualTo("example.org");
 | 
			
		||||
		assertThat(result.getScheme()).isEqualTo("https");
 | 
			
		||||
		assertThat(result.getPort()).isEqualTo(-1);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Test  // SPR-12771
 | 
			
		||||
	void fromHttpRequestWithForwardedProtoAndDefaultPort() {
 | 
			
		||||
		MockHttpServletRequest request = new MockHttpServletRequest();
 | 
			
		||||
		request.setScheme("http");
 | 
			
		||||
		request.setServerName("localhost");
 | 
			
		||||
		request.setServerPort(80);
 | 
			
		||||
		request.setRequestURI("/mvc-showcase");
 | 
			
		||||
		request.addHeader("X-Forwarded-Proto", "https");
 | 
			
		||||
		request.addHeader("X-Forwarded-Host", "84.198.58.199");
 | 
			
		||||
		request.addHeader("X-Forwarded-Port", "443");
 | 
			
		||||
 | 
			
		||||
		HttpRequest httpRequest = new ServletServerHttpRequest(request);
 | 
			
		||||
		UriComponents result = UriComponentsBuilder.fromHttpRequest(httpRequest).build();
 | 
			
		||||
 | 
			
		||||
		assertThat(result.toString()).isEqualTo("https://84.198.58.199/mvc-showcase");
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Test  // SPR-12813
 | 
			
		||||
	void fromHttpRequestWithForwardedPortMultiValueHeader() {
 | 
			
		||||
		MockHttpServletRequest request = new MockHttpServletRequest();
 | 
			
		||||
		request.setScheme("http");
 | 
			
		||||
		request.setServerName("localhost");
 | 
			
		||||
		request.setServerPort(9090);
 | 
			
		||||
		request.setRequestURI("/mvc-showcase");
 | 
			
		||||
		request.addHeader("X-Forwarded-Host", "a.example.org");
 | 
			
		||||
		request.addHeader("X-Forwarded-Port", "80,52022");
 | 
			
		||||
 | 
			
		||||
		HttpRequest httpRequest = new ServletServerHttpRequest(request);
 | 
			
		||||
		UriComponents result = UriComponentsBuilder.fromHttpRequest(httpRequest).build();
 | 
			
		||||
 | 
			
		||||
		assertThat(result.toString()).isEqualTo("http://a.example.org/mvc-showcase");
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Test  // SPR-12816
 | 
			
		||||
	void fromHttpRequestWithForwardedProtoMultiValueHeader() {
 | 
			
		||||
		MockHttpServletRequest request = new MockHttpServletRequest();
 | 
			
		||||
		request.setScheme("http");
 | 
			
		||||
		request.setServerName("localhost");
 | 
			
		||||
		request.setServerPort(8080);
 | 
			
		||||
		request.setRequestURI("/mvc-showcase");
 | 
			
		||||
		request.addHeader("X-Forwarded-Host", "a.example.org");
 | 
			
		||||
		request.addHeader("X-Forwarded-Port", "443");
 | 
			
		||||
		request.addHeader("X-Forwarded-Proto", "https,https");
 | 
			
		||||
 | 
			
		||||
		HttpRequest httpRequest = new ServletServerHttpRequest(request);
 | 
			
		||||
		UriComponents result = UriComponentsBuilder.fromHttpRequest(httpRequest).build();
 | 
			
		||||
 | 
			
		||||
		assertThat(result.toString()).isEqualTo("https://a.example.org/mvc-showcase");
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Test  // SPR-12742
 | 
			
		||||
	void fromHttpRequestWithTrailingSlash() {
 | 
			
		||||
		UriComponents before = UriComponentsBuilder.fromPath("/foo/").build();
 | 
			
		||||
| 
						 | 
				
			
			@ -676,29 +359,6 @@ class UriComponentsBuilderTests {
 | 
			
		|||
		assertThat(after.getPath()).isEqualTo("/foo/");
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Test  // gh-19890
 | 
			
		||||
	void fromHttpRequestWithEmptyScheme() {
 | 
			
		||||
		HttpRequest request = new HttpRequest() {
 | 
			
		||||
			@Override
 | 
			
		||||
			public HttpMethod getMethod() {
 | 
			
		||||
				return HttpMethod.GET;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			@Override
 | 
			
		||||
			public URI getURI() {
 | 
			
		||||
				return UriComponentsBuilder.fromUriString("/").build().toUri();
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			@Override
 | 
			
		||||
			public HttpHeaders getHeaders() {
 | 
			
		||||
				return new HttpHeaders();
 | 
			
		||||
			}
 | 
			
		||||
		};
 | 
			
		||||
		UriComponents result = UriComponentsBuilder.fromHttpRequest(request).build();
 | 
			
		||||
 | 
			
		||||
		assertThat(result.toString()).isEqualTo("/");
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Test
 | 
			
		||||
	void path() {
 | 
			
		||||
		UriComponentsBuilder builder = UriComponentsBuilder.fromPath("/foo/bar");
 | 
			
		||||
| 
						 | 
				
			
			@ -1107,166 +767,6 @@ class UriComponentsBuilderTests {
 | 
			
		|||
		tester.accept("/a{year:\\d{1,4}}b", "/a{year:\\d{1,4}}b");
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Test  // SPR-11856
 | 
			
		||||
	void fromHttpRequestForwardedHeader()  {
 | 
			
		||||
		MockHttpServletRequest request = new MockHttpServletRequest();
 | 
			
		||||
		request.addHeader("Forwarded", "proto=https; host=84.198.58.199");
 | 
			
		||||
		request.setScheme("http");
 | 
			
		||||
		request.setServerName("example.com");
 | 
			
		||||
		request.setRequestURI("/rest/mobile/users/1");
 | 
			
		||||
 | 
			
		||||
		HttpRequest httpRequest = new ServletServerHttpRequest(request);
 | 
			
		||||
		UriComponents result = UriComponentsBuilder.fromHttpRequest(httpRequest).build();
 | 
			
		||||
 | 
			
		||||
		assertThat(result.getScheme()).isEqualTo("https");
 | 
			
		||||
		assertThat(result.getHost()).isEqualTo("84.198.58.199");
 | 
			
		||||
		assertThat(result.getPath()).isEqualTo("/rest/mobile/users/1");
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Test
 | 
			
		||||
	void fromHttpRequestForwardedHeaderQuoted()  {
 | 
			
		||||
		MockHttpServletRequest request = new MockHttpServletRequest();
 | 
			
		||||
		request.addHeader("Forwarded", "proto=\"https\"; host=\"84.198.58.199\"");
 | 
			
		||||
		request.setScheme("http");
 | 
			
		||||
		request.setServerName("example.com");
 | 
			
		||||
		request.setRequestURI("/rest/mobile/users/1");
 | 
			
		||||
 | 
			
		||||
		HttpRequest httpRequest = new ServletServerHttpRequest(request);
 | 
			
		||||
		UriComponents result = UriComponentsBuilder.fromHttpRequest(httpRequest).build();
 | 
			
		||||
 | 
			
		||||
		assertThat(result.getScheme()).isEqualTo("https");
 | 
			
		||||
		assertThat(result.getHost()).isEqualTo("84.198.58.199");
 | 
			
		||||
		assertThat(result.getPath()).isEqualTo("/rest/mobile/users/1");
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Test
 | 
			
		||||
	void fromHttpRequestMultipleForwardedHeader()  {
 | 
			
		||||
		MockHttpServletRequest request = new MockHttpServletRequest();
 | 
			
		||||
		request.addHeader("Forwarded", "host=84.198.58.199;proto=https");
 | 
			
		||||
		request.addHeader("Forwarded", "proto=ftp; host=1.2.3.4");
 | 
			
		||||
		request.setScheme("http");
 | 
			
		||||
		request.setServerName("example.com");
 | 
			
		||||
		request.setRequestURI("/rest/mobile/users/1");
 | 
			
		||||
 | 
			
		||||
		HttpRequest httpRequest = new ServletServerHttpRequest(request);
 | 
			
		||||
		UriComponents result = UriComponentsBuilder.fromHttpRequest(httpRequest).build();
 | 
			
		||||
 | 
			
		||||
		assertThat(result.getScheme()).isEqualTo("https");
 | 
			
		||||
		assertThat(result.getHost()).isEqualTo("84.198.58.199");
 | 
			
		||||
		assertThat(result.getPath()).isEqualTo("/rest/mobile/users/1");
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Test
 | 
			
		||||
	void fromHttpRequestMultipleForwardedHeaderComma()  {
 | 
			
		||||
		MockHttpServletRequest request = new MockHttpServletRequest();
 | 
			
		||||
		request.addHeader("Forwarded", "host=84.198.58.199 ;proto=https, proto=ftp; host=1.2.3.4");
 | 
			
		||||
		request.setScheme("http");
 | 
			
		||||
		request.setServerName("example.com");
 | 
			
		||||
		request.setRequestURI("/rest/mobile/users/1");
 | 
			
		||||
 | 
			
		||||
		HttpRequest httpRequest = new ServletServerHttpRequest(request);
 | 
			
		||||
		UriComponents result = UriComponentsBuilder.fromHttpRequest(httpRequest).build();
 | 
			
		||||
 | 
			
		||||
		assertThat(result.getScheme()).isEqualTo("https");
 | 
			
		||||
		assertThat(result.getHost()).isEqualTo("84.198.58.199");
 | 
			
		||||
		assertThat(result.getPath()).isEqualTo("/rest/mobile/users/1");
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Test
 | 
			
		||||
	void fromHttpRequestForwardedHeaderWithHostPortAndWithoutServerPort()  {
 | 
			
		||||
		MockHttpServletRequest request = new MockHttpServletRequest();
 | 
			
		||||
		request.addHeader("Forwarded", "proto=https; host=84.198.58.199:9090");
 | 
			
		||||
		request.setScheme("http");
 | 
			
		||||
		request.setServerName("example.com");
 | 
			
		||||
		request.setRequestURI("/rest/mobile/users/1");
 | 
			
		||||
 | 
			
		||||
		HttpRequest httpRequest = new ServletServerHttpRequest(request);
 | 
			
		||||
		UriComponents result = UriComponentsBuilder.fromHttpRequest(httpRequest).build();
 | 
			
		||||
 | 
			
		||||
		assertThat(result.getScheme()).isEqualTo("https");
 | 
			
		||||
		assertThat(result.getHost()).isEqualTo("84.198.58.199");
 | 
			
		||||
		assertThat(result.getPath()).isEqualTo("/rest/mobile/users/1");
 | 
			
		||||
		assertThat(result.getPort()).isEqualTo(9090);
 | 
			
		||||
		assertThat(result.toUriString()).isEqualTo("https://84.198.58.199:9090/rest/mobile/users/1");
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Test
 | 
			
		||||
	void fromHttpRequestForwardedHeaderWithHostPortAndServerPort()  {
 | 
			
		||||
		MockHttpServletRequest request = new MockHttpServletRequest();
 | 
			
		||||
		request.addHeader("Forwarded", "proto=https; host=84.198.58.199:9090");
 | 
			
		||||
		request.setScheme("http");
 | 
			
		||||
		request.setServerPort(8080);
 | 
			
		||||
		request.setServerName("example.com");
 | 
			
		||||
		request.setRequestURI("/rest/mobile/users/1");
 | 
			
		||||
 | 
			
		||||
		HttpRequest httpRequest = new ServletServerHttpRequest(request);
 | 
			
		||||
		UriComponents result = UriComponentsBuilder.fromHttpRequest(httpRequest).build();
 | 
			
		||||
 | 
			
		||||
		assertThat(result.getScheme()).isEqualTo("https");
 | 
			
		||||
		assertThat(result.getHost()).isEqualTo("84.198.58.199");
 | 
			
		||||
		assertThat(result.getPath()).isEqualTo("/rest/mobile/users/1");
 | 
			
		||||
		assertThat(result.getPort()).isEqualTo(9090);
 | 
			
		||||
		assertThat(result.toUriString()).isEqualTo("https://84.198.58.199:9090/rest/mobile/users/1");
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Test
 | 
			
		||||
	void fromHttpRequestForwardedHeaderWithoutHostPortAndWithServerPort()  {
 | 
			
		||||
		MockHttpServletRequest request = new MockHttpServletRequest();
 | 
			
		||||
		request.addHeader("Forwarded", "proto=https; host=84.198.58.199");
 | 
			
		||||
		request.setScheme("http");
 | 
			
		||||
		request.setServerPort(8080);
 | 
			
		||||
		request.setServerName("example.com");
 | 
			
		||||
		request.setRequestURI("/rest/mobile/users/1");
 | 
			
		||||
 | 
			
		||||
		HttpRequest httpRequest = new ServletServerHttpRequest(request);
 | 
			
		||||
		UriComponents result = UriComponentsBuilder.fromHttpRequest(httpRequest).build();
 | 
			
		||||
 | 
			
		||||
		assertThat(result.getScheme()).isEqualTo("https");
 | 
			
		||||
		assertThat(result.getHost()).isEqualTo("84.198.58.199");
 | 
			
		||||
		assertThat(result.getPath()).isEqualTo("/rest/mobile/users/1");
 | 
			
		||||
		assertThat(result.getPort()).isEqualTo(-1);
 | 
			
		||||
		assertThat(result.toUriString()).isEqualTo("https://84.198.58.199/rest/mobile/users/1");
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Test  // SPR-16262
 | 
			
		||||
	void fromHttpRequestForwardedHeaderWithProtoAndServerPort()  {
 | 
			
		||||
		MockHttpServletRequest request = new MockHttpServletRequest();
 | 
			
		||||
		request.addHeader("Forwarded", "proto=https");
 | 
			
		||||
		request.setScheme("http");
 | 
			
		||||
		request.setServerPort(8080);
 | 
			
		||||
		request.setServerName("example.com");
 | 
			
		||||
		request.setRequestURI("/rest/mobile/users/1");
 | 
			
		||||
 | 
			
		||||
		HttpRequest httpRequest = new ServletServerHttpRequest(request);
 | 
			
		||||
		UriComponents result = UriComponentsBuilder.fromHttpRequest(httpRequest).build();
 | 
			
		||||
 | 
			
		||||
		assertThat(result.getScheme()).isEqualTo("https");
 | 
			
		||||
		assertThat(result.getHost()).isEqualTo("example.com");
 | 
			
		||||
		assertThat(result.getPath()).isEqualTo("/rest/mobile/users/1");
 | 
			
		||||
		assertThat(result.getPort()).isEqualTo(-1);
 | 
			
		||||
		assertThat(result.toUriString()).isEqualTo("https://example.com/rest/mobile/users/1");
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Test  // gh-25737
 | 
			
		||||
	void fromHttpRequestForwardedHeaderComma() {
 | 
			
		||||
		MockHttpServletRequest request = new MockHttpServletRequest();
 | 
			
		||||
		request.addHeader("Forwarded", "for=192.0.2.0,for=192.0.2.1;proto=https;host=192.0.2.3:9090");
 | 
			
		||||
		request.setScheme("http");
 | 
			
		||||
		request.setServerPort(8080);
 | 
			
		||||
		request.setServerName("example.com");
 | 
			
		||||
		request.setRequestURI("/rest/mobile/users/1");
 | 
			
		||||
 | 
			
		||||
		HttpRequest httpRequest = new ServletServerHttpRequest(request);
 | 
			
		||||
		UriComponents result = UriComponentsBuilder.fromHttpRequest(httpRequest).build();
 | 
			
		||||
 | 
			
		||||
		assertThat(result.getScheme()).isEqualTo("https");
 | 
			
		||||
		assertThat(result.getHost()).isEqualTo("192.0.2.3");
 | 
			
		||||
		assertThat(result.getPath()).isEqualTo("/rest/mobile/users/1");
 | 
			
		||||
		assertThat(result.getPort()).isEqualTo(9090);
 | 
			
		||||
		assertThat(result.toUriString()).isEqualTo("https://192.0.2.3:9090/rest/mobile/users/1");
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	@Test  // SPR-16364
 | 
			
		||||
	void uriComponentsNotEqualAfterNormalization() {
 | 
			
		||||
		UriComponents uri1 = UriComponentsBuilder.fromUriString("http://test.com").build().normalize();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue