Polishing in HtmlUnitRequestBuilder

Order methods according to Spring Framework conventions.
Order request initialization by URI component.

See gh-27837
This commit is contained in:
rstoyanchev 2022-01-11 14:33:12 +00:00
parent 29fe109440
commit 9346c89f5c
1 changed files with 97 additions and 117 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright 2002-2021 the original author or authors.
* Copyright 2002-2022 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,7 +18,6 @@ package org.springframework.test.web.servlet.htmlunit;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.net.URLDecoder;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
@ -32,7 +31,6 @@ import java.util.Map;
import java.util.Set;
import java.util.StringTokenizer;
import com.gargoylesoftware.htmlunit.CookieManager;
import com.gargoylesoftware.htmlunit.FormEncodingType;
import com.gargoylesoftware.htmlunit.WebClient;
import com.gargoylesoftware.htmlunit.WebRequest;
@ -69,6 +67,7 @@ import org.springframework.web.util.UriComponentsBuilder;
*
* @author Rob Winch
* @author Sam Brannen
* @author Rossen Stoyanchev
* @since 4.2
* @see MockMvcWebConnection
*/
@ -111,52 +110,58 @@ final class HtmlUnitRequestBuilder implements RequestBuilder, Mergeable {
}
/**
* Set the contextPath to be used.
* <p>The value may be null in which case the first path segment of the
* URL is turned into the contextPath. Otherwise it must conform to
* {@link HttpServletRequest#getContextPath()} which states it can be
* an empty string, or it must start with a "/" and not end with a "/".
* @param contextPath a valid contextPath
* @throws IllegalArgumentException if the contextPath is not a valid
* {@link HttpServletRequest#getContextPath()}
*/
public void setContextPath(@Nullable String contextPath) {
MockMvcWebConnection.validateContextPath(contextPath);
this.contextPath = contextPath;
}
public void setForwardPostProcessor(RequestPostProcessor forwardPostProcessor) {
this.forwardPostProcessor = forwardPostProcessor;
}
@Override
public MockHttpServletRequest buildRequest(ServletContext servletContext) {
Charset charset = getCharset();
String httpMethod = this.webRequest.getHttpMethod().name();
UriComponents uriComponents = uriComponents();
String path = uriComponents.getPath();
UriComponents uri = UriComponentsBuilder.fromUriString(this.webRequest.getUrl().toExternalForm()).build();
MockHttpServletRequest request =
new HtmlUnitMockHttpServletRequest(servletContext, httpMethod, (path != null ? path : ""));
MockHttpServletRequest request = new HtmlUnitMockHttpServletRequest(
servletContext, httpMethod, (uri.getPath() != null ? uri.getPath() : ""));
parent(request, this.parentBuilder);
String host = uriComponents.getHost();
request.setServerName(host != null ? host : ""); // needs to be first for additional headers
authType(request);
request.setCharacterEncoding(charset.name());
content(request, charset);
contextPath(request, uriComponents);
contentType(request);
cookies(request);
headers(request);
locales(request);
servletPath(uriComponents, request);
params(request, uriComponents);
ports(uriComponents, request);
request.setProtocol("HTTP/1.1");
request.setQueryString(uriComponents.getQuery());
String scheme = uriComponents.getScheme();
request.setScheme(scheme != null ? scheme : "");
request.setScheme(uri.getScheme() != null ? uri.getScheme() : "");
request.setServerName(uri.getHost() != null ? uri.getHost() : ""); // needs to be first for additional headers
ports(uri, request);
authType(request);
contextPath(request, uri);
servletPath(uri, request);
request.setPathInfo(null);
return postProcess(request);
}
private Charset getCharset() {
Charset charset = this.webRequest.getCharset();
return (charset != null ? charset : StandardCharsets.ISO_8859_1);
}
charset = (charset != null ? charset : StandardCharsets.ISO_8859_1);
request.setCharacterEncoding(charset.name());
content(request, charset);
contentType(request);
private MockHttpServletRequest postProcess(MockHttpServletRequest request) {
if (this.parentPostProcessor != null) {
request = this.parentPostProcessor.postProcessRequest(request);
}
if (this.forwardPostProcessor != null) {
request = this.forwardPostProcessor.postProcessRequest(request);
}
return request;
cookies(request);
this.webRequest.getAdditionalHeaders().forEach(request::addHeader);
locales(request);
params(request, uri);
request.setQueryString(uri.getQuery());
return postProcess(request);
}
private void parent(MockHttpServletRequest request, @Nullable RequestBuilder parent) {
@ -208,50 +213,30 @@ final class HtmlUnitRequestBuilder implements RequestBuilder, Mergeable {
}
}
/**
* Set the contextPath to be used.
* <p>The value may be null in which case the first path segment of the
* URL is turned into the contextPath. Otherwise it must conform to
* {@link HttpServletRequest#getContextPath()} which states it can be
* an empty string, or it must start with a "/" and not end with a "/".
* @param contextPath a valid contextPath
* @throws IllegalArgumentException if the contextPath is not a valid
* {@link HttpServletRequest#getContextPath()}
*/
public void setContextPath(@Nullable String contextPath) {
MockMvcWebConnection.validateContextPath(contextPath);
this.contextPath = contextPath;
}
public void setForwardPostProcessor(RequestPostProcessor forwardPostProcessor) {
this.forwardPostProcessor = forwardPostProcessor;
private void ports(UriComponents uriComponents, MockHttpServletRequest request) {
int serverPort = uriComponents.getPort();
request.setServerPort(serverPort);
if (serverPort == -1) {
int portConnection = this.webRequest.getUrl().getDefaultPort();
request.setLocalPort(serverPort);
request.setRemotePort(portConnection);
}
else {
request.setRemotePort(serverPort);
}
}
private void authType(MockHttpServletRequest request) {
String authorization = header("Authorization");
String authorization = getHeader("Authorization");
String[] authSplit = StringUtils.split(authorization, ": ");
if (authSplit != null) {
request.setAuthType(authSplit[0]);
}
}
private void content(MockHttpServletRequest request, Charset charset) {
String requestBody = this.webRequest.getRequestBody();
if (requestBody == null) {
return;
}
request.setContent(requestBody.getBytes(charset));
}
private void contentType(MockHttpServletRequest request) {
String contentType = header("Content-Type");
if (contentType == null) {
FormEncodingType encodingType = this.webRequest.getEncodingType();
if (encodingType != null) {
contentType = encodingType.getName();
}
}
request.setContentType(contentType != null ? contentType : MediaType.ALL_VALUE);
@Nullable
private String getHeader(String headerName) {
return this.webRequest.getAdditionalHeaders().get(headerName);
}
private void contextPath(MockHttpServletRequest request, UriComponents uriComponents) {
@ -273,10 +258,36 @@ final class HtmlUnitRequestBuilder implements RequestBuilder, Mergeable {
}
}
private void servletPath(UriComponents uriComponents, MockHttpServletRequest request) {
String path = uriComponents.getPath();
String requestPath = (path != null ? path : "");
String servletPath = requestPath.substring(request.getContextPath().length());
request.setServletPath(servletPath);
}
private void content(MockHttpServletRequest request, Charset charset) {
String requestBody = this.webRequest.getRequestBody();
if (requestBody == null) {
return;
}
request.setContent(requestBody.getBytes(charset));
}
private void contentType(MockHttpServletRequest request) {
String contentType = getHeader("Content-Type");
if (contentType == null) {
FormEncodingType encodingType = this.webRequest.getEncodingType();
if (encodingType != null) {
contentType = encodingType.getName();
}
}
request.setContentType(contentType != null ? contentType : MediaType.ALL_VALUE);
}
private void cookies(MockHttpServletRequest request) {
List<Cookie> cookies = new ArrayList<>();
String cookieHeaderValue = header("Cookie");
String cookieHeaderValue = getHeader("Cookie");
if (cookieHeaderValue != null) {
StringTokenizer tokens = new StringTokenizer(cookieHeaderValue, "=;");
while (tokens.hasMoreTokens()) {
@ -312,15 +323,6 @@ final class HtmlUnitRequestBuilder implements RequestBuilder, Mergeable {
}
}
@Nullable
private String header(String headerName) {
return this.webRequest.getAdditionalHeaders().get(headerName);
}
private void headers(MockHttpServletRequest request) {
this.webRequest.getAdditionalHeaders().forEach(request::addHeader);
}
private MockHttpSession httpSession(MockHttpServletRequest request, final String sessionid) {
MockHttpSession session;
synchronized (this.sessions) {
@ -341,11 +343,11 @@ final class HtmlUnitRequestBuilder implements RequestBuilder, Mergeable {
}
private void addSessionCookie(MockHttpServletRequest request, String sessionid) {
getCookieManager().addCookie(createCookie(request, sessionid));
this.webClient.getCookieManager().addCookie(createCookie(request, sessionid));
}
private void removeSessionCookie(MockHttpServletRequest request, String sessionid) {
getCookieManager().removeCookie(createCookie(request, sessionid));
this.webClient.getCookieManager().removeCookie(createCookie(request, sessionid));
}
private com.gargoylesoftware.htmlunit.util.Cookie createCookie(MockHttpServletRequest request, String sessionid) {
@ -354,7 +356,7 @@ final class HtmlUnitRequestBuilder implements RequestBuilder, Mergeable {
}
private void locales(MockHttpServletRequest request) {
String locale = header("Accept-Language");
String locale = getHeader("Accept-Language");
if (locale == null) {
request.addPreferredLocale(Locale.getDefault());
}
@ -407,36 +409,18 @@ final class HtmlUnitRequestBuilder implements RequestBuilder, Mergeable {
}
}
private void servletPath(MockHttpServletRequest request, String requestPath) {
String servletPath = requestPath.substring(request.getContextPath().length());
request.setServletPath(servletPath);
private MockHttpServletRequest postProcess(MockHttpServletRequest request) {
if (this.parentPostProcessor != null) {
request = this.parentPostProcessor.postProcessRequest(request);
}
if (this.forwardPostProcessor != null) {
request = this.forwardPostProcessor.postProcessRequest(request);
}
return request;
}
private void servletPath(UriComponents uriComponents, MockHttpServletRequest request) {
if ("".equals(request.getPathInfo())) {
request.setPathInfo(null);
}
String path = uriComponents.getPath();
servletPath(request, (path != null ? path : ""));
}
private void ports(UriComponents uriComponents, MockHttpServletRequest request) {
int serverPort = uriComponents.getPort();
request.setServerPort(serverPort);
if (serverPort == -1) {
int portConnection = this.webRequest.getUrl().getDefaultPort();
request.setLocalPort(serverPort);
request.setRemotePort(portConnection);
}
else {
request.setRemotePort(serverPort);
}
}
private UriComponents uriComponents() {
URL url = this.webRequest.getUrl();
return UriComponentsBuilder.fromUriString(url.toExternalForm()).build();
}
/* Mergeable methods */
@Override
public boolean isMergeEnabled() {
@ -461,10 +445,6 @@ final class HtmlUnitRequestBuilder implements RequestBuilder, Mergeable {
return this;
}
private CookieManager getCookieManager() {
return this.webClient.getCookieManager();
}
/**
* An extension to {@link MockHttpServletRequest} that ensures that when a