com.github.tomakehurst.wiremock.servlet.WireMockHttpServletRequestAdapter Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of wiremock-standalone Show documentation
Show all versions of wiremock-standalone Show documentation
A web service test double for all occasions
/*
* Copyright (C) 2011 Thomas Akehurst
*
* 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 com.github.tomakehurst.wiremock.servlet;
import com.github.tomakehurst.wiremock.common.Gzip;
import com.github.tomakehurst.wiremock.http.ContentTypeHeader;
import com.github.tomakehurst.wiremock.http.Cookie;
import com.github.tomakehurst.wiremock.http.HttpHeader;
import com.github.tomakehurst.wiremock.http.HttpHeaders;
import com.github.tomakehurst.wiremock.http.QueryParameter;
import com.github.tomakehurst.wiremock.http.Request;
import com.github.tomakehurst.wiremock.http.RequestMethod;
import com.github.tomakehurst.wiremock.jetty9.JettyUtils;
import com.google.common.base.Function;
import com.google.common.base.Joiner;
import com.google.common.base.Optional;
import com.google.common.base.Predicate;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMultimap;
import com.google.common.collect.Maps;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.Charset;
import java.util.*;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.Part;
import org.eclipse.jetty.util.MultiPartInputStreamParser;
import static com.github.tomakehurst.wiremock.common.Encoding.encodeBase64;
import static com.github.tomakehurst.wiremock.common.Exceptions.throwUnchecked;
import static com.github.tomakehurst.wiremock.common.Strings.stringFromBytes;
import static com.github.tomakehurst.wiremock.common.Urls.splitQuery;
import static com.google.common.base.Charsets.UTF_8;
import static com.google.common.base.MoreObjects.firstNonNull;
import static com.google.common.base.Strings.isNullOrEmpty;
import static com.google.common.collect.FluentIterable.from;
import static com.google.common.collect.Lists.newArrayList;
import static com.google.common.io.ByteStreams.toByteArray;
import static java.util.Collections.list;
public class WireMockHttpServletRequestAdapter implements Request {
public static final String ORIGINAL_REQUEST_KEY = "wiremock.ORIGINAL_REQUEST";
private final HttpServletRequest request;
private byte[] cachedBody;
private String urlPrefixToRemove;
private Collection cachedMultiparts;
public WireMockHttpServletRequestAdapter(HttpServletRequest request) {
this.request = request;
}
public WireMockHttpServletRequestAdapter(HttpServletRequest request, String urlPrefixToRemove) {
this.request = request;
this.urlPrefixToRemove = urlPrefixToRemove;
}
@Override
public String getUrl() {
String url = request.getRequestURI();
String contextPath = request.getContextPath();
if (!isNullOrEmpty(contextPath) && url.startsWith(contextPath)) {
url = url.substring(contextPath.length());
}
if (!isNullOrEmpty(urlPrefixToRemove) && url.startsWith(urlPrefixToRemove)) {
url = url.substring(urlPrefixToRemove.length());
}
return withQueryStringIfPresent(url);
}
@Override
public String getAbsoluteUrl() {
return withQueryStringIfPresent(request.getRequestURL().toString());
}
private String withQueryStringIfPresent(String url) {
return url + (isNullOrEmpty(request.getQueryString()) ? "" : "?" + request.getQueryString());
}
@Override
public RequestMethod getMethod() {
return RequestMethod.fromString(request.getMethod().toUpperCase());
}
@Override
public String getClientIp() {
String forwardedForHeader = this.getHeader("X-Forwarded-For");
if (forwardedForHeader != null && forwardedForHeader.length() > 0) {
return forwardedForHeader;
}
return request.getRemoteAddr();
}
@Override
public byte[] getBody() {
if (cachedBody == null) {
try {
byte[] body = toByteArray(request.getInputStream());
boolean isGzipped = hasGzipEncoding() || Gzip.isGzipped(body);
cachedBody = isGzipped ? Gzip.unGzip(body) : body;
} catch (IOException ioe) {
throw new RuntimeException(ioe);
}
}
return cachedBody;
}
private Charset encodingFromContentTypeHeaderOrUtf8() {
ContentTypeHeader contentTypeHeader = contentTypeHeader();
if (contentTypeHeader != null) {
return contentTypeHeader.charset();
}
return UTF_8;
}
private boolean hasGzipEncoding() {
String encodingHeader = request.getHeader("Content-Encoding");
return encodingHeader != null && encodingHeader.contains("gzip");
}
@Override
public String getBodyAsString() {
return stringFromBytes(getBody(), encodingFromContentTypeHeaderOrUtf8());
}
@Override
public String getBodyAsBase64() {
return encodeBase64(getBody());
}
@SuppressWarnings("unchecked")
@Override
public String getHeader(String key) {
List headerNames = list(request.getHeaderNames());
for (String currentKey : headerNames) {
if (currentKey.toLowerCase().equals(key.toLowerCase())) {
return request.getHeader(currentKey);
}
}
return null;
}
@Override
@SuppressWarnings("unchecked")
public HttpHeader header(String key) {
List headerNames = list(request.getHeaderNames());
for (String currentKey : headerNames) {
if (currentKey.toLowerCase().equals(key.toLowerCase())) {
List valueList = list(request.getHeaders(currentKey));
if (valueList.isEmpty()) {
return HttpHeader.empty(key);
}
return new HttpHeader(key, valueList);
}
}
return HttpHeader.absent(key);
}
@Override
public ContentTypeHeader contentTypeHeader() {
return getHeaders().getContentTypeHeader();
}
@Override
public boolean containsHeader(String key) {
return header(key).isPresent();
}
@Override
public HttpHeaders getHeaders() {
List headerList = newArrayList();
for (String key : getAllHeaderKeys()) {
headerList.add(header(key));
}
return new HttpHeaders(headerList);
}
@SuppressWarnings("unchecked")
@Override
public Set getAllHeaderKeys() {
LinkedHashSet headerKeys = new LinkedHashSet();
for (Enumeration headerNames = request.getHeaderNames(); headerNames.hasMoreElements(); ) {
headerKeys.add(headerNames.nextElement());
}
return headerKeys;
}
@Override
public Map getCookies() {
ImmutableMultimap.Builder builder = ImmutableMultimap.builder();
javax.servlet.http.Cookie[] cookies = firstNonNull(request.getCookies(), new javax.servlet.http.Cookie[0]);
for (javax.servlet.http.Cookie cookie: cookies) {
builder.put(cookie.getName(), cookie.getValue());
}
return Maps.transformValues(builder.build().asMap(), new Function, Cookie>() {
@Override
public Cookie apply(Collection input) {
return new Cookie(null, ImmutableList.copyOf(input));
}
});
}
@Override
public QueryParameter queryParameter(String key) {
return firstNonNull((splitQuery(request.getQueryString())
.get(key)),
QueryParameter.absent(key));
}
@Override
public boolean isBrowserProxyRequest() {
if (!isJetty()) {
return false;
}
if (request instanceof org.eclipse.jetty.server.Request) {
org.eclipse.jetty.server.Request jettyRequest = (org.eclipse.jetty.server.Request) request;
return JettyUtils.getUri(jettyRequest).isAbsolute();
}
return false;
}
@Override
@SuppressWarnings("unchecked")
public Collection getParts() {
if (!isMultipart()) {
return null;
}
if (cachedMultiparts == null) {
try {
String contentTypeHeaderValue = from(contentTypeHeader().values()).join(Joiner.on(" "));
InputStream inputStream = new ByteArrayInputStream(getBody());
MultiPartInputStreamParser inputStreamParser = new MultiPartInputStreamParser(inputStream, contentTypeHeaderValue, null, null);
request.setAttribute(org.eclipse.jetty.server.Request.__MULTIPART_INPUT_STREAM, inputStreamParser);
cachedMultiparts = from(safelyGetRequestParts()).transform(new Function() {
@Override
public Part apply(javax.servlet.http.Part input) {
return WireMockHttpServletMultipartAdapter.from(input);
}
}).toList();
} catch (IOException | ServletException exception) {
return throwUnchecked(exception, Collection.class);
}
}
return (cachedMultiparts.size() > 0) ? cachedMultiparts : null;
}
private Collection safelyGetRequestParts() throws IOException, ServletException {
try {
return request.getParts();
} catch (IOException ioe) {
if (ioe.getMessage().contains("Missing content for multipart")) {
return Collections.emptyList();
}
throw ioe;
}
}
@Override
public boolean isMultipart() {
String header = getHeader("Content-Type");
return (header != null && header.contains("multipart"));
}
@Override
public Part getPart(final String name) {
if (name == null || name.length() == 0) {
return null;
}
if (cachedMultiparts == null) {
if (getParts() == null) {
return null;
}
}
return from(cachedMultiparts).firstMatch(new Predicate() {
@Override
public boolean apply(Part input) {
return name.equals(input.getName());
}
}).get();
}
@Override
public Optional getOriginalRequest() {
Request originalRequest = (Request) request.getAttribute(ORIGINAL_REQUEST_KEY);
return Optional.fromNullable(originalRequest);
}
private boolean isJetty() {
try {
getClass("org.eclipse.jetty.server.Request");
return true;
} catch (Exception e) {
}
return false;
}
private void getClass(String type) throws ClassNotFoundException {
ClassLoader contextCL = Thread.currentThread().getContextClassLoader();
ClassLoader loader = contextCL == null ? WireMockHttpServletRequestAdapter.class.getClassLoader() : contextCL;
Class.forName(type, false, loader);
}
@Override
public String toString() {
return request.toString() + getBodyAsString();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy