All Downloads are FREE. Search and download functionalities are using the official Maven repository.

software.xdev.mockserver.model.HttpRequest Maven / Gradle / Ivy

There is a newer version: 1.0.8
Show newest version
/*
 * Copyright © 2024 XDEV Software (https://xdev.software)
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package software.xdev.mockserver.model;

import static io.netty.handler.codec.http.HttpHeaderNames.CONTENT_TYPE;
import static io.netty.handler.codec.http.HttpHeaderNames.HOST;
import static software.xdev.mockserver.character.Character.NEW_LINE;
import static software.xdev.mockserver.model.Header.header;
import static software.xdev.mockserver.model.NottableString.string;
import static software.xdev.mockserver.model.SocketAddress.Scheme.HTTP;
import static software.xdev.mockserver.util.StringUtils.isBlank;
import static software.xdev.mockserver.util.StringUtils.isNotBlank;

import java.net.InetSocketAddress;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Objects;

import com.fasterxml.jackson.annotation.JsonIgnore;


@SuppressWarnings({"rawtypes", "UnusedReturnValue"})
public class HttpRequest extends RequestDefinition implements HttpMessage
{
	private int hashCode;
	private NottableString method = string("");
	private NottableString path = string("");
	private Parameters pathParameters;
	private Parameters queryStringParameters;
	private Body body;
	private Headers headers;
	private Cookies cookies;
	private Boolean keepAlive;
	private Protocol protocol;
	private Integer streamId;
	private SocketAddress socketAddress;
	private String localAddress;
	private String remoteAddress;
	
	public static HttpRequest request()
	{
		return new HttpRequest();
	}
	
	public static HttpRequest request(final String path)
	{
		return new HttpRequest().withPath(path);
	}
	
	public Boolean isKeepAlive()
	{
		return this.keepAlive;
	}
	
	/**
	 * Match on whether the request was made using an HTTP persistent connection, also called HTTP keep-alive, or HTTP
	 * connection reuse
	 *
	 * @param isKeepAlive true if the request was made with an HTTP persistent connection
	 */
	public HttpRequest withKeepAlive(final Boolean isKeepAlive)
	{
		this.keepAlive = isKeepAlive;
		this.hashCode = 0;
		return this;
	}
	
	public Protocol getProtocol()
	{
		return this.protocol;
	}
	
	/**
	 * Match on whether the request was made over HTTP or HTTP2
	 *
	 * @param protocol used to indicate HTTP or HTTP2
	 */
	public HttpRequest withProtocol(final Protocol protocol)
	{
		this.protocol = protocol;
		this.hashCode = 0;
		return this;
	}
	
	public Integer getStreamId()
	{
		return this.streamId;
	}
	
	/**
	 * HTTP2 stream id request was received on
	 *
	 * @param streamId HTTP2 stream id request was received on
	 */
	public HttpRequest withStreamId(final Integer streamId)
	{
		this.streamId = streamId;
		this.hashCode = 0;
		return this;
	}
	
	public SocketAddress getSocketAddress()
	{
		return this.socketAddress;
	}
	
	/**
	 * Specify remote address if the remote address can't be derived from the host header, if no value is specified the
	 * host header will be used to determine remote address
	 *
	 * @param socketAddress the remote address to send request to
	 */
	public HttpRequest withSocketAddress(final SocketAddress socketAddress)
	{
		this.socketAddress = socketAddress;
		this.hashCode = 0;
		return this;
	}
	
	/**
	 * Specify remote address if the remote address can't be derived from the host header, if no value is specified the
	 * host header will be used to determine remote address
	 *
	 * @param host   the remote host or ip to send request to
	 * @param port   the remote port to send request to
	 * @param scheme the scheme to use for remote socket
	 */
	public HttpRequest withSocketAddress(final String host, final Integer port, final SocketAddress.Scheme scheme)
	{
		this.socketAddress = new SocketAddress()
			.withHost(host)
			.withPort(port)
			.withScheme(scheme);
		this.hashCode = 0;
		return this;
	}
	
	/**
	 * Specify remote address by attempting to derive it from the host header
	 */
	public HttpRequest withSocketAddressFromHostHeader()
	{
		this.withSocketAddress(this.getFirstHeader("host"), null);
		this.hashCode = 0;
		return this;
	}
	
	/**
	 * Specify remote address by attempting to derive it from the host header and / or the specified port
	 *
	 * @param host     the remote host or ip to send request to
	 * @param port     the remote port to send request to
	 */
	@SuppressWarnings("checkstyle:MagicNumber")
	public HttpRequest withSocketAddress(final String host, final Integer port)
	{
		if(isNotBlank(host))
		{
			final String[] hostParts = host.split(":");
			if(hostParts.length > 1)
			{
				this.withSocketAddress(hostParts[0], port != null ? port : Integer.parseInt(hostParts[1]), HTTP);
			}
			else
			{
				this.withSocketAddress(host, port != null ? port : 80, HTTP);
			}
		}
		this.hashCode = 0;
		return this;
	}
	
	public HttpRequest withLocalAddress(final String localAddress)
	{
		this.localAddress = localAddress;
		this.hashCode = 0;
		return this;
	}
	
	public String getLocalAddress()
	{
		return this.localAddress;
	}
	
	public HttpRequest withRemoteAddress(final String remoteAddress)
	{
		this.remoteAddress = remoteAddress;
		this.hashCode = 0;
		return this;
	}
	
	public String getRemoteAddress()
	{
		return this.remoteAddress;
	}
	
	/**
	 * The HTTP method to match on such as "GET" or "POST"
	 *
	 * @param method the HTTP method such as "GET" or "POST"
	 */
	public HttpRequest withMethod(final String method)
	{
		return this.withMethod(string(method));
	}
	
	/**
	 * The HTTP method all method except a specific value using the "not" operator, for example this allows operations
	 * such as not("GET")
	 *
	 * @param method the HTTP method to not match on not("GET") or not("POST")
	 */
	public HttpRequest withMethod(final NottableString method)
	{
		this.method = method;
		this.hashCode = 0;
		return this;
	}
	
	public NottableString getMethod()
	{
		return this.method;
	}
	
	public String getMethod(final String defaultValue)
	{
		if(isBlank(this.method.getValue()))
		{
			return defaultValue;
		}
		else
		{
			return this.method.getValue();
		}
	}
	
	/**
	 * The path to match on such as "/some_mocked_path" any servlet context path is ignored for matching and should not
	 * be specified here regex values are also supported such as ".*_path", see
	 * http://docs.oracle.com/javase/8/docs/api/java/util/regex/Pattern.html for full details of the supported regex
	 * syntax
	 *
	 * @param path the path such as "/some_mocked_path" or a regex
	 */
	public HttpRequest withPath(final String path)
	{
		this.withPath(string(path));
		return this;
	}
	
	/**
	 * The path to not match on for example not("/some_mocked_path") with match any path not equal to
	 * "/some_mocked_path", the servlet context path is ignored for matching and should not be specified hereregex
	 * values are also supported such as not(".*_path"), see
	 * http://docs.oracle.com/javase/8/docs/api/java/util/regex/Pattern.html for full details of the supported regex
	 * syntax
	 *
	 * @param path the path to not match on such as not("/some_mocked_path") or not(".*_path")
	 */
	public HttpRequest withPath(final NottableString path)
	{
		this.path = path;
		this.hashCode = 0;
		return this;
	}
	
	public NottableString getPath()
	{
		return this.path;
	}
	
	public boolean matches(final String method)
	{
		return this.method.getValue().equals(method);
	}
	
	public boolean matches(final String method, final String... paths)
	{
		if(!this.matches(method))
		{
			return false;
		}
		return this.matchesPath(paths);
	}
	
	public boolean matchesPath(final String... paths)
	{
		boolean matches = false;
		for(final String path : paths)
		{
			matches = this.path.getValue().equals(path);
			if(matches)
			{
				break;
			}
		}
		return matches;
	}
	
	public Parameters getPathParameters()
	{
		return this.pathParameters;
	}
	
	private Parameters getOrCreatePathParameters()
	{
		if(this.pathParameters == null)
		{
			this.pathParameters = new Parameters();
			this.hashCode = 0;
		}
		return this.pathParameters;
	}
	
	public HttpRequest withPathParameters(final Parameters parameters)
	{
		if(parameters == null || parameters.isEmpty())
		{
			this.pathParameters = null;
		}
		else
		{
			this.pathParameters = parameters;
		}
		this.hashCode = 0;
		return this;
	}
	
	/**
	 * The path parameter to match on as a list of Parameter objects where the values or keys of each parameter can be
	 * either a string or a regex (for more details of the supported regex syntax see
	 * http://docs.oracle.com/javase/8/docs/api/java/util/regex/Pattern.html)
	 *
	 * @param parameters the list of Parameter objects where the values or keys of each parameter can be either a
	 *                      string
	 *                   or a regex
	 */
	public HttpRequest withPathParameters(final List parameters)
	{
		this.getOrCreatePathParameters().withEntries(parameters);
		this.hashCode = 0;
		return this;
	}
	
	/**
	 * The path parameter to match on as a varags Parameter objects where the values or keys of each parameter can be
	 * either a string or a regex (for more details of the supported regex syntax see
	 * http://docs.oracle.com/javase/8/docs/api/java/util/regex/Pattern.html)
	 *
	 * @param parameters the varags Parameter objects where the values or keys of each parameter can be either a string
	 *                   or a regex
	 */
	public HttpRequest withPathParameters(final Parameter... parameters)
	{
		this.getOrCreatePathParameters().withEntries(parameters);
		this.hashCode = 0;
		return this;
	}
	
	/**
	 * The path parameter to match on as a Map<String, List<String>> where the values or keys of each
	 * parameter can be either a string or a regex (for more details of the supported regex syntax see
	 * http://docs.oracle.com/javase/8/docs/api/java/util/regex/Pattern.html)
	 *
	 * @param parameters the Map<String, List<String>> object where the values or keys of each parameter
	 *                     can
	 *                   be either a string or a regex
	 */
	public HttpRequest withPathParameters(final Map> parameters)
	{
		this.getOrCreatePathParameters().withEntries(parameters);
		this.hashCode = 0;
		return this;
	}
	
	/**
	 * Adds one path parameter to match on as a Parameter object where the parameter values list can be a list of
	 * strings or regular expressions (for more details of the supported regex syntax see
	 * http://docs.oracle.com/javase/8/docs/api/java/util/regex/Pattern.html)
	 *
	 * @param parameter the Parameter object which can have a values list of strings or regular expressions
	 */
	public HttpRequest withPathParameter(final Parameter parameter)
	{
		this.getOrCreatePathParameters().withEntry(parameter);
		this.hashCode = 0;
		return this;
	}
	
	/**
	 * Adds one path parameter to match which can specified using plain strings or regular expressions (for more
	 * details
	 * of the supported regex syntax see http://docs.oracle.com/javase/8/docs/api/java/util/regex/Pattern.html)
	 *
	 * @param name   the parameter name
	 * @param values the parameter values which can be a varags of strings or regular expressions
	 */
	public HttpRequest withPathParameter(final String name, final String... values)
	{
		this.getOrCreatePathParameters().withEntry(name, values.length == 0 ? new String[]{".*"} : values);
		this.hashCode = 0;
		return this;
	}
	
	/**
	 * Adds one path parameter to match on or to not match on using the NottableString, each NottableString can either
	 * be a positive matching value, such as string("match"), or a value to not match on, such as not("do not match"),
	 * the string values passed to the NottableString can also be a plain string or a regex (for more details of the
	 * supported regex syntax see http://docs.oracle.com/javase/8/docs/api/java/util/regex/Pattern.html)
	 *
	 * @param name   the parameter name as a NottableString
	 * @param values the parameter values which can be a varags of NottableStrings
	 */
	public HttpRequest withPathParameter(final NottableString name, final NottableString... values)
	{
		this.getOrCreatePathParameters()
			.withEntry(name, values.length == 0 ? new NottableString[]{string(".*")} : values);
		this.hashCode = 0;
		return this;
	}
	
	public List getPathParameterList()
	{
		if(this.pathParameters != null)
		{
			return this.pathParameters.getEntries();
		}
		else
		{
			return Collections.emptyList();
		}
	}
	
	@SuppressWarnings("unused")
	public boolean hasPathParameter(final String name, final String value)
	{
		if(this.pathParameters != null)
		{
			return this.pathParameters.containsEntry(name, value);
		}
		else
		{
			return false;
		}
	}
	
	@SuppressWarnings("unused")
	public boolean hasPathParameter(final NottableString name, final NottableString value)
	{
		if(this.pathParameters != null)
		{
			return this.pathParameters.containsEntry(name, value);
		}
		else
		{
			return false;
		}
	}
	
	public String getFirstPathParameter(final String name)
	{
		if(this.pathParameters != null)
		{
			return this.pathParameters.getFirstValue(name);
		}
		else
		{
			return "";
		}
	}
	
	public Parameters getQueryStringParameters()
	{
		return this.queryStringParameters;
	}
	
	private Parameters getOrCreateQueryStringParameters()
	{
		if(this.queryStringParameters == null)
		{
			this.queryStringParameters = new Parameters();
			this.hashCode = 0;
		}
		return this.queryStringParameters;
	}
	
	public HttpRequest withQueryStringParameters(final Parameters parameters)
	{
		if(parameters == null || parameters.isEmpty())
		{
			this.queryStringParameters = null;
		}
		else
		{
			this.queryStringParameters = parameters;
		}
		this.hashCode = 0;
		return this;
	}
	
	/**
	 * The query string parameters to match on as a list of Parameter objects where the values or keys of each
	 * parameter
	 * can be either a string or a regex (for more details of the supported regex syntax see
	 * http://docs.oracle.com/javase/8/docs/api/java/util/regex/Pattern.html)
	 *
	 * @param parameters the list of Parameter objects where the values or keys of each parameter can be either a
	 *                      string
	 *                   or a regex
	 */
	public HttpRequest withQueryStringParameters(final List parameters)
	{
		this.getOrCreateQueryStringParameters().withEntries(parameters);
		this.hashCode = 0;
		return this;
	}
	
	/**
	 * The query string parameters to match on as a varags Parameter objects where the values or keys of each parameter
	 * can be either a string or a regex (for more details of the supported regex syntax see
	 * http://docs.oracle.com/javase/8/docs/api/java/util/regex/Pattern.html)
	 *
	 * @param parameters the varags Parameter objects where the values or keys of each parameter can be either a string
	 *                   or a regex
	 */
	public HttpRequest withQueryStringParameters(final Parameter... parameters)
	{
		this.getOrCreateQueryStringParameters().withEntries(parameters);
		this.hashCode = 0;
		return this;
	}
	
	/**
	 * The query string parameters to match on as a Map<String, List<String>> where the values or keys of
	 * each parameter can be either a string or a regex (for more details of the supported regex syntax see
	 * http://docs.oracle.com/javase/8/docs/api/java/util/regex/Pattern.html)
	 *
	 * @param parameters the Map<String, List<String>> object where the values or keys of each parameter
	 *                     can
	 *                   be either a string or a regex
	 */
	public HttpRequest withQueryStringParameters(final Map> parameters)
	{
		this.getOrCreateQueryStringParameters().withEntries(parameters);
		this.hashCode = 0;
		return this;
	}
	
	/**
	 * Adds one query string parameter to match on as a Parameter object where the parameter values list can be a list
	 * of strings or regular expressions (for more details of the supported regex syntax see
	 * http://docs.oracle.com/javase/8/docs/api/java/util/regex/Pattern.html)
	 *
	 * @param parameter the Parameter object which can have a values list of strings or regular expressions
	 */
	public HttpRequest withQueryStringParameter(final Parameter parameter)
	{
		this.getOrCreateQueryStringParameters().withEntry(parameter);
		this.hashCode = 0;
		return this;
	}
	
	/**
	 * Adds one query string parameter to match which the values are plain strings or regular expressions (for more
	 * details of the supported regex syntax see http://docs.oracle.com/javase/8/docs/api/java/util/regex/Pattern.html)
	 *
	 * @param name   the parameter name
	 * @param values the parameter values which can be a varags of strings or regular expressions
	 */
	public HttpRequest withQueryStringParameter(final String name, final String... values)
	{
		this.getOrCreateQueryStringParameters().withEntry(name, values);
		this.hashCode = 0;
		return this;
	}
	
	/**
	 * Adds one query string parameter to match on or to not match on using the NottableString, each NottableString can
	 * either be a positive matching value, such as string("match"), or a value to not match on, such as not("do not
	 * match"), the string values passed to the NottableString can also be a plain string or a regex (for more details
	 * of the supported regex syntax see http://docs.oracle.com/javase/8/docs/api/java/util/regex/Pattern.html)
	 *
	 * @param name   the parameter name as a NottableString
	 * @param values the parameter values which can be a varags of NottableStrings
	 */
	public HttpRequest withQueryStringParameter(final NottableString name, final NottableString... values)
	{
		this.getOrCreateQueryStringParameters()
			.withEntry(name, values.length == 0 ? new NottableString[]{string(".*")} : values);
		this.hashCode = 0;
		return this;
	}
	
	public List getQueryStringParameterList()
	{
		if(this.queryStringParameters != null)
		{
			return this.queryStringParameters.getEntries();
		}
		else
		{
			return Collections.emptyList();
		}
	}
	
	@SuppressWarnings("unused")
	public boolean hasQueryStringParameter(final String name, final String value)
	{
		if(this.queryStringParameters != null)
		{
			return this.queryStringParameters.containsEntry(name, value);
		}
		else
		{
			return false;
		}
	}
	
	@SuppressWarnings("unused")
	public boolean hasQueryStringParameter(final NottableString name, final NottableString value)
	{
		if(this.queryStringParameters != null)
		{
			return this.queryStringParameters.containsEntry(name, value);
		}
		else
		{
			return false;
		}
	}
	
	public String getFirstQueryStringParameter(final String name)
	{
		if(this.queryStringParameters != null)
		{
			return this.queryStringParameters.getFirstValue(name);
		}
		else
		{
			return "";
		}
	}
	
	/**
	 * The exact string body to match on such as "this is an exact string body"
	 *
	 * @param body the body on such as "this is an exact string body"
	 */
	@Override
	public HttpRequest withBody(final String body)
	{
		this.body = new StringBody(body);
		this.hashCode = 0;
		return this;
	}
	
	/**
	 * The exact string body to match on such as "this is an exact string body"
	 *
	 * @param body    the body on such as "this is an exact string body"
	 * @param charset character set the string will be encoded in
	 */
	@Override
	public HttpRequest withBody(final String body, final Charset charset)
	{
		if(body != null)
		{
			this.body = new StringBody(body, charset);
			this.hashCode = 0;
		}
		return this;
	}
	
	/**
	 * The body to match on as binary data such as a pdf or image
	 *
	 * @param body a byte array
	 */
	@Override
	public HttpRequest withBody(final byte[] body)
	{
		this.body = new BinaryBody(body);
		this.hashCode = 0;
		return this;
	}
	
	/**
	 * The body match rules on such as using one of the Body subclasses as follows:
	 * 

* exact string match: - exact("this is an exact string body"); *

* or *

* - new StringBody("this is an exact string body") *

* regular expression match: - regex("username[a-z]{4}"); *

* or *

* - new RegexBody("username[a-z]{4}"); *

* json match: - json("{username: 'foo', password: 'bar'}"); *

* or *

* - json("{username: 'foo', password: 'bar'}", MatchType.STRICT); *

* or *

* - new JsonBody("{username: 'foo', password: 'bar'}"); *

* json schema match: - jsonSchema("{type: 'object', properties: { 'username': { 'type': 'string' }, 'password': { * 'type': 'string' } }, 'required': ['username', 'password']}"); *

* or *

* - jsonSchemaFromResource("org/mockserver/model/loginSchema.json"); *

* or *

* - new JsonSchemaBody("{type: 'object', properties: { 'username': { 'type': 'string' }, 'password': { 'type': * 'string' } }, 'required': ['username', 'password']}"); *

* xpath match: - xpath("/element[key = 'some_key' and value = 'some_value']"); *

* or *

* - new XPathBody("/element[key = 'some_key' and value = 'some_value']"); *

* body parameter match: - params( param("name_one", "value_one_one", "value_one_two") param("name_two", * "value_two") ); *

* or *

* - new ParameterBody( new Parameter("name_one", "value_one_one", "value_one_two") new Parameter("name_two", * "value_two") ); *

* binary match: - binary(IOUtils.readFully(getClass().getClassLoader().getResourceAsStream("example.pdf"), 1024)); *

* or *

* - new BinaryBody(IOUtils.readFully(getClass().getClassLoader().getResourceAsStream("example.pdf"), 1024)); *

* for more details of the supported regular expression syntax see http://docs.oracle * .com/javase/8/docs/api/java/util/regex/Pattern.html * * @param body an instance of one of the Body subclasses including StringBody, ParameterBody or BinaryBody */ @Override public HttpRequest withBody(final Body body) { this.body = body; this.hashCode = 0; return this; } @Override public Body getBody() { return this.body; } @Override @JsonIgnore public byte[] getBodyAsRawBytes() { return this.body != null ? this.body.getRawBytes() : new byte[0]; } @Override @JsonIgnore public String getBodyAsString() { if(this.body != null) { return this.body.toString(); } else { return null; } } @JsonIgnore public String getBodyAsJsonOrXmlString() { if(this.body != null) { if(this.body instanceof StringBody) { // if it should be json (and it has been validated i.e. control plane request) // assume the Content-Type header was forgotten so should be parsed as json return new String( this.body.toString() .getBytes(MediaType.parse(this.getFirstHeader(CONTENT_TYPE.toString())).getCharsetOrDefault()), StandardCharsets.UTF_8); } else { return this.getBodyAsString(); } } else { return null; } } @Override public Headers getHeaders() { return this.headers; } private Headers getOrCreateHeaders() { if(this.headers == null) { this.headers = new Headers(); this.hashCode = 0; } return this.headers; } @Override public HttpRequest withHeaders(final Headers headers) { if(headers == null || headers.isEmpty()) { this.headers = null; } else { this.headers = headers; } this.hashCode = 0; return this; } /** * The headers to match on as a list of Header objects where the values or keys of each header can be either a * string or a regex (for more details of the supported regex syntax see * http://docs.oracle.com/javase/8/docs/api/java/util/regex/Pattern.html) * * @param headers the list of Header objects where the values or keys of each header can be either a string or a * regex */ @Override public HttpRequest withHeaders(final List

headers) { this.getOrCreateHeaders().withEntries(headers); this.hashCode = 0; return this; } /** * The headers to match on as a varags of Header objects where the values or keys of each header can be either a * string or a regex (for more details of the supported regex syntax see * http://docs.oracle.com/javase/8/docs/api/java/util/regex/Pattern.html) * * @param headers the varags of Header objects where the values or keys of each header can be either a string or a * regex */ @Override public HttpRequest withHeaders(final Header... headers) { this.getOrCreateHeaders().withEntries(headers); this.hashCode = 0; return this; } /** * Adds one header to match on as a Header object where the header values list can be a list of strings or regular * expressions (for more details of the supported regex syntax see * http://docs.oracle.com/javase/8/docs/api/java/util/regex/Pattern.html) * * @param header the Header object which can have a values list of strings or regular expressions */ @Override public HttpRequest withHeader(final Header header) { this.getOrCreateHeaders().withEntry(header); this.hashCode = 0; return this; } /** * Adds one header to match which can specified using plain strings or regular expressions (for more details of the * supported regex syntax see http://docs.oracle.com/javase/8/docs/api/java/util/regex/Pattern.html) * * @param name the header name * @param values the header values which can be a varags of strings or regular expressions */ @Override public HttpRequest withHeader(final String name, final String... values) { this.getOrCreateHeaders().withEntry(header(name, values.length == 0 ? new String[]{".*"} : values)); this.hashCode = 0; return this; } /** * Adds one header to match on or to not match on using the NottableString, each NottableString can either be a * positive matching value, such as string("match"), or a value to not match on, such as not("do not match"), the * string values passed to the NottableString can also be a plain string or a regex (for more details of the * supported regex syntax see http://docs.oracle.com/javase/8/docs/api/java/util/regex/Pattern.html) * * @param name the header name as a NottableString * @param values the header values which can be a varags of NottableStrings */ @Override public HttpRequest withHeader(final NottableString name, final NottableString... values) { this.getOrCreateHeaders() .withEntry(header(name, values.length == 0 ? new NottableString[]{string(".*")} : values)); this.hashCode = 0; return this; } @Override public HttpRequest withContentType(final MediaType mediaType) { this.getOrCreateHeaders().withEntry(header(CONTENT_TYPE.toString(), mediaType.toString())); this.hashCode = 0; return this; } /** * Adds one header to match on as a Header object where the header values list can be a list of strings or regular * expressions (for more details of the supported regex syntax see * http://docs.oracle.com/javase/8/docs/api/java/util/regex/Pattern.html) * * @param header the Header object which can have a values list of strings or regular expressions */ @Override public HttpRequest replaceHeader(final Header header) { this.getOrCreateHeaders().replaceEntry(header); this.hashCode = 0; return this; } @Override public List
getHeaderList() { if(this.headers != null) { return this.headers.getEntries(); } else { return Collections.emptyList(); } } @Override public List getHeader(final String name) { if(this.headers != null) { return this.headers.getValues(name); } else { return Collections.emptyList(); } } @Override public String getFirstHeader(final String name) { if(this.headers != null) { return this.headers.getFirstValue(name); } else { return ""; } } /** * Returns true if a header with the specified name has been added * * @param name the header name * @return true if a header has been added with that name otherwise false */ @Override public boolean containsHeader(final String name) { if(this.headers != null) { return this.headers.containsEntry(name); } else { return false; } } /** * Returns true if a header with the specified name and value has been added * * @param name the header name * @param value the header value * @return true if a header has been added with that name otherwise false */ public boolean containsHeader(final String name, final String value) { if(this.headers != null) { return this.headers.containsEntry(name, value); } else { return false; } } @Override public HttpRequest removeHeader(final String name) { if(this.headers != null) { this.headers.remove(name); this.hashCode = 0; } return this; } @Override public HttpRequest removeHeader(final NottableString name) { if(this.headers != null) { this.headers.remove(name); this.hashCode = 0; } return this; } @Override public Cookies getCookies() { return this.cookies; } private Cookies getOrCreateCookies() { if(this.cookies == null) { this.cookies = new Cookies(); this.hashCode = 0; } return this.cookies; } @Override public HttpRequest withCookies(final Cookies cookies) { if(cookies == null || cookies.isEmpty()) { this.cookies = null; } else { this.cookies = cookies; } this.hashCode = 0; return this; } /** * The cookies to match on as a list of Cookie objects where the values or keys of each cookie can be either a * string or a regex (for more details of the supported regex syntax see * http://docs.oracle.com/javase/8/docs/api/java/util/regex/Pattern.html) * * @param cookies a list of Cookie objects */ @Override public HttpRequest withCookies(final List cookies) { this.getOrCreateCookies().withEntries(cookies); this.hashCode = 0; return this; } /** * The cookies to match on as a varags Cookie objects where the values or keys of each cookie can be either a * string * or a regex (for more details of the supported regex syntax see * http://docs.oracle.com/javase/8/docs/api/java/util/regex/Pattern.html) * * @param cookies a varargs of Cookie objects */ @Override public HttpRequest withCookies(final Cookie... cookies) { this.getOrCreateCookies().withEntries(cookies); this.hashCode = 0; return this; } /** * Adds one cookie to match on as a Cookie object where the cookie values list can be a list of strings or regular * expressions (for more details of the supported regex syntax see * http://docs.oracle.com/javase/8/docs/api/java/util/regex/Pattern.html) * * @param cookie a Cookie object */ @Override public HttpRequest withCookie(final Cookie cookie) { this.getOrCreateCookies().withEntry(cookie); this.hashCode = 0; return this; } /** * Adds one cookie to match on, which the value is plain strings or regular expressions (for more details of the * supported regex syntax see http://docs.oracle.com/javase/8/docs/api/java/util/regex/Pattern.html) * * @param name the cookies name * @param value the cookies value */ @Override public HttpRequest withCookie(final String name, final String value) { this.getOrCreateCookies().withEntry(name, value); this.hashCode = 0; return this; } /** * Adds one cookie to match on or to not match on using the NottableString, each NottableString can either be a * positive matching value, such as string("match"), or a value to not match on, such as not("do not match"), the * string values passed to the NottableString can be a plain string or a regex (for more details of the supported * regex syntax see http://docs.oracle.com/javase/8/docs/api/java/util/regex/Pattern.html) * * @param name the cookies name * @param value the cookies value */ @Override public HttpRequest withCookie(final NottableString name, final NottableString value) { this.getOrCreateCookies().withEntry(name, value); this.hashCode = 0; return this; } @Override public List getCookieList() { if(this.cookies != null) { return this.cookies.getEntries(); } else { return Collections.emptyList(); } } @SuppressWarnings("checkstyle:MagicNumber") public InetSocketAddress socketAddressFromHostHeader() { if(this.socketAddress != null && this.socketAddress.getHost() != null) { final boolean isSsl = this.socketAddress.getScheme() != null && this.socketAddress.getScheme() .equals(SocketAddress.Scheme.HTTPS); return new InetSocketAddress( this.socketAddress.getHost(), this.socketAddress.getPort() != null ? this.socketAddress.getPort() : isSsl ? 443 : 80); } else if(isNotBlank(this.getFirstHeader(HOST.toString()))) { final String[] hostHeaderParts = this.getFirstHeader(HOST.toString()).split(":"); return new InetSocketAddress( hostHeaderParts[0], hostHeaderParts.length > 1 ? Integer.parseInt(hostHeaderParts[1]) : 80); } else { throw new IllegalArgumentException( "Host header must be provided to determine remote socket address, the request does not include the " + "\"Host\" header:" + NEW_LINE + this); } } @Override public HttpRequest shallowClone() { return not(request(), this.not) .withMethod(this.method) .withPath(this.path) .withPathParameters(this.pathParameters) .withQueryStringParameters(this.queryStringParameters) .withBody(this.body) .withHeaders(this.headers) .withCookies(this.cookies) .withKeepAlive(this.keepAlive) .withProtocol(this.protocol) .withStreamId(this.streamId) .withSocketAddress(this.socketAddress) .withLocalAddress(this.localAddress) .withRemoteAddress(this.remoteAddress); } @Override @SuppressWarnings({"MethodDoesntCallSuperMethod", "checkstyle:NoClone"}) public HttpRequest clone() { return not(request(), this.not) .withMethod(this.method) .withPath(this.path) .withPathParameters(this.pathParameters != null ? this.pathParameters.clone() : null) .withQueryStringParameters(this.queryStringParameters != null ? this.queryStringParameters.clone() : null) .withBody(this.body) .withHeaders(this.headers != null ? this.headers.clone() : null) .withCookies(this.cookies != null ? this.cookies.clone() : null) .withKeepAlive(this.keepAlive) .withProtocol(this.protocol) .withStreamId(this.streamId) .withSocketAddress(this.socketAddress) .withLocalAddress(this.localAddress) .withRemoteAddress(this.remoteAddress); } public HttpRequest update(final HttpRequest requestOverride, final HttpRequestModifier requestModifier) { if(requestOverride != null) { if(requestOverride.getMethod() != null && isNotBlank(requestOverride.getMethod().getValue())) { this.withMethod(requestOverride.getMethod()); } if(requestOverride.getPath() != null && isNotBlank(requestOverride.getPath().getValue())) { this.withPath(requestOverride.getPath()); } for(final Parameter parameter : requestOverride.getPathParameterList()) { this.getOrCreatePathParameters().replaceEntry(parameter); } for(final Parameter parameter : requestOverride.getQueryStringParameterList()) { this.getOrCreateQueryStringParameters().replaceEntry(parameter); } if(requestOverride.getBody() != null) { this.withBody(requestOverride.getBody()); } for(final Header header : requestOverride.getHeaderList()) { this.getOrCreateHeaders().replaceEntry(header); } for(final Cookie cookie : requestOverride.getCookieList()) { this.withCookie(cookie); } if(requestOverride.getProtocol() != null) { this.withProtocol(requestOverride.getProtocol()); } if(requestOverride.getStreamId() != null) { this.withStreamId(requestOverride.getStreamId()); } if(requestOverride.isKeepAlive() != null) { this.withKeepAlive(requestOverride.isKeepAlive()); } if(requestOverride.getSocketAddress() != null) { this.withSocketAddress(requestOverride.getSocketAddress()); } this.hashCode = 0; } if(requestModifier != null) { if(requestModifier.getPath() != null) { this.withPath(requestModifier.getPath().update(this.getPath())); } if(requestModifier.getQueryStringParameters() != null) { this.withQueryStringParameters(requestModifier.getQueryStringParameters() .update(this.getQueryStringParameters())); } if(requestModifier.getHeaders() != null) { this.withHeaders(requestModifier.getHeaders().update(this.getHeaders())); } if(requestModifier.getCookies() != null) { this.withCookies(requestModifier.getCookies().update(this.getCookies())); } } return this; } @Override public boolean equals(final Object o) { if(this == o) { return true; } if(o == null || this.getClass() != o.getClass()) { return false; } if(this.hashCode() != o.hashCode()) { return false; } if(!super.equals(o)) { return false; } final HttpRequest that = (HttpRequest)o; return Objects.equals(this.method, that.method) && Objects.equals(this.path, that.path) && Objects.equals(this.pathParameters, that.pathParameters) && Objects.equals(this.queryStringParameters, that.queryStringParameters) && Objects.equals(this.body, that.body) && Objects.equals(this.headers, that.headers) && Objects.equals(this.cookies, that.cookies) && Objects.equals(this.keepAlive, that.keepAlive) && Objects.equals(this.protocol, that.protocol) && Objects.equals(this.streamId, that.streamId) && Objects.equals(this.socketAddress, that.socketAddress) && Objects.equals(this.localAddress, that.localAddress) && Objects.equals(this.remoteAddress, that.remoteAddress); } @Override public int hashCode() { if(this.hashCode == 0) { this.hashCode = Objects.hash( super.hashCode(), this.method, this.path, this.pathParameters, this.queryStringParameters, this.body, this.headers, this.cookies, this.keepAlive, this.protocol, this.streamId, this.socketAddress, this.localAddress, this.remoteAddress); } return this.hashCode; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy