using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Net; using System.Net.Http; using System.Text; using System.Threading.Tasks; using JetBrains.Annotations; using Newtonsoft.Json; using WireMock.Http; using WireMock.Settings; using WireMock.Transformers; using WireMock.Util; using WireMock.Validation; namespace WireMock.ResponseBuilders { /// /// The Response. /// public class Response : IResponseBuilder { private HttpClient _httpClientForProxy; /// /// The delay /// public TimeSpan? Delay { get; private set; } /// /// Gets a value indicating whether [use transformer]. /// /// /// true if [use transformer]; otherwise, false. /// public bool UseTransformer { get; private set; } /// /// The Proxy URL to use. /// public string ProxyUrl { get; private set; } /// /// The client X509Certificate2 Thumbprint or SubjectName to use. /// public string ClientX509Certificate2ThumbprintOrSubjectName { get; private set; } /// /// Gets the response message. /// /// /// The response message. /// public ResponseMessage ResponseMessage { get; } /// /// Creates this instance. /// /// ResponseMessage /// A . [PublicAPI] public static IResponseBuilder Create([CanBeNull] ResponseMessage responseMessage = null) { var message = responseMessage ?? new ResponseMessage { StatusCode = (int)HttpStatusCode.OK }; return new Response(message); } /// /// Creates this instance. /// /// A . [PublicAPI] public static IResponseBuilder Create([NotNull] Func func) { Check.NotNull(func, nameof(func)); return new Response(func()); } /// /// Initializes a new instance of the class. /// /// /// The response. /// private Response(ResponseMessage responseMessage) { ResponseMessage = responseMessage; } /// /// The with status code. /// /// The code. /// A .\ [PublicAPI] public IResponseBuilder WithStatusCode(int code) { ResponseMessage.StatusCode = code; return this; } /// /// The with status code. /// /// The code. /// A . [PublicAPI] public IResponseBuilder WithStatusCode(HttpStatusCode code) { return WithStatusCode((int)code); } /// /// The with Success status code (200). /// /// A . [PublicAPI] public IResponseBuilder WithSuccess() { return WithStatusCode((int)HttpStatusCode.OK); } /// /// The with NotFound status code (404). /// /// The . [PublicAPI] public IResponseBuilder WithNotFound() { return WithStatusCode((int)HttpStatusCode.NotFound); } /// public IResponseBuilder WithHeader(string name, params string[] values) { Check.NotNull(name, nameof(name)); ResponseMessage.AddHeader(name, values); return this; } /// public IResponseBuilder WithHeaders(IDictionary headers) { Check.NotNull(headers, nameof(headers)); ResponseMessage.Headers = headers.ToDictionary(header => header.Key, header => new WireMockList(header.Value)); return this; } /// public IResponseBuilder WithHeaders(IDictionary headers) { Check.NotNull(headers, nameof(headers)); ResponseMessage.Headers = headers.ToDictionary(header => header.Key, header => new WireMockList(header.Value)); return this; } /// public IResponseBuilder WithHeaders(IDictionary> headers) { ResponseMessage.Headers = headers; return this; } /// public IResponseBuilder WithBody(byte[] body, string destination, Encoding encoding = null) { Check.NotNull(body, nameof(body)); ResponseMessage.BodyDestination = destination; switch (destination) { case BodyDestinationFormat.String: var enc = encoding ?? Encoding.UTF8; ResponseMessage.BodyAsBytes = null; ResponseMessage.Body = enc.GetString(body); ResponseMessage.BodyEncoding = enc; break; default: ResponseMessage.BodyAsBytes = body; ResponseMessage.BodyEncoding = null; break; } return this; } /// public IResponseBuilder WithBodyFromFile(string filename, bool cache = true) { Check.NotNull(filename, nameof(filename)); ResponseMessage.BodyEncoding = null; ResponseMessage.BodyAsFileIsCached = cache; if (cache) { ResponseMessage.Body = null; ResponseMessage.BodyAsBytes = File.ReadAllBytes(filename); ResponseMessage.BodyAsFile = null; } else { ResponseMessage.Body = null; ResponseMessage.BodyAsBytes = null; ResponseMessage.BodyAsFile = filename; } return this; } /// public IResponseBuilder WithBody(string body, string destination = BodyDestinationFormat.SameAsSource, Encoding encoding = null) { Check.NotNull(body, nameof(body)); encoding = encoding ?? Encoding.UTF8; ResponseMessage.BodyDestination = destination; switch (destination) { case BodyDestinationFormat.Bytes: ResponseMessage.Body = null; ResponseMessage.BodyAsBytes = encoding.GetBytes(body); ResponseMessage.BodyEncoding = encoding; break; default: ResponseMessage.Body = body; ResponseMessage.BodyAsBytes = null; ResponseMessage.BodyEncoding = encoding; break; } return this; } /// public IResponseBuilder WithBodyAsJson(object body, Encoding encoding = null) { Check.NotNull(body, nameof(body)); string jsonBody = JsonConvert.SerializeObject(body, new JsonSerializerSettings { Formatting = Formatting.None, NullValueHandling = NullValueHandling.Ignore }); if (encoding != null && !encoding.Equals(Encoding.UTF8)) { jsonBody = encoding.GetString(Encoding.UTF8.GetBytes(jsonBody)); ResponseMessage.BodyEncoding = encoding; } ResponseMessage.BodyDestination = null; ResponseMessage.Body = jsonBody; return this; } /// public IResponseBuilder WithBodyFromBase64(string bodyAsbase64, Encoding encoding = null) { Check.NotNull(bodyAsbase64, nameof(bodyAsbase64)); encoding = encoding ?? Encoding.UTF8; ResponseMessage.BodyDestination = null; ResponseMessage.Body = encoding.GetString(Convert.FromBase64String(bodyAsbase64)); ResponseMessage.BodyEncoding = encoding; return this; } /// public IResponseBuilder WithTransformer() { UseTransformer = true; return this; } /// public IResponseBuilder WithDelay(TimeSpan delay) { Check.Condition(delay, d => d > TimeSpan.Zero, nameof(delay)); Delay = delay; return this; } /// public IResponseBuilder WithDelay(int milliseconds) { return WithDelay(TimeSpan.FromMilliseconds(milliseconds)); } /// public IResponseBuilder WithProxy(string proxyUrl, string clientX509Certificate2ThumbprintOrSubjectName = null) { Check.NotEmpty(proxyUrl, nameof(proxyUrl)); ProxyUrl = proxyUrl; ClientX509Certificate2ThumbprintOrSubjectName = clientX509Certificate2ThumbprintOrSubjectName; _httpClientForProxy = HttpClientHelper.CreateHttpClient(clientX509Certificate2ThumbprintOrSubjectName); return this; } /// public IResponseBuilder WithProxy(IProxyAndRecordSettings settings) { Check.NotNull(settings, nameof(settings)); return WithProxy(settings.Url, settings.ClientX509Certificate2ThumbprintOrSubjectName); } /// /// The provide response. /// /// The request. /// The . public async Task ProvideResponseAsync(RequestMessage requestMessage) { Check.NotNull(requestMessage, nameof(requestMessage)); if (Delay != null) { await Task.Delay(Delay.Value); } if (ProxyUrl != null && _httpClientForProxy != null) { var requestUri = new Uri(requestMessage.Url); var proxyUri = new Uri(ProxyUrl); var proxyUriWithRequestPathAndQuery = new Uri(proxyUri, requestUri.PathAndQuery); return await HttpClientHelper.SendAsync(_httpClientForProxy, requestMessage, proxyUriWithRequestPathAndQuery.AbsoluteUri); } if (UseTransformer) { return ResponseMessageTransformer.Transform(requestMessage, ResponseMessage); } return ResponseMessage; } } }