Skip to content

Commit

Permalink
Polishing in HtmlUnitRequestBuilder
Browse files Browse the repository at this point in the history
Order methods according to Spring Framework conventions.
Order request initialization by URI component.

See gh-27837
  • Loading branch information
rstoyanchev committed Jan 11, 2022
1 parent 29fe109 commit 9346c89
Showing 1 changed file with 93 additions and 113 deletions.
@@ -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.
Expand All @@ -18,7 +18,6 @@

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;
Expand All @@ -32,7 +31,6 @@
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;
Expand Down Expand Up @@ -69,6 +67,7 @@
*
* @author Rob Winch
* @author Sam Brannen
* @author Rossen Stoyanchev
* @since 4.2
* @see MockMvcWebConnection
*/
Expand Down Expand Up @@ -111,54 +110,60 @@ public HtmlUnitRequestBuilder(Map<String, MockHttpSession> sessions, WebClient w
}


/**
* 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

request.setProtocol("HTTP/1.1");
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);

Charset charset = this.webRequest.getCharset();
charset = (charset != null ? charset : StandardCharsets.ISO_8859_1);
request.setCharacterEncoding(charset.name());
content(request, charset);
contextPath(request, uriComponents);
contentType(request);

cookies(request);
headers(request);
this.webRequest.getAdditionalHeaders().forEach(request::addHeader);
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.setPathInfo(null);
params(request, uri);
request.setQueryString(uri.getQuery());

return postProcess(request);
}

private Charset getCharset() {
Charset charset = this.webRequest.getCharset();
return (charset != null ? charset : StandardCharsets.ISO_8859_1);
}

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 parent(MockHttpServletRequest request, @Nullable RequestBuilder parent) {
if (parent == null) {
return;
Expand Down Expand Up @@ -208,50 +213,30 @@ private void parent(MockHttpServletRequest request, @Nullable RequestBuilder par
}
}

/**
* 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) {
Expand All @@ -273,10 +258,36 @@ private void contextPath(MockHttpServletRequest request, UriComponents uriCompon
}
}

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()) {
Expand Down Expand Up @@ -312,15 +323,6 @@ private void processCookie(MockHttpServletRequest request, List<Cookie> cookies,
}
}

@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) {
Expand All @@ -341,11 +343,11 @@ private MockHttpSession httpSession(MockHttpServletRequest request, final String
}

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) {
Expand All @@ -354,7 +356,7 @@ private com.gargoylesoftware.htmlunit.util.Cookie createCookie(MockHttpServletRe
}

private void locales(MockHttpServletRequest request) {
String locale = header("Accept-Language");
String locale = getHeader("Accept-Language");
if (locale == null) {
request.addPreferredLocale(Locale.getDefault());
}
Expand Down Expand Up @@ -407,36 +409,18 @@ private byte[] readAllBytes(File file) {
}
}

private void servletPath(MockHttpServletRequest request, String requestPath) {
String servletPath = requestPath.substring(request.getContextPath().length());
request.setServletPath(servletPath);
}

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);
private MockHttpServletRequest postProcess(MockHttpServletRequest request) {
if (this.parentPostProcessor != null) {
request = this.parentPostProcessor.postProcessRequest(request);
}
else {
request.setRemotePort(serverPort);
if (this.forwardPostProcessor != null) {
request = this.forwardPostProcessor.postProcessRequest(request);
}
return request;
}

private UriComponents uriComponents() {
URL url = this.webRequest.getUrl();
return UriComponentsBuilder.fromUriString(url.toExternalForm()).build();
}

/* Mergeable methods */

@Override
public boolean isMergeEnabled() {
Expand All @@ -461,10 +445,6 @@ public Object merge(@Nullable Object parent) {
return this;
}

private CookieManager getCookieManager() {
return this.webClient.getCookieManager();
}


/**
* An extension to {@link MockHttpServletRequest} that ensures that when a
Expand Down

0 comments on commit 9346c89

Please sign in to comment.