This commit is contained in:
Stef Heyenrath
2018-03-17 13:20:18 +01:00
parent 720c59c595
commit 49963dfafc
94 changed files with 24186 additions and 19701 deletions

View File

@@ -1,13 +1,9 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
using JetBrains.Annotations;
using Newtonsoft.Json;
using WireMock.HttpsCertificate;
using WireMock.Util;
using WireMock.Validation;
namespace WireMock.Http
@@ -69,79 +65,14 @@ namespace WireMock.Http
var originalUri = new Uri(requestMessage.Url);
var requiredUri = new Uri(url);
var httpRequestMessage = new HttpRequestMessage(new HttpMethod(requestMessage.Method), url);
// Set Body if present
if (requestMessage.BodyAsBytes != null)
{
httpRequestMessage.Content = new ByteArrayContent(requestMessage.BodyAsBytes);
}
else if (requestMessage.BodyAsJson != null)
{
httpRequestMessage.Content = new StringContent(JsonConvert.SerializeObject(requestMessage.BodyAsJson), requestMessage.BodyEncoding);
}
else if (requestMessage.Body != null)
{
httpRequestMessage.Content = new StringContent(requestMessage.Body, requestMessage.BodyEncoding);
}
// Overwrite the host header
httpRequestMessage.Headers.Host = requiredUri.Authority;
// Set headers if present
if (requestMessage.Headers != null)
{
foreach (var header in requestMessage.Headers.Where(header => !string.Equals(header.Key, "HOST", StringComparison.OrdinalIgnoreCase)))
{
// Try to add to request headers. If failed - try to add to content headers
if (!httpRequestMessage.Headers.TryAddWithoutValidation(header.Key, header.Value))
{
httpRequestMessage.Content?.Headers.TryAddWithoutValidation(header.Key, header.Value);
}
}
}
// Create HttpRequestMessage
var httpRequestMessage = HttpRequestMessageHelper.Create(requestMessage, url);
// Call the URL
var httpResponseMessage = await client.SendAsync(httpRequestMessage, HttpCompletionOption.ResponseContentRead);
// Create transform response
var responseMessage = new ResponseMessage { StatusCode = (int)httpResponseMessage.StatusCode };
// Set both content and response headers, replacing URLs in values
var headers = (httpResponseMessage.Content?.Headers.Union(httpResponseMessage.Headers) ?? Enumerable.Empty<KeyValuePair<string, IEnumerable<string>>>()).ToArray();
if (httpResponseMessage.Content != null)
{
var stream = await httpResponseMessage.Content.ReadAsStreamAsync();
IEnumerable<string> contentTypeHeader = null;
if (headers.Any(header => string.Equals(header.Key, HttpKnownHeaderNames.ContentType, StringComparison.OrdinalIgnoreCase)))
{
contentTypeHeader = headers.First(header => string.Equals(header.Key, HttpKnownHeaderNames.ContentType, StringComparison.OrdinalIgnoreCase)).Value;
}
var body = await BodyParser.Parse(stream, contentTypeHeader?.FirstOrDefault());
responseMessage.Body = body.BodyAsString;
responseMessage.BodyAsJson = body.BodyAsJson;
responseMessage.BodyAsBytes = body.BodyAsBytes;
}
foreach (var header in headers)
{
// If Location header contains absolute redirect URL, and base URL is one that we proxy to,
// we need to replace it to original one.
if (string.Equals(header.Key, HttpKnownHeaderNames.Location, StringComparison.OrdinalIgnoreCase)
&& Uri.TryCreate(header.Value.First(), UriKind.Absolute, out Uri absoluteLocationUri)
&& string.Equals(absoluteLocationUri.Host, requiredUri.Host, StringComparison.OrdinalIgnoreCase))
{
var replacedLocationUri = new Uri(originalUri, absoluteLocationUri.PathAndQuery);
responseMessage.AddHeader(header.Key, replacedLocationUri.ToString());
}
else
{
responseMessage.AddHeader(header.Key, header.Value.ToArray());
}
}
return responseMessage;
// Parse httpResponseMessage
return await HttpResponseMessageHelper.Create(httpResponseMessage, requiredUri, originalUri);
}
}
}

View File

@@ -0,0 +1,86 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Text;
using MimeKit;
using Newtonsoft.Json;
namespace WireMock.Http
{
internal static class HttpRequestMessageHelper
{
public static HttpRequestMessage Create(RequestMessage requestMessage, string url)
{
var httpRequestMessage = new HttpRequestMessage(new HttpMethod(requestMessage.Method), url);
ContentType contentType = null;
if (requestMessage.Headers != null && requestMessage.Headers.ContainsKey(HttpKnownHeaderNames.ContentType))
{
var value = requestMessage.Headers[HttpKnownHeaderNames.ContentType].FirstOrDefault();
ContentType.TryParse(value, out contentType);
}
// Set Body if present
if (requestMessage.BodyAsBytes != null)
{
httpRequestMessage.Content = new ByteArrayContent(requestMessage.BodyAsBytes);
}
else if (requestMessage.BodyAsJson != null)
{
if (contentType != null)
{
var encoding = requestMessage.BodyEncoding ?? Encoding.GetEncoding(contentType.Charset ?? "UTF-8");
httpRequestMessage.Content = new StringContent(JsonConvert.SerializeObject(requestMessage.BodyAsJson), encoding, contentType.MimeType);
}
else
{
httpRequestMessage.Content = new StringContent(JsonConvert.SerializeObject(requestMessage.BodyAsJson), requestMessage.BodyEncoding);
}
}
else if (requestMessage.Body != null)
{
if (contentType != null)
{
var encoding = requestMessage.BodyEncoding ?? Encoding.GetEncoding(contentType.Charset ?? "UTF-8");
httpRequestMessage.Content = new StringContent(requestMessage.Body, encoding, contentType.MimeType);
}
else
{
httpRequestMessage.Content = new StringContent(requestMessage.Body, requestMessage.BodyEncoding);
}
}
// Overwrite the host header
httpRequestMessage.Headers.Host = new Uri(url).Authority;
// Set other headers if present and if not excluded
if (requestMessage.Headers == null || requestMessage.Headers.Count == 0)
{
return httpRequestMessage;
}
var excludeHeaders = new List<string> { HttpKnownHeaderNames.Host, HttpKnownHeaderNames.ContentLength };
if (contentType != null)
{
excludeHeaders.Add(HttpKnownHeaderNames.ContentType);
}
foreach (var header in requestMessage.Headers.Where(h => !excludeHeaders.Contains(h.Key, StringComparer.OrdinalIgnoreCase)))
{
// Try to add to request headers. If failed - try to add to content headers
if (httpRequestMessage.Headers.Contains(header.Key))
{
continue;
}
if (!httpRequestMessage.Headers.TryAddWithoutValidation(header.Key, header.Value))
{
httpRequestMessage.Content.Headers.TryAddWithoutValidation(header.Key, header.Value);
}
}
return httpRequestMessage;
}
}
}

View File

@@ -0,0 +1,53 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Threading.Tasks;
using WireMock.Util;
namespace WireMock.Http
{
internal static class HttpResponseMessageHelper
{
public static async Task<ResponseMessage> Create(HttpResponseMessage httpResponseMessage, Uri requiredUri, Uri originalUri)
{
var responseMessage = new ResponseMessage { StatusCode = (int)httpResponseMessage.StatusCode };
// Set both content and response headers, replacing URLs in values
var headers = (httpResponseMessage.Content?.Headers.Union(httpResponseMessage.Headers) ?? Enumerable.Empty<KeyValuePair<string, IEnumerable<string>>>()).ToArray();
if (httpResponseMessage.Content != null)
{
var stream = await httpResponseMessage.Content.ReadAsStreamAsync();
IEnumerable<string> contentTypeHeader = null;
if (headers.Any(header => string.Equals(header.Key, HttpKnownHeaderNames.ContentType, StringComparison.OrdinalIgnoreCase)))
{
contentTypeHeader = headers.First(header => string.Equals(header.Key, HttpKnownHeaderNames.ContentType, StringComparison.OrdinalIgnoreCase)).Value;
}
var body = await BodyParser.Parse(stream, contentTypeHeader?.FirstOrDefault());
responseMessage.Body = body.BodyAsString;
responseMessage.BodyAsJson = body.BodyAsJson;
responseMessage.BodyAsBytes = body.BodyAsBytes;
}
foreach (var header in headers)
{
// If Location header contains absolute redirect URL, and base URL is one that we proxy to,
// we need to replace it to original one.
if (string.Equals(header.Key, HttpKnownHeaderNames.Location, StringComparison.OrdinalIgnoreCase)
&& Uri.TryCreate(header.Value.First(), UriKind.Absolute, out Uri absoluteLocationUri)
&& string.Equals(absoluteLocationUri.Host, requiredUri.Host, StringComparison.OrdinalIgnoreCase))
{
var replacedLocationUri = new Uri(originalUri, absoluteLocationUri.PathAndQuery);
responseMessage.AddHeader(header.Key, replacedLocationUri.ToString());
}
else
{
responseMessage.AddHeader(header.Key, header.Value.ToArray());
}
}
return responseMessage;
}
}
}