Browse Source

Make kestrel not use the modified Http Protocol #17975 (#18322)

Chris Ross 6 years ago
parent
commit
6dd3d6ec49

+ 2 - 2
src/Servers/Kestrel/Core/src/Internal/Http/HttpProtocol.FeatureCollection.cs

@@ -37,8 +37,8 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
 
         string IHttpRequestFeature.Protocol
         {
-            get => HttpVersion;
-            set => HttpVersion = value;
+            get => _httpProtocol ??= HttpVersion;
+            set => _httpProtocol = value;
         }
 
         string IHttpRequestFeature.Scheme

+ 4 - 0
src/Servers/Kestrel/Core/src/Internal/Http/HttpProtocol.cs

@@ -57,6 +57,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
         private BadHttpRequestException _requestRejectedException;
 
         protected HttpVersion _httpVersion;
+        // This should only be used by the application, not the server. This is settable on HttpRequest but we don't want that to affect
+        // how Kestrel processes requests/responses.
+        private string _httpProtocol;
 
         private string _requestId;
         private int _requestHeadersParsed;
@@ -351,6 +354,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
             RawTarget = null;
             QueryString = null;
             _httpVersion = Http.HttpVersion.Unknown;
+            _httpProtocol = null;
             _statusCode = StatusCodes.Status200OK;
             _reasonPhrase = null;
 

+ 36 - 0
src/Servers/Kestrel/test/InMemory.FunctionalTests/ChunkedResponseTests.cs

@@ -78,6 +78,42 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests
             }
         }
 
+        [Fact]
+        public async Task IgnoresChangesToHttpProtocol()
+        {
+            var testContext = new TestServiceContext(LoggerFactory);
+
+            await using (var server = new TestServer(async httpContext =>
+            {
+                httpContext.Request.Protocol = "HTTP/2"; // Doesn't support chunking. This change should be ignored.
+                var response = httpContext.Response;
+                await response.BodyWriter.WriteAsync(new Memory<byte>(Encoding.ASCII.GetBytes("Hello "), 0, 6));
+                await response.BodyWriter.WriteAsync(new Memory<byte>(Encoding.ASCII.GetBytes("World!"), 0, 6));
+            }, testContext))
+            {
+                using (var connection = server.CreateConnection())
+                {
+                    await connection.Send(
+                        "GET / HTTP/1.1",
+                        "Host:",
+                        "",
+                        "");
+                    await connection.Receive(
+                        "HTTP/1.1 200 OK",
+                        $"Date: {testContext.DateHeaderValue}",
+                        "Transfer-Encoding: chunked",
+                        "",
+                        "6",
+                        "Hello ",
+                        "6",
+                        "World!",
+                        "0",
+                        "",
+                        "");
+                }
+            }
+        }
+
         [Fact]
         public async Task ResponsesAreChunkedAutomaticallyForHttp11NonKeepAliveRequests()
         {