コード例 #1
0
        private HttpContext GetContext(ClusterInfo cluster, int selectedDestination, IProxyErrorFeature error)
        {
            var context = new DefaultHttpContext();

            context.Features.Set(GetProxyFeature(cluster, cluster.DynamicState.AllDestinations[selectedDestination]));
            context.Features.Set(error);
            return(context);
        }
コード例 #2
0
        public async Task ProxyAsync_RequestWithEncodedHeaderValue(string headerValue, string encodingName)
        {
            var encoding = Encoding.GetEncoding(encodingName);
            var tcs      = new TaskCompletionSource <StringValues>(TaskCreationOptions.RunContinuationsAsynchronously);

            IProxyErrorFeature proxyError     = null;
            Exception          unhandledError = null;

            var test = new TestEnvironment(
                context =>
            {
                if (context.Request.Headers.TryGetValue(HeaderNames.Referer, out var header))
                {
                    tcs.SetResult(header);
                }
                else
                {
                    tcs.SetException(new Exception($"Missing '{HeaderNames.Referer}' header in request"));
                }
                return(Task.CompletedTask);
            },
                proxyBuilder => { },
                proxyApp =>
            {
                proxyApp.Use(async(context, next) =>
                {
                    try
                    {
                        Assert.True(context.Request.Headers.TryGetValue(HeaderNames.Referer, out var header));
                        var value = Assert.Single(header);
                        Assert.Equal(headerValue, value);

                        await next();
                        proxyError = context.Features.Get <IProxyErrorFeature>();
                    }
                    catch (Exception ex)
                    {
                        unhandledError = ex;
                        throw;
                    }
                });
            },
                proxyProtocol: HttpProtocols.Http1, headerEncoding: encoding);

            await test.Invoke(async proxyUri =>
            {
                var proxyHostUri = new Uri(proxyUri);

                using var tcpClient    = new TcpClient(proxyHostUri.Host, proxyHostUri.Port);
                await using var stream = tcpClient.GetStream();
                await stream.WriteAsync(Encoding.ASCII.GetBytes("GET / HTTP/1.1\r\n"));
                await stream.WriteAsync(Encoding.ASCII.GetBytes($"Host: {proxyHostUri.Host}:{proxyHostUri.Port}\r\n"));
                await stream.WriteAsync(Encoding.ASCII.GetBytes($"Content-Length: 0\r\n"));
                await stream.WriteAsync(Encoding.ASCII.GetBytes($"Connection: close\r\n"));
                await stream.WriteAsync(Encoding.ASCII.GetBytes($"Referer: "));
                await stream.WriteAsync(encoding.GetBytes(headerValue));
                await stream.WriteAsync(Encoding.ASCII.GetBytes("\r\n"));
                await stream.WriteAsync(Encoding.ASCII.GetBytes("\r\n"));
                var buffer          = new byte[4096];
                var responseBuilder = new StringBuilder();
                while (true)
                {
                    var count = await stream.ReadAsync(buffer);
                    if (count == 0)
                    {
                        break;
                    }
                    responseBuilder.Append(Encoding.ASCII.GetString(buffer, 0, count));
                }
                var response = responseBuilder.ToString();

                Assert.Null(proxyError);
                Assert.Null(unhandledError);

                Assert.StartsWith("HTTP/1.1 200 OK", response);

                Assert.True(tcs.Task.IsCompleted);
                var refererHeader = await tcs.Task;
                var referer       = Assert.Single(refererHeader);
                Assert.Equal(headerValue, referer);
            });
        }
コード例 #3
0
        public async Task ProxyAsync_ResponseWithEncodedHeaderValue(string headerValue, string encodingName)
        {
            var encoding = Encoding.GetEncoding(encodingName);

            var tcpListener = new TcpListener(IPAddress.Loopback, 0);

            tcpListener.Start();
            var destinationTask = Task.Run(async() =>
            {
                using var tcpClient    = await tcpListener.AcceptTcpClientAsync();
                await using var stream = tcpClient.GetStream();
                var buffer             = new byte[4096];
                var requestBuilder     = new StringBuilder();
                while (true)
                {
                    var count = await stream.ReadAsync(buffer);
                    if (count == 0)
                    {
                        break;
                    }

                    requestBuilder.Append(encoding.GetString(buffer, 0, count));

                    // End of the request
                    if (requestBuilder.Length >= 4 &&
                        requestBuilder[^ 4] == '\r' && requestBuilder[^ 3] == '\n' &&
                        requestBuilder[^ 2] == '\r' && requestBuilder[^ 1] == '\n')
                    {
                        break;
                    }
                }

                await stream.WriteAsync(Encoding.ASCII.GetBytes($"HTTP/1.1 200 OK\r\n"));
                await stream.WriteAsync(Encoding.ASCII.GetBytes($"Content-Length: 0\r\n"));
                await stream.WriteAsync(Encoding.ASCII.GetBytes($"Connection: close\r\n"));
                await stream.WriteAsync(Encoding.ASCII.GetBytes($"Test-Extra: pingu\r\n"));
                await stream.WriteAsync(Encoding.ASCII.GetBytes($"Location: "));
                await stream.WriteAsync(encoding.GetBytes(headerValue));
                await stream.WriteAsync(Encoding.ASCII.GetBytes("\r\n"));
                await stream.WriteAsync(Encoding.ASCII.GetBytes("\r\n"));
            });

            IProxyErrorFeature proxyError     = null;
            Exception          unhandledError = null;

            using var proxy = TestEnvironment.CreateProxy(HttpProtocols.Http1, false, encoding, "cluster1", $"http://{tcpListener.LocalEndpoint}",
                                                          proxyBuilder => { },
                                                          proxyApp =>
            {
                proxyApp.Use(async(context, next) =>
                {
                    try
                    {
                        await next();
                        proxyError = context.Features.Get <IProxyErrorFeature>();
                    }
                    catch (Exception ex)
                    {
                        unhandledError = ex;
                        throw;
                    }
                });
            });

            await proxy.StartAsync();

            try
            {
                using var httpClient = new HttpClient();
                using var response   = await httpClient.GetAsync(proxy.GetAddress());

                Assert.NotNull(proxyError);
                Assert.Equal(ProxyError.ResponseHeaders, proxyError.Error);
                var ioe = Assert.IsType <InvalidOperationException>(proxyError.Exception);
                Assert.StartsWith("Invalid non-ASCII or control character in header: ", ioe.Message);
                Assert.Null(unhandledError);

                Assert.Equal(HttpStatusCode.BadGateway, response.StatusCode);

                Assert.False(response.Headers.TryGetValues(HeaderNames.Location, out _));
                Assert.False(response.Headers.TryGetValues("Test-Extra", out _));

                Assert.True(destinationTask.IsCompleted);
                await destinationTask;
            }
            finally
            {
                await proxy.StopAsync();

                tcpListener.Stop();
            }
        }