Example #1
0
        public async Task SettingHeaderOverridesDefaultContentLength()
        {
            long contentLength = 0;
            var  mockHandler   = new MockHttpClientHandler(
                httpRequestMessage => contentLength = httpRequestMessage.Content.Headers.ContentLength.Value);

            var transport = new HttpClientTransport(new HttpClient(mockHandler));
            var request   = transport.CreateRequest(null);

            request.SetRequestLine(HttpPipelineMethod.Get, new Uri("http://example.com"));
            request.Content = HttpPipelineRequestContent.Create(new byte[10]);
            request.Headers.Add("Content-Length", "50");

            await ExecuteRequest(request, transport);

            Assert.AreEqual(50, contentLength);
        }
Example #2
0
        public async Task ContentLengthIsSetForArrayContent(HttpPipelineRequestContent content, int expectedLength)
        {
            long contentLength = 0;
            var  mockHandler   = new MockHttpClientHandler(
                httpRequestMessage => contentLength = httpRequestMessage.Content.Headers.ContentLength.Value
                );

            var transport = new HttpClientTransport(new HttpClient(mockHandler));
            var request   = transport.CreateRequest(null);

            request.SetRequestLine(HttpPipelineMethod.Get, new Uri("http://example.com"));
            request.Content = content;

            await ExecuteRequest(request, transport);

            Assert.AreEqual(expectedLength, contentLength);
        }
Example #3
0
        public async Task <Response <ConfigurationSetting> > UpdateAsync(ConfigurationSetting setting, CancellationToken cancellation = default)
        {
            if (setting == null)
            {
                throw new ArgumentNullException(nameof(setting));
            }
            if (string.IsNullOrEmpty(setting.Key))
            {
                throw new ArgumentNullException($"{nameof(setting)}.{nameof(setting.Key)}");
            }

            Uri uri = BuildUriForKvRoute(setting);

            using (var request = _pipeline.CreateRequest())
            {
                ReadOnlyMemory <byte> content = Serialize(setting);

                request.SetRequestLine(HttpVerb.Put, uri);

                request.AddHeader(MediaTypeKeyValueApplicationHeader);
                request.AddHeader(HttpHeader.Common.JsonContentType);

                if (setting.ETag != default)
                {
                    request.AddHeader(IfMatchName, $"\"{setting.ETag}\"");
                }
                else
                {
                    request.AddHeader(IfMatchName, "*");
                }

                request.Content = HttpPipelineRequestContent.Create(content);

                var response = await _pipeline.SendRequestAsync(request, cancellation).ConfigureAwait(false);

                if (response.Status == 200)
                {
                    return(await CreateResponse(response, cancellation));
                }
                else
                {
                    throw new RequestFailedException(response);
                }
            }
        }
Example #4
0
        public virtual async Task <Response <ConfigurationSetting> > SetAsync(ConfigurationSetting setting, CancellationToken cancellation = default)
        {
            if (setting == null)
            {
                throw new ArgumentNullException(nameof(setting));
            }
            if (string.IsNullOrEmpty(setting.Key))
            {
                throw new ArgumentNullException($"{nameof(setting)}.{nameof(setting.Key)}");
            }

            using (var request = _pipeline.CreateRequest())
            {
                ReadOnlyMemory <byte> content = Serialize(setting);

                request.Method = HttpPipelineMethod.Put;
                BuildUriForKvRoute(request.UriBuilder, setting);
                request.Headers.Add(MediaTypeKeyValueApplicationHeader);
                request.Headers.Add(HttpHeader.Common.JsonContentType);

                if (setting.ETag != default)
                {
                    request.Headers.Add(IfMatchName, $"\"{setting.ETag.ToString()}\"");
                }

                request.Content = HttpPipelineRequestContent.Create(content);

                var response = await _pipeline.SendRequestAsync(request, cancellation).ConfigureAwait(false);

                if (response.Status == 200)
                {
                    return(await CreateResponse(response, cancellation));
                }
                if (response.Status == 409)
                {
                    throw new RequestFailedException(response, "the item is locked");
                }
                else
                {
                    throw new RequestFailedException(response);
                }
            }
        }
Example #5
0
        public async Task HeadersAndQueryParametersAreNotSanitizedWhenStars()
        {
            var response = new MockResponse(200);

            response.SetContent(new byte[] { 6, 7, 8, 9, 0 });
            response.AddHeader(new HttpHeader("Custom-Response-Header", "Improved value"));
            response.AddHeader(new HttpHeader("Secret-Response-Header", "Very secret"));

            MockTransport mockTransport = CreateMockTransport(response);

            var    pipeline  = new HttpPipeline(mockTransport, new[] { new LoggingPolicy(logContent: false, int.MaxValue, new[] { "*" }, new[] { "*" }) });
            string requestId = null;

            await SendRequestAsync(pipeline, request =>
            {
                request.Method = RequestMethod.Get;
                request.Uri.Reset(new Uri("https://contoso.a.io?api-version=5&secret=123"));
                request.Headers.Add("Date", "3/26/2019");
                request.Headers.Add("Custom-Header", "Value");
                request.Headers.Add("Secret-Custom-Header", "Value");
                request.Content = HttpPipelineRequestContent.Create(new byte[] { 1, 2, 3, 4, 5 });
                requestId       = request.ClientRequestId;
            });

            EventWrittenEventArgs e = _listener.SingleEventById(RequestEvent);

            Assert.AreEqual(EventLevel.Informational, e.Level);
            Assert.AreEqual("Request", e.EventName);
            Assert.AreEqual(requestId, e.GetProperty <string>("requestId"));
            Assert.AreEqual("https://contoso.a.io/?api-version=5&secret=123", e.GetProperty <string>("uri"));
            Assert.AreEqual("GET", e.GetProperty <string>("method"));
            StringAssert.Contains($"Date:3/26/2019{Environment.NewLine}", e.GetProperty <string>("headers"));
            StringAssert.Contains($"Custom-Header:Value{Environment.NewLine}", e.GetProperty <string>("headers"));
            StringAssert.Contains($"Secret-Custom-Header:Value{Environment.NewLine}", e.GetProperty <string>("headers"));

            e = _listener.SingleEventById(ResponseEvent);
            Assert.AreEqual(EventLevel.Informational, e.Level);
            Assert.AreEqual("Response", e.EventName);
            Assert.AreEqual(requestId, e.GetProperty <string>("requestId"));
            Assert.AreEqual(e.GetProperty <int>("status"), 200);
            StringAssert.Contains($"Custom-Response-Header:Improved value{Environment.NewLine}", e.GetProperty <string>("headers"));
            StringAssert.Contains($"Secret-Response-Header:Very secret{Environment.NewLine}", e.GetProperty <string>("headers"));
        }
Example #6
0
        public async Task RequestContentIsNotLoggedWhenDisabled()
        {
            var response = new MockResponse(500);

            response.ContentStream = new MemoryStream(new byte[] { 1, 2, 3 });

            MockTransport mockTransport = CreateMockTransport(response);

            var pipeline = new HttpPipeline(mockTransport, new[] { new LoggingPolicy(logContent: false, int.MaxValue, s_allowedHeaders, s_allowedQueryParameters) });

            await SendRequestAsync(pipeline, request =>
            {
                request.Method = RequestMethod.Get;
                request.Uri.Reset(new Uri("https://contoso.a.io"));
                request.Content = HttpPipelineRequestContent.Create(Encoding.UTF8.GetBytes("Hello world"));
            });

            AssertNoContentLogged();
        }
Example #7
0
        public async Task RequestContentIsNotLoggedWhenDisabled()
        {
            var response = new MockResponse(500);

            response.ContentStream = new MemoryStream(new byte[] { 1, 2, 3 });

            MockTransport mockTransport = CreateMockTransport(response);

            var pipeline = new HttpPipeline(mockTransport, new[] { new LoggingPolicy(logContent: false) });

            using (Request request = pipeline.CreateRequest())
            {
                request.SetRequestLine(RequestMethod.Get, new Uri("https://contoso.a.io"));
                request.Content = HttpPipelineRequestContent.Create(Encoding.UTF8.GetBytes("Hello world"));

                await SendRequestAsync(pipeline, request);
            }

            AssertNoContentLogged();
        }
Example #8
0
        public async Task CanGetAndSetContent()
        {
            byte[] requestBytes = null;
            var    mockHandler  = new MockHttpClientHandler(
                async httpRequestMessage => {
                requestBytes = await httpRequestMessage.Content.ReadAsByteArrayAsync();
            });

            var bytes     = Encoding.ASCII.GetBytes("Hello world");
            var content   = HttpPipelineRequestContent.Create(bytes);
            var transport = new HttpClientTransport(new HttpClient(mockHandler));
            var request   = transport.CreateRequest(null);

            request.SetRequestLine(HttpPipelineMethod.Get, new Uri("http://example.com:340"));
            request.Content = content;

            Assert.AreEqual(content, request.Content);

            await ExecuteRequest(request, transport);

            CollectionAssert.AreEqual(bytes, requestBytes);
        }
        public async Task StreamRequestContentCanBeSentMultipleTimes()
        {
            var requests            = new List <HttpRequestMessage>();
            var httpResponseMessage = new HttpResponseMessage(HttpStatusCode.OK);

            var mockHandler = new MockHttpClientHandler(httpRequestMessage =>
            {
                requests.Add(httpRequestMessage);
                return(Task.FromResult(httpResponseMessage));
            });

            var     transport = new HttpClientTransport(new HttpClient(mockHandler));
            Request request   = transport.CreateRequest();

            request.Content = HttpPipelineRequestContent.Create(new MemoryStream(new byte[] { 1, 2, 3 }));
            request.SetRequestLine(RequestMethod.Get, new Uri("http://example.com:340"));

            await ExecuteRequest(request, transport);
            await ExecuteRequest(request, transport);

            Assert.AreEqual(2, requests.Count);
        }
Example #10
0
        private Request CreateClientSecretAuthRequest(string tenantId, string clientId, string clientSecret, string[] scopes)
        {
            Request request = _pipeline.CreateRequest();

            request.Method = RequestMethod.Post;

            request.Headers.Add(HttpHeader.Common.FormUrlEncodedContentType);

            request.UriBuilder.Uri = _options.AuthorityHost;

            request.UriBuilder.AppendPath(tenantId);

            request.UriBuilder.AppendPath("/oauth2/v2.0/token");

            var bodyStr = $"response_type=token&grant_type=client_credentials&client_id={Uri.EscapeDataString(clientId)}&client_secret={Uri.EscapeDataString(clientSecret)}&scope={Uri.EscapeDataString(string.Join(" ", scopes))}";

            ReadOnlyMemory <byte> content = Encoding.UTF8.GetBytes(bodyStr).AsMemory();

            request.Content = HttpPipelineRequestContent.Create(content);

            return(request);
        }
        public async Task GettingErrorRequestProducesEvents()
        {
            var response = new MockResponse(500);

            response.SetContent(new byte[] { 6, 7, 8, 9, 0 });
            response.AddHeader(new HttpHeader("Custom-Response-Header", "Improved value"));

            MockTransport mockTransport = CreateMockTransport(response);

            var    pipeline = new HttpPipeline(mockTransport, new[] { new LoggingPolicy(logContent: true, int.MaxValue) });
            string requestId;

            using (Request request = pipeline.CreateRequest())
            {
                request.Method = RequestMethod.Get;
                request.Uri.Assign(new Uri("https://contoso.a.io"));
                request.Headers.Add("Date", "3/26/2019");
                request.Headers.Add("Custom-Header", "Value");
                request.Content = HttpPipelineRequestContent.Create(new byte[] { 1, 2, 3, 4, 5 });
                requestId       = request.ClientRequestId;

                await SendRequestAsync(pipeline, request);
            }

            EventWrittenEventArgs e = _listener.SingleEventById(ErrorResponseEvent);

            Assert.AreEqual(EventLevel.Error, e.Level);
            Assert.AreEqual("ErrorResponse", e.EventName);
            Assert.AreEqual(requestId, e.GetProperty <string>("requestId"));
            Assert.AreEqual(e.GetProperty <int>("status"), 500);
            StringAssert.Contains($"Custom-Response-Header:Improved value{Environment.NewLine}", e.GetProperty <string>("headers"));

            e = _listener.SingleEventById(ErrorResponseContentEvent);
            Assert.AreEqual(EventLevel.Informational, e.Level);
            Assert.AreEqual("ErrorResponseContent", e.EventName);
            Assert.AreEqual(requestId, e.GetProperty <string>("requestId"));
            CollectionAssert.AreEqual(new byte[] { 6, 7, 8, 9, 0 }, e.GetProperty <byte[]>("content"));
        }
        public async Task ContentIsNotLoggedAsTextWhenDisabled()
        {
            var response = new MockResponse(500);

            response.ContentStream = new MemoryStream(new byte[] { 1, 2, 3 });
            response.AddHeader(new HttpHeader("Content-Type", "text/json"));

            MockTransport mockTransport = CreateMockTransport(response);

            var pipeline = new HttpPipeline(mockTransport, new[] { new LoggingPolicy(logContent: false, int.MaxValue) });

            using (Request request = pipeline.CreateRequest())
            {
                request.Method = RequestMethod.Get;
                request.Uri.Assign(new Uri("https://contoso.a.io"));
                request.Content = HttpPipelineRequestContent.Create(Encoding.UTF8.GetBytes("Hello world"));
                request.Headers.Add("Content-Type", "text/json");

                await SendRequestAsync(pipeline, request);
            }

            AssertNoContentLogged();
        }
        public void StreamCopyTo()
        {
            int size             = 100;
            var sourceArray      = new byte[size];
            var destinationArray = new byte[size * 2];

            new Random(100).NextBytes(sourceArray);

            var source      = new MemoryStream(sourceArray);
            var destination = new MemoryStream(destinationArray);
            var content     = HttpPipelineRequestContent.Create(source);

            content.WriteTo(destination, default);

            for (int i = 0; i < size; i++)
            {
                Assert.AreEqual(sourceArray[i], destinationArray[i]);
            }
            for (int i = size; i < destinationArray.Length; i++)
            {
                Assert.AreEqual(0, destinationArray[i]);
            }
        }
Example #14
0
        private Request CreateClientSecretAuthRequest(string tenantId, string clientId, string clientSecret, string[] scopes)
        {
            Request request = _pipeline.CreateRequest();

            request.Method = HttpPipelineMethod.Post;

            request.UriBuilder.Uri = _options.AuthorityHost;

            request.UriBuilder.AppendPath(tenantId);

            request.UriBuilder.AppendPath("/oauth2/v2.0/token");

            ReadOnlyMemory <byte> content = Serialize(
                ("response_type", "token"),
                ("grant_type", "client_credentials"),
                ("client_id", clientId),
                ("client_secret", clientSecret),
                ("scopes", string.Join(" ", scopes)));

            request.Content = HttpPipelineRequestContent.Create(content);

            return(request);
        }
Example #15
0
        private Request CreateClientCertificateAuthRequest(string tenantId, string clientId, X509Certificate2 clientCertficate, string[] scopes)
        {
            Request request = _pipeline.CreateRequest();

            request.Method = RequestMethod.Post;

            request.Headers.Add(HttpHeader.Common.FormUrlEncodedContentType);

            request.Uri.Reset(_options.AuthorityHost);

            request.Uri.AppendPath(tenantId);

            request.Uri.AppendPath("/oauth2/v2.0/token");

            string clientAssertion = CreateClientAssertionJWT(clientId, request.Uri.ToString(), clientCertficate);

            var bodyStr = $"response_type=token&grant_type=client_credentials&client_id={Uri.EscapeDataString(clientId)}&client_assertion_type={Uri.EscapeDataString(ClientAssertionType)}&client_assertion={Uri.EscapeDataString(clientAssertion)}&scope={Uri.EscapeDataString(string.Join(" ", scopes))}";

            ReadOnlyMemory <byte> content = Encoding.UTF8.GetBytes(bodyStr).AsMemory();

            request.Content = HttpPipelineRequestContent.Create(content);

            return(request);
        }
        public async Task SendingRequestProducesEvents()
        {
            var handler = new MockHttpClientHandler(httpRequestMessage => {
                var response     = new HttpResponseMessage((HttpStatusCode)500);
                response.Content = new ByteArrayContent(new byte[] { 6, 7, 8, 9, 0 });
                response.Headers.Add("Custom-Response-Header", "Improved value");
                return(Task.FromResult(response));
            });
            var transport = new HttpClientTransport(new HttpClient(handler));
            var options   = new HttpPipelineOptions(transport)
            {
                LoggingPolicy = LoggingPolicy.Shared
            };

            var    pipeline = options.Build("test", "1.0.0");
            string requestId;

            using (var request = pipeline.CreateRequest())
            {
                request.SetRequestLine(HttpVerb.Get, new Uri("https://contoso.a.io"));
                request.AddHeader("Date", "3/26/2019");
                request.AddHeader("Custom-Header", "Value");
                request.Content = HttpPipelineRequestContent.Create(new byte[] { 1, 2, 3, 4, 5 });
                requestId       = request.RequestId;

                var response = await pipeline.SendRequestAsync(request, CancellationToken.None);

                Assert.AreEqual(500, response.Status);
            }

            Assert.True(_listener.EventData.Any(e =>
                                                e.EventId == 1 &&
                                                e.Level == EventLevel.Informational &&
                                                e.EventName == "Request" &&
                                                GetStringProperty(e, "requestId").Equals(requestId) &&
                                                GetStringProperty(e, "uri").Equals("https://contoso.a.io/") &&
                                                GetStringProperty(e, "method").Equals("GET") &&
                                                GetStringProperty(e, "headers").Contains($"Date:3/26/2019{Environment.NewLine}") &&
                                                GetStringProperty(e, "headers").Contains($"Custom-Header:Value{Environment.NewLine}")
                                                ));

            Assert.True(_listener.EventData.Any(e =>
                                                e.EventId == 2 &&
                                                e.Level == EventLevel.Verbose &&
                                                e.EventName == "RequestContent" &&
                                                GetStringProperty(e, "requestId").Equals(requestId) &&
                                                ((byte[])GetProperty(e, "content")).SequenceEqual(new byte[] { 1, 2, 3, 4, 5 }))
                        );

            Assert.True(_listener.EventData.Any(e =>
                                                e.EventId == 5 &&
                                                e.Level == EventLevel.Informational &&
                                                e.EventName == "Response" &&
                                                GetStringProperty(e, "requestId").Equals(requestId) &&
                                                (int)GetProperty(e, "status") == 500 &&
                                                GetStringProperty(e, "headers").Contains($"Custom-Response-Header:Improved value{Environment.NewLine}")
                                                ));

            Assert.True(_listener.EventData.Any(e =>
                                                e.EventId == 6 &&
                                                e.Level == EventLevel.Verbose &&
                                                e.EventName == "ResponseContent" &&
                                                GetStringProperty(e, "requestId").Equals(requestId) &&
                                                ((byte[])GetProperty(e, "content")).SequenceEqual(new byte[] { 6, 7, 8, 9, 0 }))
                        );

            Assert.True(_listener.EventData.Any(e =>
                                                e.EventId == 8 &&
                                                e.Level == EventLevel.Error &&
                                                e.EventName == "ErrorResponse" &&
                                                GetStringProperty(e, "requestId").Equals(requestId) &&
                                                (int)GetProperty(e, "status") == 500 &&
                                                GetStringProperty(e, "headers").Contains($"Custom-Response-Header:Improved value{Environment.NewLine}")
                                                ));

            Assert.True(_listener.EventData.Any(e =>
                                                e.EventId == 9 &&
                                                e.Level == EventLevel.Informational &&
                                                e.EventName == "ErrorResponseContent" &&
                                                GetStringProperty(e, "requestId").Equals(requestId) &&
                                                ((byte[])GetProperty(e, "content")).SequenceEqual(new byte[] { 6, 7, 8, 9, 0 }))
                        );
        }
        public async Task SendingRequestProducesEvents()
        {
            var response = new MockResponse(500);

            response.SetContent(new byte[] { 6, 7, 8, 9, 0 });
            response.AddHeader(new HttpHeader("Custom-Response-Header", "Improved value"));

            var mockTransport = new MockTransport(response);

            var    pipeline = new HttpPipeline(mockTransport, new [] { LoggingPolicy.Shared });
            string requestId;

            using (HttpPipelineRequest request = pipeline.CreateRequest())
            {
                request.SetRequestLine(HttpPipelineMethod.Get, new Uri("https://contoso.a.io"));
                request.AddHeader("Date", "3/26/2019");
                request.AddHeader("Custom-Header", "Value");
                request.Content = HttpPipelineRequestContent.Create(new byte[] { 1, 2, 3, 4, 5 });
                requestId       = request.RequestId;

                await pipeline.SendRequestAsync(request, CancellationToken.None);
            }

            var e = _listener.SingleEventById(RequestEvent);

            Assert.AreEqual(EventLevel.Informational, e.Level);
            Assert.AreEqual("Request", e.EventName);
            Assert.AreEqual(requestId, e.GetProperty <string>("requestId"));
            Assert.AreEqual("https://contoso.a.io/", e.GetProperty <string>("uri"));
            Assert.AreEqual("GET", e.GetProperty <string>("method"));
            StringAssert.Contains($"Date:3/26/2019{Environment.NewLine}", e.GetProperty <string>("headers"));
            StringAssert.Contains($"Custom-Header:Value{Environment.NewLine}", e.GetProperty <string>("headers"));

            e = _listener.SingleEventById(RequestContentEvent);
            Assert.AreEqual(EventLevel.Verbose, e.Level);
            Assert.AreEqual("RequestContent", e.EventName);
            Assert.AreEqual(requestId, e.GetProperty <string>("requestId"));
            CollectionAssert.AreEqual(new byte[] { 1, 2, 3, 4, 5 }, e.GetProperty <byte[]>("content"));

            e = _listener.SingleEventById(ResponseEvent);
            Assert.AreEqual(EventLevel.Informational, e.Level);
            Assert.AreEqual("Response", e.EventName);
            Assert.AreEqual(requestId, e.GetProperty <string>("requestId"));
            Assert.AreEqual(e.GetProperty <int>("status"), 500);
            StringAssert.Contains($"Custom-Response-Header:Improved value{Environment.NewLine}", e.GetProperty <string>("headers"));

            e = _listener.SingleEventById(ResponseContentEvent);
            Assert.AreEqual(EventLevel.Verbose, e.Level);
            Assert.AreEqual("ResponseContent", e.EventName);
            Assert.AreEqual(requestId, e.GetProperty <string>("requestId"));
            CollectionAssert.AreEqual(new byte[] { 6, 7, 8, 9, 0 }, e.GetProperty <byte[]>("content"));

            e = _listener.SingleEventById(ErrorResponseEvent);
            Assert.AreEqual(EventLevel.Error, e.Level);
            Assert.AreEqual("ErrorResponse", e.EventName);
            Assert.AreEqual(requestId, e.GetProperty <string>("requestId"));
            Assert.AreEqual(e.GetProperty <int>("status"), 500);
            StringAssert.Contains($"Custom-Response-Header:Improved value{Environment.NewLine}", e.GetProperty <string>("headers"));

            e = _listener.SingleEventById(ErrorResponseContentEvent);
            Assert.AreEqual(EventLevel.Informational, e.Level);
            Assert.AreEqual("ErrorResponseContent", e.EventName);
            Assert.AreEqual(requestId, e.GetProperty <string>("requestId"));
            CollectionAssert.AreEqual(new byte[] { 6, 7, 8, 9, 0 }, e.GetProperty <byte[]>("content"));
        }
        public async Task SendingRequestProducesEvents()
        {
            var handler = new MockHttpClientHandler(httpRequestMessage =>
            {
                var response     = new HttpResponseMessage((HttpStatusCode)500);
                response.Content = new ByteArrayContent(new byte[] { 6, 7, 8, 9, 0 });
                response.Headers.Add("Custom-Response-Header", "Improved value");
                return(Task.FromResult(response));
            });
            var    transport = new HttpClientTransport(new HttpClient(handler));
            var    pipeline  = new HttpPipeline(transport, new [] { LoggingPolicy.Shared });
            string requestId;

            using (var request = pipeline.CreateRequest())
            {
                request.SetRequestLine(HttpPipelineMethod.Get, new Uri("https://contoso.a.io"));
                request.AddHeader("Date", "3/26/2019");
                request.AddHeader("Custom-Header", "Value");
                request.Content = HttpPipelineRequestContent.Create(new byte[] { 1, 2, 3, 4, 5 });
                requestId       = request.RequestId;

                var response = await pipeline.SendRequestAsync(request, CancellationToken.None);

                Assert.AreEqual(500, response.Status);
            }

            var e = _listener.SingleEventById(1);

            Assert.AreEqual(EventLevel.Informational, e.Level);
            Assert.AreEqual("Request", e.EventName);
            Assert.AreEqual(requestId, e.GetProperty <string>("requestId"));
            Assert.AreEqual("https://contoso.a.io/", e.GetProperty <string>("uri"));
            Assert.AreEqual("GET", e.GetProperty <string>("method"));
            StringAssert.Contains($"Date:3/26/2019{Environment.NewLine}", e.GetProperty <string>("headers"));
            StringAssert.Contains($"Custom-Header:Value{Environment.NewLine}", e.GetProperty <string>("headers"));

            e = _listener.SingleEventById(2);
            Assert.AreEqual(EventLevel.Verbose, e.Level);
            Assert.AreEqual("RequestContent", e.EventName);
            Assert.AreEqual(requestId, e.GetProperty <string>("requestId"));
            CollectionAssert.AreEqual(new byte[] { 1, 2, 3, 4, 5 }, e.GetProperty <byte[]>("content"));

            e = _listener.SingleEventById(5);
            Assert.AreEqual(EventLevel.Informational, e.Level);
            Assert.AreEqual("Response", e.EventName);
            Assert.AreEqual(requestId, e.GetProperty <string>("requestId"));
            Assert.AreEqual(e.GetProperty <int>("status"), 500);
            StringAssert.Contains($"Custom-Response-Header:Improved value{Environment.NewLine}", e.GetProperty <string>("headers"));

            e = _listener.SingleEventById(6);
            Assert.AreEqual(EventLevel.Verbose, e.Level);
            Assert.AreEqual("ResponseContent", e.EventName);
            Assert.AreEqual(requestId, e.GetProperty <string>("requestId"));
            CollectionAssert.AreEqual(new byte[] { 6, 7, 8, 9, 0 }, e.GetProperty <byte[]>("content"));

            e = _listener.SingleEventById(8);
            Assert.AreEqual(EventLevel.Error, e.Level);
            Assert.AreEqual("ErrorResponse", e.EventName);
            Assert.AreEqual(requestId, e.GetProperty <string>("requestId"));
            Assert.AreEqual(e.GetProperty <int>("status"), 500);
            StringAssert.Contains($"Custom-Response-Header:Improved value{Environment.NewLine}", e.GetProperty <string>("headers"));

            e = _listener.SingleEventById(9);
            Assert.AreEqual(EventLevel.Informational, e.Level);
            Assert.AreEqual("ErrorResponseContent", e.EventName);
            Assert.AreEqual(requestId, e.GetProperty <string>("requestId"));
            CollectionAssert.AreEqual(new byte[] { 6, 7, 8, 9, 0 }, e.GetProperty <byte[]>("content"));
        }