예제 #1
0
        public static async Task <ResponseMessage> CreateAsync(HttpResponseMessage httpResponseMessage, Uri requiredUri, Uri originalUri, bool deserializeJson, bool decompressGzipAndDeflate)
        {
            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;
                }

                IEnumerable <string> contentEncodingHeader = null;
                if (headers.Any(header => string.Equals(header.Key, HttpKnownHeaderNames.ContentEncoding, StringComparison.OrdinalIgnoreCase)))
                {
                    contentEncodingHeader = headers.First(header => string.Equals(header.Key, HttpKnownHeaderNames.ContentEncoding, StringComparison.OrdinalIgnoreCase)).Value;
                }

                var bodyParserSettings = new BodyParserSettings
                {
                    Stream                   = stream,
                    ContentType              = contentTypeHeader?.FirstOrDefault(),
                    DeserializeJson          = deserializeJson,
                    ContentEncoding          = contentEncodingHeader?.FirstOrDefault(),
                    DecompressGZipAndDeflate = decompressGzipAndDeflate
                };
                responseMessage.BodyData = await BodyParser.Parse(bodyParserSettings);
            }

            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);
        }
예제 #2
0
        /// <inheritdoc cref="IHeadersResponseBuilder.WithHeader(string, string[])"/>
        public IResponseBuilder WithHeader(string name, params string[] values)
        {
            Check.NotNull(name, nameof(name));

            ResponseMessage.AddHeader(name, values);
            return(this);
        }
        public async Task <ResultResponseMessage <ResponseMessage> > QueuesAsync(RequestMessage request)
        {
            IEnumerable <SampleMessage> samplesMessages = new List <SampleMessage>();

            try
            {
                var samplesModelListResult = await SampleService.GetToSendQueueAsync();

                samplesMessages = SampleMessageMapper.FromModel(samplesModelListResult.Models);

                if (samplesMessages.Any())
                {
                    await SendToQueue(samplesMessages, request.GetHeader(Headers.Protocol));
                }

                var result          = new ResultResponseMessage <ResponseMessage>(request);
                var responseMessage = new ResponseMessage();

                responseMessage.AddHeader("Queued-Total", samplesMessages.Count().ToString());
                result.SetReturn(responseMessage);
                result.CreateResponseAccepted();
                return(result);
            }
            catch
            {
                await SampleService.UndoSendQueueAsync(samplesMessages.Select(it => it.IdSample));

                throw;
            }
        }
        public void Should_map_headers_from_original_response()
        {
            // given
            var response = new ResponseMessage();

            response.AddHeader("cache-control", "no-cache");
            var httpListenerResponse = CreateHttpListenerResponse();

            // when
            new HttpListenerResponseMapper().Map(response, httpListenerResponse);

            // then
            Check.That(httpListenerResponse.Headers).HasSize(1);
            Check.That(httpListenerResponse.Headers.Keys).Contains("cache-control");
            Check.That(httpListenerResponse.Headers.Get("cache-control")).Contains("no-cache");
        }
예제 #5
0
        public static async Task <ResponseMessage> SendAsync(RequestMessage requestMessage, string url)
        {
            var httpRequestMessage = new HttpRequestMessage(new HttpMethod(requestMessage.Method), url);

            // Overwrite the host header
            httpRequestMessage.Headers.Host = new Uri(url).Authority;

            // Set headers if present
            if (requestMessage.Headers != null)
            {
                foreach (var headerName in requestMessage.Headers.Keys.Where(k => k.ToUpper() != "HOST"))
                {
                    httpRequestMessage.Headers.Add(headerName, new[] { requestMessage.Headers[headerName] });
                }
            }

            // Set Body if present
            if (requestMessage.BodyAsBytes != null && requestMessage.BodyAsBytes.Length > 0)
            {
                httpRequestMessage.Content = new ByteArrayContent(requestMessage.BodyAsBytes);
            }

            // Call the URL
            var httpResponseMessage = await client.SendAsync(httpRequestMessage, HttpCompletionOption.ResponseContentRead);

            // Transform response
            var responseMessage = new ResponseMessage
            {
                StatusCode = (int)httpResponseMessage.StatusCode,
                Body       = await httpResponseMessage.Content.ReadAsStringAsync()
            };

            foreach (var header in httpResponseMessage.Headers)
            {
                responseMessage.AddHeader(header.Key, header.Value.FirstOrDefault());
            }

            return(responseMessage);
        }
        public async Task Invoke(HttpContext ctx)
#endif
        {
            _options.Logger.Debug("New Task Invoke with Request: '{0}'", JsonConvert.SerializeObject(new { Headers = ctx.Request.Headers, Body = "Body not logged here." }));

            var request = await _requestMapper.MapAsync(ctx.Request);

            var logRequestStr = JsonConvert.SerializeObject(request);

            _options.Logger.Debug("Start Finding matching mapping for Request: '{0}'", logRequestStr);

            bool               logRequest         = false;
            ResponseMessage    response           = null;
            Mapping            targetMapping      = null;
            RequestMatchResult requestMatchResult = null;

            System.Collections.Generic.Dictionary <Mapping, RequestMatchResult> log_mappings = new System.Collections.Generic.Dictionary <Mapping, RequestMatchResult>();
            try
            {
                _options.Logger.Debug("Start Scenario mappings for Request: '{0}'", logRequestStr);
                foreach (var mapping in _options.Mappings.Values.Where(m => m?.Scenario != null))
                {
                    // Set start
                    if (!_options.Scenarios.ContainsKey(mapping.Scenario) && mapping.IsStartState)
                    {
                        _options.Scenarios.Add(mapping.Scenario, null);
                    }
                }
                _options.Logger.Debug("Done Getting Scenario mappings for Request: '{0}'", logRequestStr);

                _options.Logger.Debug("Start iterating mapping matchings for Request: '{0}'", logRequestStr);
                var mappings = _options.Mappings.Values
                               .Select(m => new
                {
                    Mapping     = m,
                    MatchResult = m.GetRequestMatchResult(request, m.Scenario != null && _options.Scenarios.ContainsKey(m.Scenario) ? _options.Scenarios[m.Scenario] : null)
                })
                               .ToList();
                _options.Logger.Debug("Done iterating mapping matchings for Request: '{0}'", logRequestStr);

                foreach (var mapping in mappings)
                {
                    if (mapping.MatchResult.LogThis)
                    {
                        log_mappings.Add(mapping.Mapping, mapping.MatchResult);
                    }
                }

                if (_options.AllowPartialMapping)
                {
                    _options.Logger.Debug("Start AllowPartialMapping steps for Request: '{0}'", logRequestStr);
                    var partialMappings = mappings
                                          .Where(pm => pm.Mapping.IsAdminInterface && pm.MatchResult.IsPerfectMatch || !pm.Mapping.IsAdminInterface)
                                          .OrderBy(m => m.MatchResult)
                                          .ThenBy(m => m.Mapping.Priority)
                                          .ToList();

                    var bestPartialMatch = partialMappings.FirstOrDefault(pm => pm.MatchResult.AverageTotalScore > 0.0);

                    targetMapping      = bestPartialMatch?.Mapping;
                    requestMatchResult = bestPartialMatch?.MatchResult;
                    _options.Logger.Info("Got PartialMapping steps for Request: '{0}', Mapping: '{1}'", logRequestStr, JsonConvert.SerializeObject(requestMatchResult));
                    _options.Logger.Debug("Done AllowPartialMapping steps for Request: '{0}'", logRequestStr);
                }
                else
                {
                    _options.Logger.Debug("Start Perfect mapping steps for Request: '{0}'", logRequestStr);

                    var perfectMatch = mappings
                                       .OrderBy(m => m.Mapping.Priority)
                                       .FirstOrDefault(m => m.MatchResult.IsPerfectMatch);

                    targetMapping      = perfectMatch?.Mapping;
                    requestMatchResult = perfectMatch?.MatchResult;

                    _options.Logger.Debug("Done Perfect mapping steps for Request: '{0}'", logRequestStr);
                }

                if (targetMapping == null)
                {
                    logRequest = true;
                    _options.Logger.Warn("HttpStatusCode set to 404 : No matching mapping found for request: '{0}'", logRequestStr);
                    response = new ResponseMessage {
                        StatusCode = 404, Body = JsonConvert.SerializeObject(new { Error = "No matching mapping found", RequestMessage = request, LoggedMapFailures = log_mappings })
                    };
                    response.AddHeader("Content-Type", "application/json");
                    return;
                }

                logRequest = !targetMapping.IsAdminInterface;

                if (targetMapping.IsAdminInterface && _options.AuthorizationMatcher != null)
                {
                    bool present = request.Headers.TryGetValue(HttpKnownHeaderNames.Authorization, out WireMockList <string> authorization);
                    if (!present || _options.AuthorizationMatcher.IsMatch(authorization.ToString()) < MatchScores.Perfect)
                    {
                        _options.Logger.Error("HttpStatusCode set to 401 : For request: '{0}'", logRequestStr);
                        response = new ResponseMessage {
                            StatusCode = 401
                        };
                        return;
                    }
                }

                if (!targetMapping.IsAdminInterface && _options.RequestProcessingDelay > TimeSpan.Zero)
                {
                    await Task.Delay(_options.RequestProcessingDelay.Value);
                }

                response = await targetMapping.ResponseToAsync(request);

                if (targetMapping.Scenario != null)
                {
                    _options.Scenarios[targetMapping.Scenario] = targetMapping.NextState;
                }

                if (targetMapping != null)
                {
                    _options.Logger.Info("Matching mapping found for Request: '{0}', Mapping: '{1}'", logRequestStr, JsonConvert.SerializeObject(targetMapping));
                }

                _options.Logger.Debug("Done Finding matching mapping for Request: '{0}'", logRequestStr);
            }
            catch (Exception ex)
            {
                _options.Logger.Error("Exception thrown: HttpStatusCode set to 500, Exception: '{0}'", ex.ToString());
                response = new ResponseMessage {
                    StatusCode = 500, Body = JsonConvert.SerializeObject(ex)
                };
            }
            finally
            {
                foreach (Mapping mapping in log_mappings.Keys)
                {
                    var faillog = new LogEntry
                    {
                        Timestamp          = DateTime.Now,
                        Guid               = Guid.NewGuid(),
                        RequestMessage     = request,
                        ResponseMessage    = response,
                        MappingGuid        = mapping?.Guid,
                        MappingTitle       = mapping?.Title,
                        RequestMatchResult = log_mappings[mapping]
                    };
                    LogMatch(faillog, true, "");
                }
                var log = new LogEntry
                {
                    Timestamp          = DateTime.Now,
                    Guid               = Guid.NewGuid(),
                    RequestMessage     = request,
                    ResponseMessage    = response,
                    MappingGuid        = targetMapping?.Guid,
                    MappingTitle       = targetMapping?.Title,
                    RequestMatchResult = requestMatchResult
                };

                LogRequest(log, logRequest);

                await _responseMapper.MapAsync(response, ctx.Response);
            }

            await CompletedTask;
        }
예제 #7
0
        public static async Task <ResponseMessage> SendAsync([NotNull] HttpClient client, [NotNull] RequestMessage requestMessage, string url)
        {
            Check.NotNull(client, nameof(client));
            Check.NotNull(requestMessage, nameof(requestMessage));

            var originalUri = new Uri(requestMessage.Url);
            var requiredUri = new Uri(url);

            var httpRequestMessage = new HttpRequestMessage(new HttpMethod(requestMessage.Method), url);

            WireMockList <string> contentTypeHeader = null;
            bool contentTypeHeaderPresent           = requestMessage.Headers.Any(header => string.Equals(header.Key, HttpKnownHeaderNames.ContentType, StringComparison.OrdinalIgnoreCase));

            if (contentTypeHeaderPresent)
            {
                contentTypeHeader = requestMessage.Headers[HttpKnownHeaderNames.ContentType];
            }

            // 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);
                    }
                }
            }

            // 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();

                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);
        }
예제 #8
0
        public static async Task <ResponseMessage> SendAsync(HttpClient client, RequestMessage requestMessage, string url)
        {
            Check.NotNull(client, nameof(client));

            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 && requestMessage.BodyAsBytes.Length > 0)
            {
                httpRequestMessage.Content = new ByteArrayContent(requestMessage.BodyAsBytes);
            }

            // 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);
                    }
                }
            }

            // Call the URL
            var httpResponseMessage = await client.SendAsync(httpRequestMessage, HttpCompletionOption.ResponseContentRead);

            // Transform response
            var responseMessage = new ResponseMessage
            {
                StatusCode = (int)httpResponseMessage.StatusCode,

                BodyAsBytes = await httpResponseMessage.Content.ReadAsByteArrayAsync(),
                Body        = await httpResponseMessage.Content.ReadAsStringAsync()
            };

            // Set both content and response headers, replacing URLs in values
            var headers = httpResponseMessage.Content?.Headers.Union(httpResponseMessage.Headers);

            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, "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);
        }