using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Net; using JetBrains.Annotations; using WireMock.Util; using WireMock.Validation; namespace WireMock { /// /// The request. /// public class RequestMessage { /// /// Gets the Client IP Address. /// public string ClientIP { get; } /// /// Gets the url. /// public string Url { get; } /// /// Gets the DateTime. /// public DateTime DateTime { get; set; } /// /// Gets the path. /// public string Path { get; } /// /// Gets the path segments. /// public string[] PathSegments { get; } /// /// Gets the method. /// public string Method { get; } /// /// Gets the headers. /// public IDictionary> Headers { get; } /// /// Gets the cookies. /// public IDictionary Cookies { get; } /// /// Gets the query. /// public IDictionary> Query { get; } /// /// Gets the raw query. /// public string RawQuery { get; } /// /// The original body as string, this is defined when Body or BodyAsJson are not null. /// public string Body { get; } /// /// The body (as JSON object). /// public object BodyAsJson { get; set; } /// /// The body (as bytearray). /// public byte[] BodyAsBytes { get; set; } /// /// Gets the Host /// public string Host { get; } /// /// Gets the protocol /// public string Protocol { get; } /// /// Gets the port /// public int Port { get; } /// /// Gets the origin /// public string Origin { get; } /// /// The body encoding. /// public Encoding BodyEncoding { get; } /// /// Initializes a new instance of the class. /// /// The original url. /// The HTTP method. /// The client IP Address. /// The body. /// The headers. /// The cookies. public RequestMessage([NotNull] Uri url, [NotNull] string method, [NotNull] string clientIP, [CanBeNull] BodyData body = null, [CanBeNull] IDictionary headers = null, [CanBeNull] IDictionary cookies = null) { Check.NotNull(url, nameof(url)); Check.NotNull(method, nameof(method)); Check.NotNull(clientIP, nameof(clientIP)); Url = url.ToString(); Protocol = url.Scheme; Host = url.Host; Port = url.Port; Origin = $"{url.Scheme}://{url.Host}:{url.Port}"; Path = WebUtility.UrlDecode(url.AbsolutePath); PathSegments = Path.Split('/').Skip(1).ToArray(); Method = method.ToLower(); ClientIP = clientIP; Body = body?.BodyAsString; BodyEncoding = body?.Encoding; BodyAsJson = body?.BodyAsJson; BodyAsBytes = body?.BodyAsBytes; Headers = headers?.ToDictionary(header => header.Key, header => new WireMockList(header.Value)); Cookies = cookies; RawQuery = WebUtility.UrlDecode(url.Query); Query = ParseQuery(RawQuery); } private static IDictionary> ParseQuery(string queryString) { if (string.IsNullOrEmpty(queryString)) { return null; } if (queryString.StartsWith("?")) { queryString = queryString.Substring(1); } return queryString.Split(new[] { '&' }, StringSplitOptions.RemoveEmptyEntries) .Aggregate(new Dictionary>(), (dict, term) => { string[] parts = term.Split(new[] { '=' }, StringSplitOptions.RemoveEmptyEntries); string key = parts[0]; if (!dict.ContainsKey(key)) { dict.Add(key, new WireMockList()); } if (parts.Length == 2) { string[] values = parts[1].Split(new[] { "," }, StringSplitOptions.RemoveEmptyEntries); dict[key].AddRange(values); } return dict; }); } /// /// Get a query parameter. /// /// The key. /// The query parameter. public WireMockList GetParameter(string key) { if (Query == null) { return null; } return Query.ContainsKey(key) ? Query[key] : null; } } }