public void BuilderSetsResponseBody()
        {
            // ARRANGE
            var recordedRequest = new RecordedRequest
            {
                Url          = "http://fakeSite.fake",
                Method       = "GET",
                ResponseBody = "Response Body"
            };

            var recordingSession = new RecordingSession {
                RecordedRequests = new List <RecordedRequest> {
                    recordedRequest
                }
            };

            var requestBuilder = new RecordingSessionInterceptorRequestBuilder(recordingSession);

            IWebRequestCreate creator = new HttpWebRequestWrapperInterceptorCreator(requestBuilder);

            var request = creator.Create(new Uri(recordedRequest.Url));

            // ACT
            var response = request.GetResponse();

            // ASSERT
            response.ShouldNotBeNull();

            using (var sr = new StreamReader(response.GetResponseStream()))
                sr.ReadToEnd().ShouldEqual(recordedRequest.ResponseBody.SerializedStream);
        }
        public void CanCustomizeResponseBuilder()
        {
            // ARRANGE
            var customResponseBody = "Custom Response";
            var recordedRequest    = new RecordedRequest
            {
                Url    = "http://fakeSite.fake",
                Method = "GET"
            };

            var recordingSession = new RecordingSession {
                RecordedRequests = new List <RecordedRequest> {
                    recordedRequest
                }
            };

            var requestBuilder = new RecordingSessionInterceptorRequestBuilder(recordingSession)
            {
                RecordedResultResponseBuilder =
                    (recordedReq, interceptedReq) => interceptedReq.HttpWebResponseCreator.Create(customResponseBody)
            };

            IWebRequestCreate creator = new HttpWebRequestWrapperInterceptorCreator(requestBuilder);

            var request = creator.Create(new Uri(recordedRequest.Url));

            // ACT
            var response = request.GetResponse();

            // ASSERT
            response.ShouldNotBeNull();

            using (var sr = new StreamReader(response.GetResponseStream()))
                sr.ReadToEnd().ShouldEqual(customResponseBody);
        }
        public void BuilderSetsInvalidOperationException()
        {
            // ARRANGE
            var recordedRequest = new RecordedRequest
            {
                Url               = "http://fakeSite.fake",
                Method            = "GET",
                ResponseException = new RecordedResponseException
                {
                    Message = "Test Exception Message",
                    Type    = typeof(InvalidOperationException)
                }
            };

            var recordingSession = new RecordingSession {
                RecordedRequests = new List <RecordedRequest> {
                    recordedRequest
                }
            };

            var requestBuilder = new RecordingSessionInterceptorRequestBuilder(recordingSession);

            IWebRequestCreate creator = new HttpWebRequestWrapperInterceptorCreator(requestBuilder);

            var request = creator.Create(new Uri(recordedRequest.Url));

            // ACT
            var exception = Record.Exception(() => request.GetResponse());

            // ASSERT
            exception.ShouldNotBeNull();
            exception.ShouldBeType <InvalidOperationException>();
            exception.Message.ShouldEqual(recordedRequest.ResponseException.Message);
        }
        public void BuilderSetsResponseStatusCode()
        {
            // ARRANGE
            var recordedRequest = new RecordedRequest
            {
                Url                = "http://fakeSite.fake",
                Method             = "GET",
                ResponseStatusCode = HttpStatusCode.Forbidden
            };

            var recordingSession = new RecordingSession {
                RecordedRequests = new List <RecordedRequest> {
                    recordedRequest
                }
            };

            var requestBuilder = new RecordingSessionInterceptorRequestBuilder(recordingSession);

            IWebRequestCreate creator = new HttpWebRequestWrapperInterceptorCreator(requestBuilder);

            var request = creator.Create(new Uri(recordedRequest.Url));

            // ACT
            var response = (HttpWebResponse)request.GetResponse();

            // ASSERT
            response.ShouldNotBeNull();
            response.StatusCode.ShouldEqual(recordedRequest.ResponseStatusCode);
        }
        public void BuilderSetsResponseHeaders()
        {
            // ARRANGE
            var recordedRequest = new RecordedRequest
            {
                Url             = "http://fakeSite.fake",
                Method          = "GET",
                ResponseHeaders = new RecordedHeaders {
                    { "Header1", new [] { "Header1Value" } }
                }
            };

            var recordingSession = new RecordingSession {
                RecordedRequests = new List <RecordedRequest> {
                    recordedRequest
                }
            };

            var requestBuilder = new RecordingSessionInterceptorRequestBuilder(recordingSession);

            IWebRequestCreate creator = new HttpWebRequestWrapperInterceptorCreator(requestBuilder);

            var request = creator.Create(new Uri(recordedRequest.Url));

            // ACT
            var response = (HttpWebResponse)request.GetResponse();

            // ASSERT
            response.ShouldNotBeNull();

            recordedRequest.ResponseHeaders.ShouldEqual((RecordedHeaders)response.Headers);
        }
예제 #6
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);
        }
        public void MatchesOnZippedPayload()
        {
            // ARRANGE
            var recordedRequest = new RecordedRequest
            {
                Url            = "http://fakeSite.fake",
                Method         = "POST",
                RequestPayload = new RecordedStream
                {
                    SerializedStream    = "Request 1",
                    IsGzippedCompressed = true
                },
                RequestHeaders = new RecordedHeaders
                {
                    { "Content-Type", new [] { "text/plain" } }
                },
                ResponseBody = "Response 1"
            };

            var recordingSession = new RecordingSession
            {
                RecordedRequests = new List <RecordedRequest> {
                    recordedRequest
                }
            };

            var requestBuilder = new RecordingSessionInterceptorRequestBuilder(recordingSession);

            IWebRequestCreate creator = new HttpWebRequestWrapperInterceptorCreator(requestBuilder);

            var request = creator.Create(new Uri(recordedRequest.Url));

            request.Method      = "POST";
            request.ContentType = "text/plain";

            using (var input = new MemoryStream(Encoding.UTF8.GetBytes(recordedRequest.RequestPayload.SerializedStream)))
                using (var compressed = new MemoryStream())
                    using (var zip = new GZipStream(compressed, CompressionMode.Compress, leaveOpen: true))
                    {
                        input.CopyTo(zip);
                        zip.Close();
                        compressed.Seek(0, SeekOrigin.Begin);
                        compressed.CopyTo(request.GetRequestStream());
                    }

            // ACT
            var response = request.GetResponse();

            // ASSERT
            response.ShouldNotBeNull();

            using (var sr = new StreamReader(response.GetResponseStream()))
                sr.ReadToEnd().ShouldEqual(recordedRequest.ResponseBody.SerializedStream);
        }
        public void CanSetRecordedRequestsToOnlyMatchOnce()
        {
            // ARRANGE
            var recordedRequest1 = new RecordedRequest
            {
                Url          = "http://fakeSite.fake/1",
                Method       = "GET",
                ResponseBody = "Response 1"
            };

            var recordedRequest2 = new RecordedRequest
            {
                Url          = "http://fakeSite.fake/2",
                Method       = recordedRequest1.Method,
                ResponseBody = "Response 2"
            };

            var requestBuilder = new RecordingSessionInterceptorRequestBuilder(
                new RecordingSession {
                RecordedRequests = { recordedRequest1, recordedRequest1, recordedRequest2 }
            })
            {
                AllowReplayingRecordedRequestsMultipleTimes = false
            };

            var creator = new HttpWebRequestWrapperInterceptorCreator(requestBuilder);

            // ACT
            var response1a = (HttpWebResponse)creator.Create(new Uri(recordedRequest1.Url)).GetResponse();
            var response1b = (HttpWebResponse)creator.Create(new Uri(recordedRequest1.Url)).GetResponse();
            var response1c = (HttpWebResponse)creator.Create(new Uri(recordedRequest1.Url)).GetResponse();
            var response2a = (HttpWebResponse)creator.Create(new Uri(recordedRequest2.Url)).GetResponse();
            var response2b = (HttpWebResponse)creator.Create(new Uri(recordedRequest2.Url)).GetResponse();

            // ASSERT
            response1a.ShouldNotBeNull();
            response1b.ShouldNotBeNull();
            response1c.ShouldNotBeNull();
            response2a.ShouldNotBeNull();
            response2b.ShouldNotBeNull();

            using (var sr = new StreamReader(response1a.GetResponseStream()))
                sr.ReadToEnd().ShouldEqual(recordedRequest1.ResponseBody.SerializedStream);

            using (var sr = new StreamReader(response1b.GetResponseStream()))
                sr.ReadToEnd().ShouldEqual(recordedRequest1.ResponseBody.SerializedStream);

            using (var sr = new StreamReader(response2a.GetResponseStream()))
                sr.ReadToEnd().ShouldEqual(recordedRequest2.ResponseBody.SerializedStream);

            response1c.StatusCode.ShouldEqual(HttpStatusCode.NotFound);
            response2b.StatusCode.ShouldEqual(HttpStatusCode.NotFound);
        }
        public void CanPlaybackFromMultipleRecordingSessions()
        {
            // ARRANGE
            var recordedRequest1 = new RecordedRequest
            {
                Url          = "http://fakeSite.fake/1",
                Method       = "GET",
                ResponseBody = "Response 1"
            };

            var recordedRequest2 = new RecordedRequest
            {
                Url          = "http://fakeSite.fake/2",
                Method       = recordedRequest1.Method,
                ResponseBody = "Response 2"
            };

            var recordingSession1 = new RecordingSession
            {
                RecordedRequests = new List <RecordedRequest> {
                    recordedRequest1
                }
            };

            var recordingSession2 = new RecordingSession
            {
                RecordedRequests = new List <RecordedRequest> {
                    recordedRequest2
                }
            };

            var requestBuilder = new RecordingSessionInterceptorRequestBuilder(recordingSession1, recordingSession2);

            IWebRequestCreate creator = new HttpWebRequestWrapperInterceptorCreator(requestBuilder);

            var request1 = creator.Create(new Uri(recordedRequest1.Url));
            var request2 = creator.Create(new Uri(recordedRequest2.Url));

            // ACT
            var response1 = request1.GetResponse();
            var response2 = request2.GetResponse();

            // ASSERT
            response1.ShouldNotBeNull();
            response2.ShouldNotBeNull();

            using (var sr = new StreamReader(response1.GetResponseStream()))
                sr.ReadToEnd().ShouldEqual(recordedRequest1.ResponseBody.SerializedStream);

            using (var sr = new StreamReader(response2.GetResponseStream()))
                sr.ReadToEnd().ShouldEqual(recordedRequest2.ResponseBody.SerializedStream);
        }
예제 #10
0
            /// <summary>
            /// Since these tests rely on live web requests - run as few
            /// as possible.  This makes the test a little harder to read
            /// but should improve build speed / consistency.
            /// </summary>
            public GitHubHomePageRequestFixture()
            {
                // necessary for requests to github to work
                ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;

                RequestBody = "Hello World";

                var requestUri    = new Uri("http://www.github.com");
                var requestCookie = new Cookie("test", "test")
                {
                    Domain = requestUri.Host
                };

                // first make a request using the real HttpWebRequest
                var realHttRequestCreator =
                    (IWebRequestCreate)
                    // use reflection in case HttpWebRequestWrapperSession has changed
                    // the PrefixList
                    Activator.CreateInstance(
                        typeof(HttpWebRequest).Assembly.GetType("System.Net.HttpRequestCreator"));

                RealRequest = (HttpWebRequest)realHttRequestCreator.Create(requestUri);
                RealRequest.CookieContainer = new CookieContainer();
                RealRequest.CookieContainer.Add(requestCookie);
                RealRequest.Method = "POST";
                using (var sw = new StreamWriter(RealRequest.GetRequestStream()))
                    sw.Write(RequestBody);

                RealResponse = (HttpWebResponse)RealRequest.GetResponse();

                using (var sr = new StreamReader(RealResponse.GetResponseStream()))
                    RealResponseBody = sr.ReadToEnd();


                // then make the same request using the recorder
                RecorderRequest = new HttpWebRequestWrapperRecorder(requestUri)
                {
                    CookieContainer = new CookieContainer()
                };
                RecorderRequest.CookieContainer.Add(requestCookie);
                RecorderRequest.Method = "POST";
                using (var sw = new StreamWriter(RecorderRequest.GetRequestStream()))
                    sw.Write(RequestBody);

                RecorderResponse = (HttpWebResponse)RecorderRequest.GetResponse();

                using (var sr = new StreamReader(RecorderResponse.GetResponseStream()))
                    RecorderResponseBody = sr.ReadToEnd();

                RecorderRecording = RecorderRequest.RecordedRequests.First();
            }
        public void BuilderSetsWebExceptionWithResponse()
        {
            // ARRANGE
            var recordedRequest = new RecordedRequest
            {
                Url               = "http://fakeSite.fake",
                Method            = "GET",
                ResponseException = new RecordedResponseException
                {
                    Message            = "Test Exception Message",
                    Type               = typeof(WebException),
                    WebExceptionStatus = WebExceptionStatus.ConnectionClosed
                },
                ResponseBody    = "Fake Error Response",
                ResponseHeaders = new RecordedHeaders {
                    { "header1", new [] { "value1" } }
                },
                ResponseStatusCode = HttpStatusCode.InternalServerError
            };

            var recordingSession = new RecordingSession {
                RecordedRequests = new List <RecordedRequest> {
                    recordedRequest
                }
            };

            var requestBuilder = new RecordingSessionInterceptorRequestBuilder(recordingSession);

            IWebRequestCreate creator = new HttpWebRequestWrapperInterceptorCreator(requestBuilder);

            var request = creator.Create(new Uri(recordedRequest.Url));

            // ACT
            var exception            = Record.Exception(() => request.GetResponse());
            var webException         = exception as WebException;
            var webExceptionResponse = webException.Response as HttpWebResponse;

            // ASSERT
            webException.ShouldNotBeNull();
            webException.Message.ShouldEqual(recordedRequest.ResponseException.Message);
            webException.Status.ShouldEqual(recordedRequest.ResponseException.WebExceptionStatus.Value);

            webExceptionResponse.ShouldNotBeNull();
            Assert.Equal(recordedRequest.ResponseHeaders, (RecordedHeaders)webExceptionResponse.Headers);
            webExceptionResponse.StatusCode.ShouldEqual(recordedRequest.ResponseStatusCode);
            webExceptionResponse.ContentLength.ShouldBeGreaterThan(0);

            using (var sr = new StreamReader(webExceptionResponse.GetResponseStream()))
                sr.ReadToEnd().ShouldEqual(recordedRequest.ResponseBody.SerializedStream);
        }
        public void BuilderAlwaysSetsWebExceptionResponseWhenStatusIsProtocolError()
        {
            // ARRANGE
            var recordedRequest = new RecordedRequest
            {
                Url               = "http://fakeSite.fake",
                Method            = "GET",
                ResponseException = new RecordedResponseException
                {
                    Message            = "Test Exception Message",
                    Type               = typeof(WebException),
                    WebExceptionStatus = WebExceptionStatus.ProtocolError
                },
                ResponseHeaders = new RecordedHeaders
                {
                    { "header1", new[] { "value1" } }
                },
                ResponseStatusCode = HttpStatusCode.Unauthorized
                                     //intentionally leave ResponseBody null
            };

            var recordingSession = new RecordingSession {
                RecordedRequests = new List <RecordedRequest> {
                    recordedRequest
                }
            };

            var requestBuilder = new RecordingSessionInterceptorRequestBuilder(recordingSession);

            IWebRequestCreate creator = new HttpWebRequestWrapperInterceptorCreator(requestBuilder);

            var request = creator.Create(new Uri(recordedRequest.Url));

            // ACT
            var exception            = Record.Exception(() => request.GetResponse());
            var webException         = exception as WebException;
            var webExceptionResponse = webException.Response as HttpWebResponse;

            // ASSERT
            webException.ShouldNotBeNull();
            webException.Message.ShouldEqual(recordedRequest.ResponseException.Message);
            webException.Status.ShouldEqual(recordedRequest.ResponseException.WebExceptionStatus.Value);

            webExceptionResponse.ShouldNotBeNull();
            Assert.Equal(recordedRequest.ResponseHeaders, (RecordedHeaders)webExceptionResponse.Headers);
            webExceptionResponse.StatusCode.ShouldEqual(recordedRequest.ResponseStatusCode);
            // no response content in recordedResponse, so content length should be 0
            webExceptionResponse.ContentLength.ShouldEqual(0);
        }
예제 #13
0
        private HttpWebResponse RecordRequestAndResponse(Func <HttpWebResponse> getResponse)
        {
            // record the request
            var recordedRequest = new RecordedRequest
            {
                Url    = RequestUri.ToString(),
                Method = Method,
                RequestCookieContainer = CookieContainer,
                RequestHeaders         = Headers,
                RequestPayload         =
                    null == _shadowCopyRequestStream
                    ? new RecordedStream()
                    : new RecordedStream(
                        _shadowCopyRequestStream.ShadowCopy.ToArray(),
                        this)
            };

            RecordedRequests.Add(recordedRequest);

            try
            {
                var response = getResponse();

                RecordResponse(response, recordedRequest);

                return(response);
            }
            catch (Exception e)
            {
                // record exception, exception's response and
                recordedRequest.ResponseException = new RecordedResponseException
                {
                    Message = e.Message,
                    Type    = e.GetType()
                };

                if (e is WebException webException)
                {
                    recordedRequest.ResponseException.WebExceptionStatus = webException.Status;

                    // if WebException - try and record the response
                    RecordResponse((HttpWebResponse)webException.Response, recordedRequest);
                }

                // re-throw
                throw;
            }
        }
예제 #14
0
        private void RecordResponse(HttpWebResponse response, RecordedRequest recordedRequest)
        {
            if (null == response)
            {
                // this can happen if we're coming from a WebException.Response
                return;
            }

            recordedRequest.ResponseHeaders    = response.Headers;
            recordedRequest.ResponseStatusCode = response.StatusCode;

            // copy the response stream
            try
            {
                var responseStream = response.GetResponseStream();

                if (null != responseStream)
                {
                    using (responseStream)
                    {
                        // copy the stream into a memory stream
                        // so we can read it and the caller can read it
                        var memoryStream = new MemoryStream();
                        CopyStream(responseStream, memoryStream);

                        // seek to beginning so we can read the memory stream
                        memoryStream.Seek(0, SeekOrigin.Begin);

                        recordedRequest.ResponseBody =
                            new RecordedStream(
                                memoryStream.ToArray(),
                                response);

                        // replace the default stream in response with the copy
                        ReflectionExtensions.SetField(response, "m_ConnectStream", memoryStream);
                    }
                }
            }
            catch (Exception e)
            {
                // suppress exception, but update history
                recordedRequest.ResponseBody = $"ERROR: {e.Message}\r\n{e.StackTrace}";
            }
        }
        public void CanSetOnMatchEventHandler()
        {
            var matchCallCount = 0;

            var requestUrl      = new Uri("http://fakeSite.fake/");
            var recordedRequest = new RecordedRequest
            {
                Url                = "http://fakeSite.fake/",
                Method             = "GET",
                ResponseStatusCode = HttpStatusCode.Found
            };

            var recordingSession = new RecordingSession {
                RecordedRequests = new List <RecordedRequest> {
                    recordedRequest
                }
            };

            var requestBuilder = new RecordingSessionInterceptorRequestBuilder(recordingSession)
            {
                OnMatch = (recordedReq, interceptedReq, httpWebResponse, exception) =>
                {
                    recordedReq.ShouldEqual(recordedRequest);
                    interceptedReq.HttpWebRequest.RequestUri.ShouldEqual(new Uri(recordedRequest.Url));
                    httpWebResponse.StatusCode.ShouldEqual(recordedRequest.ResponseStatusCode);

                    matchCallCount++;
                }
            };

            IWebRequestCreate creator = new HttpWebRequestWrapperInterceptorCreator(requestBuilder);

            var request = creator.Create(requestUrl);

            // ACT
            var response = request.GetResponse();

            // ASSERT
            response.ShouldNotBeNull();

            matchCallCount.ShouldEqual(1);
        }
        public void CanPlaybackDeflatedResponse()
        {
            // ARRANGE
            var recordedRequest = new RecordedRequest
            {
                Url          = "http://fakeSite.fake",
                Method       = "GET",
                ResponseBody = new RecordedStream
                {
                    SerializedStream    = "Response 1",
                    IsDeflateCompressed = true
                },
                ResponseHeaders = new RecordedHeaders
                {
                    { "Content-Encoding", new [] { "deflate" } }
                }
            };

            var recordingSession = new RecordingSession
            {
                RecordedRequests = new List <RecordedRequest> {
                    recordedRequest
                }
            };

            var requestBuilder = new RecordingSessionInterceptorRequestBuilder(recordingSession);

            IWebRequestCreate creator = new HttpWebRequestWrapperInterceptorCreator(requestBuilder);

            var request = (HttpWebRequest)creator.Create(new Uri(recordedRequest.Url));

            request.AutomaticDecompression = DecompressionMethods.Deflate;

            // ACT
            var response = request.GetResponse();

            // ASSERT
            response.ShouldNotBeNull();

            using (var sr = new StreamReader(response.GetResponseStream()))
                sr.ReadToEnd().ShouldEqual(recordedRequest.ResponseBody.SerializedStream);
        }
예제 #17
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));
        }
        public void BuilderSetsWebException()
        {
            // ARRANGE
            var recordedRequest = new RecordedRequest
            {
                Url               = "http://fakeSite.fake",
                Method            = "GET",
                ResponseException = new RecordedResponseException
                {
                    Message            = "Test Exception Message",
                    Type               = typeof(WebException),
                    WebExceptionStatus = WebExceptionStatus.ConnectionClosed
                }
            };

            var recordingSession = new RecordingSession {
                RecordedRequests = new List <RecordedRequest> {
                    recordedRequest
                }
            };

            var requestBuilder = new RecordingSessionInterceptorRequestBuilder(recordingSession);

            IWebRequestCreate creator = new HttpWebRequestWrapperInterceptorCreator(requestBuilder);

            var request = creator.Create(new Uri(recordedRequest.Url));

            // ACT
            var exception    = Record.Exception(() => request.GetResponse());
            var webException = exception as WebException;

            // ASSERT
            webException.ShouldNotBeNull();
            webException.Message.ShouldEqual(recordedRequest.ResponseException.Message);
            webException.Status.ShouldEqual(recordedRequest.ResponseException.WebExceptionStatus.Value);
            webException.Response.ShouldBeNull();
        }
        public void CanCustomizeMatchingAlgorithm()
        {
            // ARRANGE
            var requestUrl      = new Uri("http://fakeSite.fake/2");
            var recordedRequest = new RecordedRequest
            {
                // intentionally use a different url from requestUrl
                Url          = "http://fakeSite.fake/3",
                Method       = "GET",
                ResponseBody = "Custom Matching Algorithm"
            };

            var recordingSession = new RecordingSession {
                RecordedRequests = new List <RecordedRequest> {
                    recordedRequest
                }
            };

            var requestBuilder = new RecordingSessionInterceptorRequestBuilder(recordingSession)
            {
                MatchingAlgorithm = (interceptedReq, recordedReq) => interceptedReq.HttpWebRequest.RequestUri == requestUrl
            };

            IWebRequestCreate creator = new HttpWebRequestWrapperInterceptorCreator(requestBuilder);

            var request = creator.Create(requestUrl);

            // ACT
            var response = request.GetResponse();

            // ASSERT
            response.ShouldNotBeNull();

            using (var sr = new StreamReader(response.GetResponseStream()))
                sr.ReadToEnd().ShouldEqual(recordedRequest.ResponseBody.SerializedStream);
        }
        public async Task CanInterceptMultipleSequentialPosts()
        {
            // ARRANGE
            var numberOfSequentialRequests = 20;

            var recordedRequest = new RecordedRequest
            {
                Method         = "POST",
                Url            = "http://fakeSite.fake/",
                RequestPayload = new RecordedStream
                {
                    SerializedStream = "Test Request"
                },
                ResponseStatusCode = HttpStatusCode.OK,
                ResponseBody       = new RecordedStream
                {
                    SerializedStream = "Test Response",
                    // important - force gzip so a compression stream gets plumbed
                    // through the http client as that changes behavior
                    IsGzippedCompressed = true
                }
            };

            var requestBuilder = new RecordingSessionInterceptorRequestBuilder(
                new RecordingSession
            {
                RecordedRequests = new List <RecordedRequest> {
                    recordedRequest
                }
            })
            {
                MatchingAlgorithm = (intercepted, recorded) =>
                                    string.Equals(
                    intercepted.HttpWebRequest.RequestUri.ToString(),
                    recorded.Url,
                    StringComparison.OrdinalIgnoreCase)
            };

            // ACT
            using (new HttpWebRequestWrapperSession(new HttpWebRequestWrapperInterceptorCreator(requestBuilder)))
            {
                for (var i = 0; i < numberOfSequentialRequests; i++)
                {
                    var httpClient = new HttpClient(new WebRequestHandler());

                    var message = new HttpRequestMessage(HttpMethod.Post, recordedRequest.Url)
                    {
                        Content = new StringContent(recordedRequest.RequestPayload.ToString())
                    };

                    var response = await httpClient.SendAsync(message);

                    // decompress stream
                    var responseStream = await response.Content.ReadAsStreamAsync();

                    using (var zip = new GZipStream(responseStream, CompressionMode.Decompress, leaveOpen: true))
                        using (var sr = new StreamReader(zip))
                            //using (var sr = new StreamReader(responseStream))
                            sr.ReadToEnd().ShouldEqual(recordedRequest.ResponseBody.ToString());

                    Console.WriteLine("Completed " + i);
                }
            }

            // ASSERT

            // if we didn't timeout, then we're good
        }
        /// <summary>
        /// Examines <paramref name="request"/> and if <see cref="RecordedRequest.ResponseException"/>
        /// is populated, creates a new strongly typed exception based on the data in <paramref name="request"/>
        /// and sets <paramref name="recordedException"/>.
        /// <para />
        /// If <see cref="RecordedRequest.ResponseException"/> is null, then <paramref name="recordedException"/>
        /// is set to null and this returns <c>false</c>.
        /// <para />
        /// This method can activate any exception type as long as it has a constructor that takes a single
        /// string parameter.
        /// <para />
        /// However, there is special handling for <see cref="WebException"/>s.  If <see cref="RecordedRequest.ResponseBody"/>
        /// and the other Response properties are set, then this data will be used to set <see cref="WebException.Response"/>.
        /// </summary>
        /// <returns>
        /// <c>true</c> if <paramref name="request"/> has a <see cref="RecordedRequest.ResponseException"/>,
        /// indicating <paramref name="recordedException"/> has been populated.  <c>false</c> otherwise.
        /// </returns>
        public static bool TryGetResponseException(this RecordedRequest request, out Exception recordedException)
        {
            recordedException = null;

            if (request?.ResponseException == null)
            {
                return(false);
            }

            if (request.ResponseException.Type != typeof(WebException))
            {
                // use reflection to create the exception.  really
                // hope whatever it is, the exception has a Exception(string message)
                // constructor, other we are in trouble.  However, all of the documented
                // exceptions that HttpWebRequest.GetResponse() can throw do, so we should be ok
                recordedException =
                    (Exception)
                    Activator.CreateInstance(
                        request.ResponseException.Type,
                        args: request.ResponseException.Message);

                return(true);
            }

            // if we're here - we're building a WebException

            if (null == request.ResponseException.WebExceptionStatus)
            {
                recordedException = new WebException(request.ResponseException.Message);
                return(true);
            }

            // can we return a WebException without a Response?
            if (string.IsNullOrEmpty(request?.ResponseBody?.SerializedStream) &&
                // always need to return a response if WebExceptionStatus is ProtocolError
                //https://msdn.microsoft.com/en-us/library/system.net.webexception.response(v=vs.110).aspx
                request.ResponseException.WebExceptionStatus != WebExceptionStatus.ProtocolError)
            {
                recordedException = new WebException(
                    request.ResponseException.Message,
                    request.ResponseException.WebExceptionStatus.Value);

                return(true);
            }

            // if we have a response body, then we need to build a complicated Web Exception

            recordedException =
                new WebException(
                    request.ResponseException.Message,
                    innerException: null,
                    status: request.ResponseException.WebExceptionStatus.Value,
                    response: HttpWebResponseCreator.Create(
                        new Uri(request.Url),
                        request.Method,
                        request.ResponseStatusCode,
                        request.ResponseBody?.ToStream() ?? new MemoryStream(),
                        request.ResponseHeaders));

            return(true);
        }
        public void MatchesOnUniqueRequestHeaders()
        {
            // ARRANGE
            var recordedRequest1 = new RecordedRequest
            {
                Url            = "http://fakeSite.fake",
                Method         = "GET",
                RequestHeaders = new RecordedHeaders {
                    { "Request1", new [] { "Request1Value" } }
                },
                ResponseBody = "Response 1"
            };

            var recordedRequest2 = new RecordedRequest
            {
                Url            = recordedRequest1.Url,
                Method         = recordedRequest1.Method,
                RequestHeaders = new RecordedHeaders {
                    { "Request2", new [] { "Request2Value" } }
                },
                ResponseBody = "Response 2"
            };

            var recordingSession = new RecordingSession
            {
                RecordedRequests = new List <RecordedRequest> {
                    recordedRequest1, recordedRequest2
                }
            };

            var requestBuilder = new RecordingSessionInterceptorRequestBuilder(recordingSession);

            IWebRequestCreate creator = new HttpWebRequestWrapperInterceptorCreator(requestBuilder);

            var request1 = creator.Create(new Uri(recordedRequest1.Url));

            request1.Headers = new WebHeaderCollection {
                recordedRequest1.RequestHeaders
            };

            var request2 = creator.Create(new Uri(recordedRequest2.Url));

            request2.Headers = new WebHeaderCollection {
                recordedRequest2.RequestHeaders
            };


            // ACT
            var response1 = request1.GetResponse();
            var response2 = request2.GetResponse();

            // ASSERT
            response1.ShouldNotBeNull();
            response2.ShouldNotBeNull();

            using (var sr = new StreamReader(response1.GetResponseStream()))
                sr.ReadToEnd().ShouldEqual(recordedRequest1.ResponseBody.SerializedStream);

            using (var sr = new StreamReader(response2.GetResponseStream()))
                sr.ReadToEnd().ShouldEqual(recordedRequest2.ResponseBody.SerializedStream);
        }
        public void MatchesOnUniquePayload()
        {
            // ARRANGE
            var recordedRequest1 = new RecordedRequest
            {
                Url            = "http://fakeSite.fake",
                Method         = "POST",
                RequestPayload = "Request 1",
                RequestHeaders = new RecordedHeaders
                {
                    { "Content-Type", new [] { "text/plain" } }
                },
                ResponseBody = "Response 1"
            };

            var recordedRequest2 = new RecordedRequest
            {
                Url            = recordedRequest1.Url,
                Method         = recordedRequest1.Method,
                RequestPayload = "Request 2",
                RequestHeaders = recordedRequest1.RequestHeaders,
                ResponseBody   = "Response 2"
            };

            var recordingSession = new RecordingSession
            {
                RecordedRequests = new List <RecordedRequest> {
                    recordedRequest1, recordedRequest2
                }
            };

            var requestBuilder = new RecordingSessionInterceptorRequestBuilder(recordingSession);

            IWebRequestCreate creator = new HttpWebRequestWrapperInterceptorCreator(requestBuilder);

            var request1 = creator.Create(new Uri(recordedRequest1.Url));

            request1.Method      = "POST";
            request1.ContentType = "text/plain";

            recordedRequest1.RequestPayload.ToStream().CopyTo(request1.GetRequestStream());

            var request2 = creator.Create(new Uri(recordedRequest2.Url));

            request2.Method      = "POST";
            request2.ContentType = "text/plain";

            recordedRequest2.RequestPayload.ToStream().CopyTo(request2.GetRequestStream());

            // ACT
            var response1 = request1.GetResponse();
            var response2 = request2.GetResponse();

            // ASSERT
            response1.ShouldNotBeNull();
            response2.ShouldNotBeNull();

            using (var sr = new StreamReader(response1.GetResponseStream()))
                sr.ReadToEnd().ShouldEqual(recordedRequest1.ResponseBody.SerializedStream);

            using (var sr = new StreamReader(response2.GetResponseStream()))
                sr.ReadToEnd().ShouldEqual(recordedRequest2.ResponseBody.SerializedStream);
        }