add tests for invalid HTTP headers (dotnet/corefx#36898)
authorTomas Weinfurt <tweinfurt@yahoo.com>
Tue, 16 Apr 2019 21:53:07 +0000 (14:53 -0700)
committerGitHub <noreply@github.com>
Tue, 16 Apr 2019 21:53:07 +0000 (14:53 -0700)
* add SendAsync_InvalidHeader_Throw

* fix tests

* move SendAsync_InvalidHeader_Throw

Commit migrated from https://github.com/dotnet/corefx/commit/18e1fabd13b40eb6ea88c1b7bae8c4e14a927019

src/libraries/Common/tests/System/Net/Http/Http2LoopbackServer.cs
src/libraries/Common/tests/System/Net/Http/LoopbackServer.cs
src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http2Connection.cs
src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.Headers.cs

index f70024e..bfabf9d 100644 (file)
@@ -282,6 +282,10 @@ namespace System.Net.Test.Common
         {
             // Receive HEADERS frame for request.
             Frame frame = await ReadFrameAsync(TimeSpan.FromSeconds(30));
+            if (frame == null)
+            {
+                throw new IOException("Failed to read Headers frame.");
+            }
             Assert.Equal(FrameType.Headers, frame.Type);
             Assert.Equal(FrameFlags.EndHeaders | FrameFlags.EndStream, frame.Flags);
             return frame.StreamId;
@@ -498,6 +502,10 @@ namespace System.Net.Test.Common
 
             // Receive HEADERS frame for request.
             Frame frame = await ReadFrameAsync(Timeout).ConfigureAwait(false);
+            if (frame == null)
+            {
+                throw new IOException("Failed to read Headers frame.");
+            }
             Assert.Equal(FrameType.Headers, frame.Type);
             HeadersFrame headersFrame = (HeadersFrame) frame;
 
@@ -619,7 +627,7 @@ namespace System.Net.Test.Common
                 throw new Exception("Response body too long");
             }
 
-            await SendResponseDataAsync(streamId, responseBody, true);
+            await SendResponseDataAsync(streamId, responseBody, true).ConfigureAwait(false);
         }
 
         public override void Dispose()
@@ -637,25 +645,25 @@ namespace System.Net.Test.Common
 
         public override async Task<HttpRequestData> HandleRequestAsync(HttpStatusCode statusCode = HttpStatusCode.OK, IList<HttpHeaderData> headers = null, string content = null)
         {
-            await EstablishConnectionAsync();
+            await EstablishConnectionAsync().ConfigureAwait(false);
 
-            (int streamId, HttpRequestData requestData) = await ReadAndParseRequestHeaderAsync();
+            (int streamId, HttpRequestData requestData) = await ReadAndParseRequestHeaderAsync().ConfigureAwait(false);
 
             // We are about to close the connection, after we send the response.
             // So, send a GOAWAY frame now so the client won't inadvertantly try to reuse the connection.
-            await SendGoAway(streamId);
+            await SendGoAway(streamId).ConfigureAwait(false);
 
             if (content == null)
             {
-                await SendResponseHeadersAsync(streamId, endStream: true, statusCode, isTrailingHeader: false, headers);
+                await SendResponseHeadersAsync(streamId, endStream: true, statusCode, isTrailingHeader: false, headers).ConfigureAwait(false);
             }
             else
             {
-                await SendResponseHeadersAsync(streamId, endStream: false, statusCode, isTrailingHeader: false, headers);
-                await SendResponseBodyAsync(streamId, Encoding.ASCII.GetBytes(content));
+                await SendResponseHeadersAsync(streamId, endStream: false, statusCode, isTrailingHeader: false, headers).ConfigureAwait(false);
+                await SendResponseBodyAsync(streamId, Encoding.ASCII.GetBytes(content)).ConfigureAwait(false);
             }
 
-            await WaitForConnectionShutdownAsync();
+            await WaitForConnectionShutdownAsync().ConfigureAwait(false);
 
             return requestData;
         }
@@ -677,7 +685,7 @@ namespace System.Net.Test.Common
         {
             using (var server = Http2LoopbackServer.CreateServer())
             {
-                await funcAsync(server, server.Address).TimeoutAfter(millisecondsTimeout);
+                await funcAsync(server, server.Address).TimeoutAfter(millisecondsTimeout).ConfigureAwait(false);
             }
         }
 
index 25cdaf5..a1867ee 100644 (file)
@@ -565,7 +565,7 @@ namespace System.Net.Test.Common
 
                 if (line == null)
                 {
-                    throw new Exception("Unexpected EOF trying to read request header");
+                    throw new IOException("Unexpected EOF trying to read request header");
                 }
 
                 return lines;
index e338ef0..213e0c0 100644 (file)
@@ -968,9 +968,6 @@ namespace System.Net.Http
                 http2Stream = AddStream(request);
                 int streamId = http2Stream.StreamId;
 
-                http2Stream = AddStream(request);
-                streamId = http2Stream.StreamId;
-
                 // Generate the entire header block, without framing, into the connection header buffer.
                 WriteHeaders(request);
 
@@ -1013,7 +1010,11 @@ namespace System.Net.Http
             }
             catch
             {
-                http2Stream?.Dispose();
+                if (http2Stream != null)
+                {
+                    RemoveStream(http2Stream);
+                    http2Stream.Dispose();
+                }
                 throw;
             }
             finally
index 37921cc..5f5abc4 100644 (file)
@@ -44,6 +44,34 @@ namespace System.Net.Http.Functional.Tests
             });
         }
 
+        [Theory]
+        [InlineData("\u05D1\u05F1")]
+        [InlineData("jp\u30A5")]
+        public async Task SendAsync_InvalidHeader_Throw(string value)
+        {
+            await LoopbackServerFactory.CreateClientAndServerAsync(async uri =>
+            {
+                HttpClientHandler handler = CreateHttpClientHandler();
+                using (HttpClient client = CreateHttpClient())
+                {
+                    var request = new HttpRequestMessage(HttpMethod.Get, uri);
+                    Assert.True(request.Headers.TryAddWithoutValidation("bad", value));
+
+                    await Assert.ThrowsAsync<HttpRequestException>(() => client.SendAsync(request));
+                }
+
+            },
+            async server =>
+            {
+                try
+                {
+                    // Client should abort at some point so this is going to throw.
+                    HttpRequestData requestData = await server.HandleRequestAsync(HttpStatusCode.OK).ConfigureAwait(false);
+                }
+                catch (IOException) { };
+            });
+        }
+
         [Fact]
         public async Task SendAsync_SpecialCharacterHeader_Success()
         {