Exemple #1
0
        private bool DefaultMatchingAlgorithm(
            InterceptedRequest interceptedRequest,
            RecordedRequest recordedRequest)
        {
            if (null == interceptedRequest || null == recordedRequest)
            {
                return(false);
            }

            var urlMatches =
                string.Equals(
                    interceptedRequest.HttpWebRequest.RequestUri?.ToString().RemoveTrailingSlash() ?? "",
                    recordedRequest.Url?.RemoveTrailingSlash(),
                    StringComparison.InvariantCultureIgnoreCase);

            var methodMatches =
                string.Equals(
                    interceptedRequest.HttpWebRequest.Method ?? "",
                    recordedRequest.Method,
                    StringComparison.InvariantCultureIgnoreCase);

            var requestPayloadMatches =
                true == interceptedRequest?.RequestPayload.Equals(recordedRequest.RequestPayload);

            var requestHeadersMatch =
                recordedRequest.RequestHeaders.Equals(interceptedRequest.HttpWebRequest.Headers);

            return
                (urlMatches &&
                 methodMatches &&
                 requestPayloadMatches &&
                 requestHeadersMatch);
        }
Exemple #2
0
        /// <summary>
        /// 1. Use <see cref="MatchingAlgorithm"/> to find a match from <see cref="RecordedRequests"/>.
        /// <para />
        /// 2. Use either <see cref="RecordedResultResponseBuilder"/> or <see cref="RequestNotFoundResponseBuilder"/>
        /// to build a <see cref="HttpWebResponse"/>.
        /// <para />
        /// 3. Fire <see cref="OnMatch"/>
        /// <para />
        /// 4. Honor <see cref="AllowReplayingRecordedRequestsMultipleTimes"/> and remove the matched
        /// <see cref="RecordedRequest"/> from <see cref="RecordedRequests"/>
        /// <para />
        /// 5. Return the <see cref="HttpWebResponse"/>. aka Profit!
        /// </summary>
        public HttpWebResponse BuildResponse(InterceptedRequest intercepted)
        {
            lock (_buildResponseLock)
            {
                var matchedRecordedRequest =
                    RecordedRequests
                    .FirstOrDefault(recorded => MatchingAlgorithm(intercepted, recorded));

                try
                {
                    var response =
                        null != matchedRecordedRequest
                            ? RecordedResultResponseBuilder(matchedRecordedRequest, intercepted)
                            : RequestNotFoundResponseBuilder(intercepted);

                    OnMatch?.Invoke(matchedRecordedRequest, intercepted, response, null);

                    return(response);
                }
                catch (Exception e)
                {
                    OnMatch?.Invoke(matchedRecordedRequest, intercepted, null, e);
                    throw;
                }
                finally
                {
                    if (!AllowReplayingRecordedRequestsMultipleTimes &&
                        null != matchedRecordedRequest)
                    {
                        RecordedRequests.Remove(matchedRecordedRequest);
                    }
                }
            }
        }
Exemple #3
0
        /// <inheritdoc />
        public override WebResponse GetResponse()
        {
            HttpWebResponse passThroughShadowCopy = null;
            var             interceptedRequest    = new InterceptedRequest
            {
                RequestPayload =
                    new RecordedStream(
                        _requestStream.ToArray(),
                        this),
                HttpWebRequest         = this,
                HttpWebResponseCreator = new HttpWebResponseInterceptorCreator(RequestUri, Method, AutomaticDecompression),
                PassThroughResponse    = () =>
                {
                    // if we are going to pass through - we need to use the base.GetRequest
                    // to copy over the request stream (as well as set some additional headers like Content-Length)
                    if (_requestStream.ToArray().Length > 0)
                    {
                        using (var requestStream = base.GetRequestStream())
                            new MemoryStream(_requestStream.ToArray()).WriteTo(requestStream);
                    }

                    // save the pass through so we'll know if _responseCreator
                    // returned that to us - if so we don't want to try and
                    // perform any initialization
                    passThroughShadowCopy = (HttpWebResponse)base.GetResponse();
                    return(passThroughShadowCopy);
                }
            };

            var response = _responseCreator(interceptedRequest);

            if (response == passThroughShadowCopy)
            {
                // short circuit
                return(passThroughShadowCopy);
            }

            // set response to HttpWebRequest's internal field
            ReflectionExtensions.SetField(this, "_HttpResponse", response);

            // wire up cookies - static void CookieModule.OnReceivedHeaders(HttpWebRequest)
            var cookieModuleType = typeof(HttpWebRequest).Assembly.GetType("System.Net.CookieModule");

            // ReSharper disable once PossibleNullReferenceException
            cookieModuleType
            .GetMethod("OnReceivedHeaders", BindingFlags.Static | BindingFlags.NonPublic)
            .Invoke(null, new object[] { this });

            return(response);
        }
Exemple #4
0
        /// <remarks>
        /// This is static so it can be referenced in constructor chaining
        /// </remarks>
        private static HttpWebResponse DefaultRequestNotFoundResponseBuilder(
            InterceptedRequest interceptedRequest,
            RequestNotFoundBehavior behavior)
        {
            switch (behavior)
            {
            case RequestNotFoundBehavior.PassThrough:
                return(interceptedRequest.PassThroughResponse());

            case RequestNotFoundBehavior.Return404:
                return(interceptedRequest
                       .HttpWebResponseCreator.Create(
                           $"Request not found in {nameof(RecordedRequests)}",
                           HttpStatusCode.NotFound));

            default:
                throw new InvalidEnumArgumentException(
                          $"Don't know how to handle behavior [{Enum.GetName(typeof(RequestNotFoundBehavior), behavior)}].  " +
                          $"This is a bug in the {nameof(HttpWebRequestWrapper)} library.");
            }
        }
Exemple #5
0
        private HttpWebResponse DefaultRecordedResultResponseBuilder(
            RecordedRequest recordedRequest,
            InterceptedRequest interceptedRequest)
        {
            var headers = new WebHeaderCollection();

            if (null != recordedRequest.ResponseHeaders)
            {
                headers.Add(recordedRequest.ResponseHeaders);
            }

            if (recordedRequest.TryGetResponseException(out var recordedException))
            {
                // throw the recorded exception and let it bubble up
                throw recordedException;
            }

            return(interceptedRequest.HttpWebResponseCreator.Create(
                       recordedRequest.ResponseBody.ToStream(),
                       recordedRequest.ResponseStatusCode,
                       headers));
        }