All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
com.github.tomakehurst.wiremock.http.ProxyResponseRenderer Maven / Gradle / Ivy
/*
* 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.http;
import com.github.tomakehurst.wiremock.common.KeyStoreSettings;
import com.github.tomakehurst.wiremock.common.ProxySettings;
import com.google.common.collect.ImmutableList;
import org.apache.http.*;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.*;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.InputStreamEntity;
import org.apache.http.entity.ByteArrayEntity;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.util.LinkedList;
import java.util.List;
import static com.github.tomakehurst.wiremock.common.HttpClientUtils.getEntityAsByteArrayAndCloseStream;
import static com.github.tomakehurst.wiremock.common.LocalNotifier.notifier;
import static com.github.tomakehurst.wiremock.http.RequestMethod.DELETE;
import static com.github.tomakehurst.wiremock.http.RequestMethod.GET;
import static com.github.tomakehurst.wiremock.http.RequestMethod.HEAD;
import static com.github.tomakehurst.wiremock.http.RequestMethod.OPTIONS;
import static com.github.tomakehurst.wiremock.http.RequestMethod.POST;
import static com.github.tomakehurst.wiremock.http.RequestMethod.PUT;
import static com.github.tomakehurst.wiremock.http.RequestMethod.PATCH;
import static com.github.tomakehurst.wiremock.http.RequestMethod.TRACE;
import static com.github.tomakehurst.wiremock.http.Response.response;
public class ProxyResponseRenderer implements ResponseRenderer {
private static final int MINUTES = 1000 * 60;
private static final String TRANSFER_ENCODING = "transfer-encoding";
private static final String CONTENT_LENGTH = "content-length";
private static final String HOST_HEADER = "host";
private final HttpClient client;
private final boolean preserveHostHeader;
private final String hostHeaderValue;
public ProxyResponseRenderer(ProxySettings proxySettings, KeyStoreSettings trustStoreSettings, boolean preserveHostHeader, String hostHeaderValue) {
client = HttpClientFactory.createClient(1000, 5 * MINUTES, proxySettings, trustStoreSettings);
this.preserveHostHeader = preserveHostHeader;
this.hostHeaderValue = hostHeaderValue;
}
public ProxyResponseRenderer() {
this(ProxySettings.NO_PROXY, KeyStoreSettings.NO_STORE, false, null);
}
@Override
public Response render(ResponseDefinition responseDefinition) {
HttpUriRequest httpRequest = getHttpRequestFor(responseDefinition);
addRequestHeaders(httpRequest, responseDefinition);
try {
addBodyIfPostPutOrPatch(httpRequest, responseDefinition);
HttpResponse httpResponse = client.execute(httpRequest);
return response()
.status(httpResponse.getStatusLine().getStatusCode())
.headers(headersFrom(httpResponse, responseDefinition))
.body(getEntityAsByteArrayAndCloseStream(httpResponse))
.fromProxy(true)
.build();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
private HttpHeaders headersFrom(HttpResponse httpResponse, ResponseDefinition responseDefinition) {
List httpHeaders = new LinkedList();
for (Header header : httpResponse.getAllHeaders()) {
httpHeaders.add(new HttpHeader(header.getName(), header.getValue()));
}
if (responseDefinition.getHeaders() != null) {
httpHeaders.addAll(responseDefinition.getHeaders().all());
}
return new HttpHeaders(httpHeaders);
}
private static HttpUriRequest getHttpRequestFor(ResponseDefinition response) {
final RequestMethod method = response.getOriginalRequest().getMethod();
final String url = response.getProxyUrl();
notifier().info("Proxying: " + method + " " + url);
if (method.equals(GET))
return new HttpGet(url);
else if (method.equals(POST))
return new HttpPost(url);
else if (method.equals(PUT))
return new HttpPut(url);
else if (method.equals(DELETE))
return new HttpDelete(url);
else if (method.equals(HEAD))
return new HttpHead(url);
else if (method.equals(OPTIONS))
return new HttpOptions(url);
else if (method.equals(TRACE))
return new HttpTrace(url);
else if (method.equals(PATCH))
return new HttpPatch(url);
else
return new GenericHttpUriRequest(method.toString(), url);
}
private void addRequestHeaders(HttpRequest httpRequest, ResponseDefinition response) {
Request originalRequest = response.getOriginalRequest();
for (String key: originalRequest.getAllHeaderKeys()) {
if (headerShouldBeTransferred(key)) {
if (!HOST_HEADER.equalsIgnoreCase(key) || preserveHostHeader) {
List values = originalRequest.header(key).values();
for (String value: values) {
httpRequest.addHeader(key, value);
}
} else {
if (hostHeaderValue != null) {
httpRequest.addHeader(key, hostHeaderValue);
} else if (response.getProxyBaseUrl() != null) {
httpRequest.addHeader(key, URI.create(response.getProxyBaseUrl()).getAuthority());
}
}
}
}
if (response.getAdditionalProxyRequestHeaders() != null) {
for (String key: response.getAdditionalProxyRequestHeaders().keys()) {
httpRequest.setHeader(key, response.getAdditionalProxyRequestHeaders().getHeader(key).firstValue());
}
}
}
private static boolean headerShouldBeTransferred(String key) {
return !ImmutableList.of(CONTENT_LENGTH, TRANSFER_ENCODING, "connection").contains(key.toLowerCase());
}
private static void addBodyIfPostPutOrPatch(HttpRequest httpRequest, ResponseDefinition response) throws UnsupportedEncodingException {
Request originalRequest = response.getOriginalRequest();
if (originalRequest.getMethod().isOneOf(PUT, POST, PATCH)) {
HttpEntityEnclosingRequest requestWithEntity = (HttpEntityEnclosingRequest) httpRequest;
requestWithEntity.setEntity(buildEntityFrom(originalRequest));
}
}
private static HttpEntity buildEntityFrom(Request originalRequest) {
ContentTypeHeader contentTypeHeader = originalRequest.contentTypeHeader().or("text/plain");
ContentType contentType = ContentType.create(contentTypeHeader.mimeTypePart(), contentTypeHeader.encodingPart().or("utf-8"));
if (originalRequest.containsHeader(TRANSFER_ENCODING) &&
originalRequest.header(TRANSFER_ENCODING).firstValue().equals("chunked")) {
return new InputStreamEntity(new ByteArrayInputStream(originalRequest.getBody()), -1, contentType);
}
return new ByteArrayEntity(originalRequest.getBody());
}
}