Exemplo n.º 1
0
        public async Task TcpClient_Should_Be_Derivable()
        {
            var tcpClient = new TestTcpClient(_tcpClientChannelFactory, _logger, _eventLoopGroupFactory);
            var exception = await Record.ExceptionAsync(() => tcpClient.StartAsync());

            exception.Should().BeOfType <NotImplementedException>();
        }
Exemplo n.º 2
0
        public void VeryQuicklyCloseTest()
        {
            var server = new TestTcpServer();
            var engine = new DefaultEngine(server)
            {
                DelayForTest = 100
            };

            var client = new TestTcpClient();

            Task.Run(() => server.AcceptTcp(client));
            client.Close();
            int count = 0;

            while (!client.IsClosed)
            {
                Thread.Sleep(100);
                count++;
                if (50 < count)
                {
                    Assert.False(true, "timeout.");
                }
            }
            engine.connections.Count.Is(0);

            (engine as IReadOnlyHttpProxyEngine).Stop();
        }
Exemplo n.º 3
0
        public void ListeningConfigTest()
        {
            var server = new TestTcpServer();
            var engine = new DefaultEngine(server, new ListeningConfig(10000));

            (engine as IReadOnlyHttpProxyEngine).Start();
            server.IsStartupCalled.IsTrue();
            server.Port.Is(10000);

            engine.connections.Count.Is(0);
            server.AcceptTcp(new TestTcpClient());
            engine.connections.Count.Is(1);
            server.AcceptTcp(new TestTcpClient());
            engine.connections.Count.Is(2);

            var testClient = new TestTcpClient();

            server.AcceptTcp(testClient);
            engine.connections.Count.Is(3);
            var tcsDispose = new TaskCompletionSource <ProxyConnection>();

            engine.connections.Last().Disposing += connection => tcsDispose.TrySetResult(connection);
            testClient.Close();
            tcsDispose.Task.Wait(5000);
            engine.connections.Count.Is(2);

            (engine as IReadOnlyHttpProxyEngine).Stop();
            server.IsShutdownCalled.IsTrue();
            engine.connections.Count.Is(0);
        }
Exemplo n.º 4
0
        public void TunnelTest()
        {
            var clientTcp  = new TestTcpClient();
            var connection = new ProxyConnection(clientTcp)
            {
                CreateTcpClientForServer = (host, port) => new TestTcpClient(host, port)
            };
            var exceptions = new List <Exception>();

            connection.FatalException += (_, e) => exceptions.Add(e);

            connection.StartReceiving();

            var tcsSession = new TaskCompletionSource <IReadOnlySession>();

            connection.HttpResponseSent += result => tcsSession.TrySetResult(result);

            var request =
                @"CONNECT www.example.com:443 HTTP/1.1
Host: www.example.com:443
Proxy-Connection: keep-alive
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.79 Safari/537.36

";

            clientTcp.WriteToInput(request);

            var session = tcsSession.GetResult();

            session.Request.ToString().Is(request);

            var expectedResponse =
                @"HTTP/1.1 200 Connection Established
Date: Mon, 01 Jan 2018 01:00:00 GMT

";

            session.Response.ToString().Is(expectedResponse);

            connection.serverConnection.client.AsTest().Host.Is("www.example.com");
            connection.serverConnection.client.AsTest().Port.Is(443);
            connection.serverConnection.IsTunnelMode.IsTrue();
            connection.clientConnection.IsTunnelMode.IsTrue();

            var expectedString = "hogehoge\r\n";

            clientTcp.WriteToInput(expectedString);

            // HTTP と解釈できないので例外が発生するが、データは送信されている。
            var serverTcp = connection.serverConnection.client.AsTest();

            serverTcp.GetStream().AsTest().OutputStream.Is(expectedString);

            exceptions.Count.Is(1);

            connection.Dispose();
        }
        public void TestMethod1()
        {
            Assert.IsNotNull(_services);
            Assert.IsNotNull(_configuration);

            var client = new TestTcpClient("localhost", 4242);
            var result = client.SendTestMessage("Hello World!").GetAwaiter().GetResult();

            Assert.IsTrue(result == "Hello World!");
        }
Exemplo n.º 6
0
        public void Session302Test()
        {
            var clientTcp  = new TestTcpClient();
            var connection = new ProxyConnection(clientTcp)
            {
                CreateTcpClientForServer = (host, port) => new TestTcpClient(host, port)
            };

            connection.StartReceiving();

            var tcsRequest = new TaskCompletionSource <IReadOnlyHttpRequest>();

            connection.HttpRequestSent += result => tcsRequest.TrySetResult(result);

            var tcsSession = new TaskCompletionSource <IReadOnlySession>();

            connection.HttpResponseSent += result => tcsSession.TrySetResult(result);

            var tcsClose = new TaskCompletionSource <ProxyConnection>();

            connection.Disposing += result => tcsClose.TrySetResult(result);

            var request =
                @"GET http://www.example.com/netgame/social/-/gadgets/=/app_id=854854/ HTTP/1.1
Host: www.example.com
Proxy-Connection: keep-alive
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.79 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9

";

            clientTcp.WriteToInput(request);

            var requestResult = tcsRequest.GetResult();

            connection.serverConnection.client.AsTest().WriteFileToInput("TestData/Response302");

            var sessionResult = tcsSession.GetResult();

            sessionResult.Request.ToString().Is(request);

            var response = sessionResult.Response as HttpResponse;

            response.GetBodyAsString().Is("");

            connection.serverConnection.client.AsTest().Close();    // サーバーから閉じる
            //clientTcp.Close();  // クライアントから閉じる

            tcsClose.GetResult().Is(connection);

            connection.Dispose();
        }
Exemplo n.º 7
0
        public void IsCaptureBodyTest()
        {
            var server = new TestTcpServer();
            var engine = new DefaultEngine(server)
            {
                IsCaptureBody = false
            };

            var clientTcp = new TestTcpClient();

            server.AcceptTcp(clientTcp);

            var connection = engine.connections.Last();

            connection.CreateTcpClientForServer = (host, port) => new TestTcpClient(host, port);

            var tcsRequest = new TaskCompletionSource <IReadOnlyHttpRequest>();

            connection.HttpRequestSent += r => tcsRequest.TrySetResult(r);
            var tcsSession = new TaskCompletionSource <IReadOnlySession>();

            connection.HttpResponseSent += s => tcsSession.TrySetResult(s);

            var request =
                @"GET / HTTP/1.1
Host: hoge.example.com

";

            clientTcp.WriteToInput(request);

            tcsRequest.Task.Wait(5000);

            connection.serverConnection.client.AsTest().WriteFileToInput("TestData/ResponseChunked");

            var session = tcsSession.GetResult();

            (session.Request as HttpRequest).Source.Is(request);
            session.Response.ToString().Is(@"HTTP/1.1 200 OK
Server: nginx
Date: Thu, 20 Sep 2018 01:59:09 GMT
Content-Type: application/javascript; charset=utf-8
Transfer-Encoding: chunked
Connection: keep-alive
Cache-Control: private, no-cache, no-cache=""Set-Cookie"", proxy-revalidate
Pragma: no-cache
Access-Control-Allow-Origin: *
P3P: CP=""ADM NOI OUR""
Content-Encoding: gzip

");
            session.Response.Body.Length.Is(0);

            (engine as IReadOnlyHttpProxyEngine).Stop();
        }
Exemplo n.º 8
0
        private void ResponseTest(string path)
        {
            var tcp        = new TestTcpClient();
            var connection = new ClientConnection(tcp);

            connection.StartReceiving();
            connection.WriteFile(path);
            var response = tcp.ReadAllBytesFromOutput();

            response.Is(path);
            connection.Dispose();
        }
Exemplo n.º 9
0
        public void RequestBodyTest()
        {
            var tcp        = new TestTcpClient();
            var connection = new ClientConnection(tcp);

            connection.StartReceiving();
            var tcsHeader = new TaskCompletionSource <HttpRequest>();

            connection.ReceivedRequestHeaders += result => tcsHeader.TrySetResult(result);
            var tcsBody = new TaskCompletionSource <HttpRequest>();

            connection.ReceivedRequestBody += result => tcsBody.TrySetResult(result);

            tcp.WriteToInput(
                @"POST http://203.104.209.71/kcsapi/api_get_member/sortie_conditions HTTP/1.1
Host: 203.104.209.71
Connection: keep-alive
Content-Length: 62
Accept: application/json, text/plain, */*
Origin: http://203.104.209.71
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.79 Safari/537.36
Content-Type: application/x-www-form-urlencoded
Referer: http://203.104.209.71/kcs2/index.php?api_root=/kcsapi&voice_root=/kcs/sound&osapi_root=osapi.example.com&version=4.1.1.4
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9

api_token=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx&api_verno=1");

            var header = tcsHeader.GetResult();
            var body   = tcsBody.GetResult();

            header.RequestLine.HttpVersion.Is(new Version(1, 1));
            header.RequestLine.Method.Is(HttpMethod.Post);
            header.RequestLine.RequestTarget.Is("http://203.104.209.71/kcsapi/api_get_member/sortie_conditions");

            header.Headers.Host.Is("203.104.209.71");
            header.Headers.GetFirstValue("Connection").IsNull();
            header.Headers.GetOrigin().GetFirstValue("Connection").Is("keep-alive");
            header.Headers.ContentLength.Exists.IsTrue();
            header.Headers.ContentLength.Is(62);
            header.Headers.GetFirstValue("Accept").Is("application/json, text/plain, */*");
            header.Headers.GetFirstValue("User-Agent").Is("Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.79 Safari/537.36");
            header.Headers.ContentLength.Exists.IsTrue();
            header.Headers.ContentType.Is("application/x-www-form-urlencoded");
            header.Headers.GetFirstValue("Referer").Is("http://203.104.209.71/kcs2/index.php?api_root=/kcsapi&voice_root=/kcs/sound&osapi_root=osapi.example.com&version=4.1.1.4");
            header.Headers.GetFirstValue("Accept-Encoding").Is("gzip, deflate");
            header.Headers.GetFirstValue("Accept-Language").Is("en-US,en;q=0.9");

            body.GetBodyAsString().Is("api_token=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx&api_verno=1");

            connection.Dispose();
        }
Exemplo n.º 10
0
        public void SessionNoBodyTest()
        {
            var clientTcp  = new TestTcpClient();
            var connection = new ProxyConnection(clientTcp)
            {
                CreateTcpClientForServer = (host, port) => new TestTcpClient(host, port)
            };

            connection.StartReceiving();

            var tcsRequest = new TaskCompletionSource <IReadOnlyHttpRequest>();

            connection.HttpRequestSent += result => tcsRequest.TrySetResult(result);

            var tcsSession = new TaskCompletionSource <IReadOnlySession>();

            connection.HttpResponseSent += result => tcsSession.TrySetResult(result);

            var tcsClose = new TaskCompletionSource <ProxyConnection>();

            connection.Disposing += result => tcsClose.TrySetResult(result);

            var request =
                @"GET http://203.104.209.71/kcs2/resources/voice/titlecall_1/005.mp3 HTTP/1.1
Host: 203.104.209.71

";

            clientTcp.WriteToInput(request);

            var requestResult = tcsRequest.GetResult();

            connection.serverConnection.client.AsTest().WriteFileToInput("TestData/ResponseNoBody");

            var sessionResult = tcsSession.GetResult();

            sessionResult.Request.ToString().Is(request);

            var response = sessionResult.Response as HttpResponse;

            response.GetBodyAsString().Is("");

            connection.serverConnection.client.AsTest().Close();    // サーバーから閉じる
            //clientTcp.Close();  // クライアントから閉じる

            tcsClose.GetResult().Is(connection);

            connection.Dispose();
        }
Exemplo n.º 11
0
        public void RequestTest()
        {
            var tcp        = new TestTcpClient();
            var connection = new ClientConnection(tcp);

            connection.StartReceiving();
            var tcsHeader = new TaskCompletionSource <HttpRequest>();

            connection.ReceivedRequestHeaders += result => tcsHeader.TrySetResult(result);
            var tcsBody = new TaskCompletionSource <HttpRequest>();

            connection.ReceivedRequestBody += result => tcsBody.TrySetResult(result);

            tcp.WriteToInput(
                @"GET http://203.104.209.71/kcs2/resources/voice/titlecall_1/005.mp3 HTTP/1.1
Host: 203.104.209.71
Connection: keep-alive
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.79 Safari/537.36
Accept: */*
Referer: http://203.104.209.71/kcs2/index.php?api_root=/kcsapi&voice_root=/kcs/sound&osapi_root=osapi.example.com&version=4.1.1.4
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9

");

            var header = tcsHeader.GetResult();
            var body   = tcsBody.GetResult();

            header.RequestLine.HttpVersion.Is(new Version(1, 1));
            header.RequestLine.Method.Is(HttpMethod.Get);
            header.RequestLine.RequestTarget.Is("http://203.104.209.71/kcs2/resources/voice/titlecall_1/005.mp3");

            header.Headers.Host.Is("203.104.209.71");
            header.Headers.GetFirstValue("Connection").IsNull();
            header.Headers.GetOrigin().GetFirstValue("Connection").Is("keep-alive");
            header.Headers.GetFirstValue("User-Agent").Is("Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.79 Safari/537.36");
            header.Headers.GetFirstValue("Accept").Is("*/*");
            header.Headers.GetFirstValue("Referer").Is("http://203.104.209.71/kcs2/index.php?api_root=/kcsapi&voice_root=/kcs/sound&osapi_root=osapi.example.com&version=4.1.1.4");
            header.Headers.GetFirstValue("Accept-Encoding").Is("gzip, deflate");
            header.Headers.GetFirstValue("Accept-Language").Is("en-US,en;q=0.9");

            body.Body.IsNull();

            connection.Dispose();
        }
Exemplo n.º 12
0
        public void HandlerExceptionTest()
        {
            var server = new TestTcpServer();
            var engine = new DefaultEngine(server);

            var clientTcp = new TestTcpClient();

            server.AcceptTcp(clientTcp);

            var connection = engine.connections.Last();

            connection.CreateTcpClientForServer = (host, port) => new TestTcpClient(host, port);

            var tcsRequest = new TaskCompletionSource <IReadOnlyHttpRequest>();

            connection.HttpRequestSent += r => tcsRequest.TrySetResult(r);

            var tcsSession = new TaskCompletionSource <IReadOnlySession>();

            (engine as IReadOnlyHttpProxyEngine).HttpResponseSent += (_, s) => tcsSession.TrySetResult(s.Session);
            (engine as IReadOnlyHttpProxyEngine).HttpResponseSent += (_, s) => throw new Exception();

            var request =
                @"GET / HTTP/1.1
Host: hoge.example.com

";

            clientTcp.WriteToInput(request);

            tcsRequest.Task.Wait(5000);

            connection.serverConnection.client.AsTest().WriteFileToInput("TestData/ResponseChunked");

            var session = tcsSession.GetResult();

            engine.connections.Count.Is(1);

            (engine as IReadOnlyHttpProxyEngine).Stop();
        }
Exemplo n.º 13
0
        public void AfterSessionCompleteTest()
        {
            var server = new TestTcpServer();
            var engine = new DefaultEngine(server);

            var proxy       = HttpProxyFactory.Create(engine);
            var tcsComplete = new TaskCompletionSource <IReadOnlySession>();

            proxy.HttpResponseSent += (_, s) => tcsComplete.TrySetResult(s.Session);

            var clientTcp = new TestTcpClient();

            server.AcceptTcp(clientTcp);
            var connection = engine.connections.Last();

            connection.CreateTcpClientForServer = (host, port) => new TestTcpClient(host, port);

            var request =
                @"CONNECT www.example.com:443 HTTP/1.1
Host: www.example.com:443
Proxy-Connection: keep-alive
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.79 Safari/537.36

";

            clientTcp.WriteToInput(request);

            var expectedResponse =
                @"HTTP/1.1 200 Connection Established
Date: Mon, 01 Jan 2018 01:00:00 GMT

";

            var session = tcsComplete.GetResult();

            session.Request.ToString().Is(request);
            session.Response.ToString().Is(expectedResponse);
        }
Exemplo n.º 14
0
        public void SessionContentLengthTest()
        {
            var clientTcp  = new TestTcpClient();
            var connection = new ProxyConnection(clientTcp)
            {
                CreateTcpClientForServer = (host, port) => new TestTcpClient(host, port)
            };

            connection.StartReceiving();

            var tcsRequest = new TaskCompletionSource <IReadOnlyHttpRequest>();

            connection.HttpRequestSent += result => tcsRequest.TrySetResult(result);

            var tcsSession = new TaskCompletionSource <IReadOnlySession>();

            connection.HttpResponseSent += result => tcsSession.TrySetResult(result);

            var tcsClose = new TaskCompletionSource <ProxyConnection>();

            connection.Disposing += result => tcsClose.TrySetResult(result);

            var request =
                @"GET http://203.104.209.71/kcs2/resources/voice/titlecall_1/005.mp3 HTTP/1.1
Host: 203.104.209.71
Connection: keep-alive
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.79 Safari/537.36
Accept: */*
Referer: http://203.104.209.71/kcs2/index.php?api_root=/kcsapi&voice_root=/kcs/sound&osapi_root=osapi.example.com&version=4.1.1.4
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9

";

            clientTcp.WriteToInput(request);

            //var tcsRequestSuccess = tcsRequest.Task.Wait(1000);
            //if (!tcsRequestSuccess)
            //    Assert.False(true, "request timeout");
            var requestResult = tcsRequest.GetResult();

            connection.serverConnection.client.AsTest().WriteFileToInput("TestData/ResponseContentLength");

            //var tcsSessionSuccess = tcsSession.Task.Wait(1000);
            //if (!tcsSessionSuccess)
            //    Assert.False(true, "session timeout");
            var sessionResult = tcsSession.GetResult();

            var requestHeaders = sessionResult.Request.Headers as HttpHeaders;

            sessionResult.Request.RequestLine.HttpVersion.Is(new Version(1, 1));
            sessionResult.Request.RequestLine.Method.Is(HttpMethod.Get);
            sessionResult.Request.RequestLine.RequestTarget.Is("http://203.104.209.71/kcs2/resources/voice/titlecall_1/005.mp3");
            requestHeaders.Host.Is("203.104.209.71");
            requestHeaders.GetFirstValue("Connection").Is("keep-alive");
            requestHeaders.GetFirstValue("User-Agent").Is("Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.79 Safari/537.36");
            requestHeaders.GetFirstValue("Accept").Is("*/*");
            requestHeaders.GetFirstValue("Referer").Is("http://203.104.209.71/kcs2/index.php?api_root=/kcsapi&voice_root=/kcs/sound&osapi_root=osapi.example.com&version=4.1.1.4");
            requestHeaders.GetFirstValue("Accept-Encoding").Is("gzip, deflate");
            requestHeaders.GetFirstValue("Accept-Language").Is("en-US,en;q=0.9");
            requestHeaders.HasHeader("Via").IsFalse();
            sessionResult.Request.Body.IsNull();


            var response = sessionResult.Response as HttpResponse;

            response.StatusLine.HttpVersion.Is(new Version(1, 1));
            response.StatusLine.StatusCode.Is(HttpStatusCode.OK);
            response.StatusLine.ReasonPhrase.Is("OK");
            response.Headers.ContentLength.Exists.Is(true);
            response.Headers.ContentLength.Is(47);
            response.Headers.TransferEncoding.Exists.Is(false);
            response.Headers.IsChunked.Is(false);
            response.Headers.GetFirstValue("Access-Control-Allow-Credentials").Is("true");
            response.Headers.GetFirstValue("Access-Control-Allow-Methods").Is("POST,GET,HEAD,OPTIONS");
            response.Headers.GetFirstValue("Access-Control-Allow-Origin").Is("http://d.hatena.ne.jp");
            response.Headers.GetFirstValue("Cache-Control").Is("no-store, no-cache");
            response.Headers.ContentType.Is("application/json");
            response.Headers.GetFirstValue("Date").Is("Thu, 20 Sep 2018 01:59:09 GMT");
            response.Headers.GetFirstValue("Expires").Is("Mon, 15 Jun 1998 00:00:00 GMT");
            response.Headers.GetFirstValue("Pragma").Is("no-cache");
            response.Headers.GetFirstValue("Server").Is("Adtech Adserver");
            response.GetBodyAsString().Is(@"{""id"":""31259257328373081"",""seatbid"":[],""nbr"":1}");



            //connection.serverConnection.client.AsTest().Close();    // サーバーから閉じる
            clientTcp.Close();  // クライアントから閉じる

            tcsClose.GetResult().Is(connection);

            connection.Dispose();
        }
Exemplo n.º 15
0
        public async Task TcpClient_Should_Be_Derivable()
        {
            var tcpClient = new TestTcpClient(_tcpClientChannelFactory, _logger, _eventLoopGroupFactory);

            Assert.Throws <NotImplementedException>(() => tcpClient.StartAsync());
        }
Exemplo n.º 16
0
        public void ChangeUpstreamProxyTest()
        {
            var server     = new TestTcpServer();
            var engine     = new DefaultEngine(server);
            var clientTcp1 = new TestTcpClient();

            server.AcceptTcp(clientTcp1);
            var connection1 = engine.connections.Last();

            connection1.CreateTcpClientForServer = (host, port) => new TestTcpClient(host, port);

            engine.UpstreamProxyConfig = new UpstreamProxyConfig("first.example.com", 1);

            var tcsRequest1_1 = new TaskCompletionSource <IReadOnlyHttpRequest>();

            connection1.HttpRequestSent += r => tcsRequest1_1.TrySetResult(r);

            var request =
                @"GET / HTTP/1.1
Host: hoge.example.com

";

            clientTcp1.WriteToInput(request);

            var request1_1 = tcsRequest1_1.GetResult();

            var serverTcp1 = connection1.serverConnection.client.AsTest();

            serverTcp1.Host.Is("first.example.com");
            serverTcp1.Port.Is(1);

            // UpstreamProxyConfig 変更
            engine.UpstreamProxyConfig = new UpstreamProxyConfig("second.example.com", 2);

            var tcsRequest1_2 = new TaskCompletionSource <IReadOnlyHttpRequest>();

            connection1.HttpRequestSent += r => tcsRequest1_2.TrySetResult(r);
            clientTcp1.WriteToInput(request);
            // 接続中のコネクションには反映されない
            var request1_2 = tcsRequest1_2.GetResult();

            serverTcp1.Host.Is("first.example.com");
            serverTcp1.Port.Is(1);

            // 次の接続から反映される
            var clientTcp2 = new TestTcpClient();

            server.AcceptTcp(clientTcp2);
            var connection2 = engine.connections.Last();

            connection2.CreateTcpClientForServer = (host, port) => new TestTcpClient(host, port);

            connection2.HttpRequestSent += r => tcsRequest1_1.TrySetResult(r);

            var tcsRequest2 = new TaskCompletionSource <IReadOnlyHttpRequest>();

            connection2.HttpRequestSent += r => tcsRequest2.TrySetResult(r);
            clientTcp2.WriteToInput(request);
            var request2   = tcsRequest2.GetResult();
            var serverTcp2 = connection2.serverConnection.client.AsTest();

            serverTcp2.Host.Is("second.example.com");
            serverTcp2.Port.Is(2);

            (engine as IReadOnlyHttpProxyEngine).Stop();
        }