From a9cb6b1f1a12f9746eae3b8bc06268faaae5565e Mon Sep 17 00:00:00 2001 From: Stephen Toub Date: Thu, 1 Feb 2018 17:17:49 -0500 Subject: [PATCH] Move ManagedHandler version/chunking validation earlier Move it to ManagedHandler.SendAsync rather than HttpConnection.SendAsync so that it happens before we even try to get a connection. A minor benefit of the change as well is that isHttp10 is no longer lifted to the state machine. --- .../System/Net/Http/Managed/HttpConnection.cs | 34 +++---------------- .../System/Net/Http/Managed/ManagedHandler.cs | 22 ++++++++++++ 2 files changed, 26 insertions(+), 30 deletions(-) diff --git a/src/System.Net.Http/src/System/Net/Http/Managed/HttpConnection.cs b/src/System.Net.Http/src/System/Net/Http/Managed/HttpConnection.cs index c48b7b0731c6..bd8a31602e65 100644 --- a/src/System.Net.Http/src/System/Net/Http/Managed/HttpConnection.cs +++ b/src/System.Net.Http/src/System/Net/Http/Managed/HttpConnection.cs @@ -220,38 +220,10 @@ public async Task SendAsync(HttpRequestMessage request, Can Debug.Assert(!_canRetry); _canRetry = true; + // Send the request. + if (NetEventSource.IsEnabled) Trace($"Sending request: {request}"); try { - // Our max supported version is 1.1, so if Version > 1.1, degrade to 1.1. - Debug.Assert(request.Version.Major >= 0 && request.Version.Minor >= 0); // guaranteed by Version class - bool isHttp10 = false; - if (request.Version.Major == 0) - { - throw new NotSupportedException(SR.net_http_unsupported_version); - } - else if (request.Version.Major == 1 && request.Version.Minor == 0) - { - isHttp10 = true; - } - - // Send the request. - if (NetEventSource.IsEnabled) Trace($"Sending request: {request}"); - - // Add headers to define content transfer, if not present - if (request.Content != null && - (!request.HasHeaders || request.Headers.TransferEncodingChunked != true) && - request.Content.Headers.ContentLength == null) - { - // We have content, but neither Transfer-Encoding or Content-Length is set. - request.Headers.TransferEncodingChunked = true; - } - - if (isHttp10 && request.HasHeaders && request.Headers.TransferEncodingChunked == true) - { - // HTTP 1.0 does not support chunking - throw new NotSupportedException(SR.net_http_unsupported_chunking); - } - // Write request line await WriteStringAsync(request.Method.Method, cancellationToken).ConfigureAwait(false); await WriteByteAsync((byte)' ', cancellationToken).ConfigureAwait(false); @@ -267,6 +239,8 @@ public async Task SendAsync(HttpRequestMessage request, Can await WriteStringAsync(request.RequestUri.PathAndQuery, cancellationToken).ConfigureAwait(false); // fall-back to 1.1 for all versions other than 1.0 + Debug.Assert(request.Version.Major >= 0 && request.Version.Minor >= 0); // guaranteed by Version class + bool isHttp10 = request.Version.Minor == 0 && request.Version.Major == 1; await WriteBytesAsync(isHttp10 ? s_spaceHttp10NewlineAsciiBytes : s_spaceHttp11NewlineAsciiBytes, cancellationToken).ConfigureAwait(false); diff --git a/src/System.Net.Http/src/System/Net/Http/Managed/ManagedHandler.cs b/src/System.Net.Http/src/System/Net/Http/Managed/ManagedHandler.cs index 58d849393a4f..76ac59850b17 100644 --- a/src/System.Net.Http/src/System/Net/Http/Managed/ManagedHandler.cs +++ b/src/System.Net.Http/src/System/Net/Http/Managed/ManagedHandler.cs @@ -300,6 +300,28 @@ protected internal override Task SendAsync( { CheckDisposed(); HttpMessageHandler handler = _handler ?? SetupHandlerChain(); + + if (request.Version.Major == 0) + { + return Task.FromException(new NotSupportedException(SR.net_http_unsupported_version)); + } + + // Add headers to define content transfer, if not present + if (request.Content != null && + (!request.HasHeaders || request.Headers.TransferEncodingChunked != true) && + request.Content.Headers.ContentLength == null) + { + // We have content, but neither Transfer-Encoding or Content-Length is set. + request.Headers.TransferEncodingChunked = true; + } + + if (request.Version.Minor == 0 && request.Version.Major == 1 && + request.HasHeaders && request.Headers.TransferEncodingChunked == true) + { + // HTTP 1.0 does not support chunking + return Task.FromException(new NotSupportedException(SR.net_http_unsupported_chunking)); + } + return handler.SendAsync(request, cancellationToken); } }