From 4b03513e20e0caf9ee34817eb74356903f1bb33e Mon Sep 17 00:00:00 2001 From: buyaa-n Date: Mon, 16 Mar 2020 18:06:01 -0700 Subject: [PATCH] Annotate System.Net.Http for nullable (#33268) * Annotate System.Net.Http for nullable --- .../Interop/OSX/Interop.CoreFoundation.CFProxy.cs | 22 +- .../Windows/WinHttp/Interop.SafeWinHttpHandle.cs | 5 +- .../src/Interop/Windows/WinHttp/Interop.winhttp.cs | 3 +- .../Windows/WinHttp/Interop.winhttp_types.cs | 3 +- .../Common/src/System/IO/DelegatingStream.cs | 5 +- .../Common/src/System/IO/ReadOnlyMemoryStream.cs | 2 +- .../System/Net/Http/NoWriteNoSeekStreamContent.cs | 7 +- .../src/System/Net/Http/WinInetProxyHelper.cs | 19 +- .../Http/aspnetcore/Http2/Hpack/HPackDecoder.cs | 11 +- .../Http/aspnetcore/Http2/Hpack/HPackEncoder.cs | 5 +- .../Http/aspnetcore/Http3/QPack/QPackDecoder.cs | 11 +- .../Http/aspnetcore/Http3/QPack/QPackEncoder.cs | 8 +- .../Quic/Implementations/Mock/MockConnection.cs | 33 +- .../Mock/MockImplementationProvider.cs | 2 +- .../Quic/Implementations/Mock/MockListener.cs | 11 +- .../Quic/Implementations/Mock/MockStream.cs | 25 +- .../Implementations/MsQuic/Internal/MsQuicApi.cs | 9 +- .../MsQuic/Internal/MsQuicSession.cs | 4 +- .../MsQuic/Internal/QuicExceptionHelpers.cs | 3 +- .../MsQuic/Internal/ResettableCompletionSource.cs | 3 +- .../Implementations/MsQuic/MsQuicConnection.cs | 19 +- .../Quic/Implementations/MsQuic/MsQuicListener.cs | 11 +- .../Quic/Implementations/MsQuic/MsQuicStream.cs | 7 +- .../aspnetcore/Quic/Interop/MsQuicNativeMethods.cs | 3 +- .../aspnetcore/Quic/QuicClientConnectionOptions.cs | 7 +- .../Net/Http/aspnetcore/Quic/QuicConnection.cs | 5 +- .../Http/aspnetcore/Quic/QuicListenerOptions.cs | 9 +- .../System/Net/Http/aspnetcore/Quic/QuicStream.cs | 5 +- .../Net/HttpKnownHeaderNames.TryGetHeaderName.cs | 12 +- .../Common/src/System/Net/HttpStatusDescription.cs | 5 +- .../System/Net/Logging/NetEventSource.Common.cs | 2 +- .../Common/src/System/Net/Mail/MailAddress.cs | 3 +- .../src/System/Net/Mail/MailAddressParser.cs | 16 +- .../Common/src/System/Net/Mail/MailBnfHelper.cs | 13 +- .../src/System/Net/NTAuthentication.Common.cs | 8 +- .../System/Net/Security/CertificateHelper.Unix.cs | 2 +- .../Net/Security/CertificateHelper.Windows.cs | 3 +- .../src/System/Net/Security/CertificateHelper.cs | 5 +- .../System/Net/Security/NegotiateStreamPal.Unix.cs | 8 +- .../Net/Security/NegotiateStreamPal.Windows.cs | 4 +- .../SslClientAuthenticationOptionsExtensions.cs | 6 +- .../ExceptionServices/ExceptionStackTrace.cs | 5 +- .../Common/src/System/StrongToWeakReference.cs | 6 +- .../System/Threading/Tasks/RendezvousAwaitable.cs | 16 +- src/libraries/Common/tests/Common.Tests.csproj | 1 + .../src/System.Net.Http.WinHttpHandler.csproj | 1 + ...ystem.Net.Http.WinHttpHandler.Unit.Tests.csproj | 1 + .../System.Net.Http/ref/System.Net.Http.cs | 361 +++++++++++---------- .../System.Net.Http/ref/System.Net.Http.csproj | 1 + .../System.Net.Http/src/System.Net.Http.csproj | 1 + .../src/System/Net/Http/ByteArrayContent.cs | 6 +- .../src/System/Net/Http/DelegatingHandler.cs | 8 +- .../src/System/Net/Http/DiagnosticsHandler.cs | 20 +- .../src/System/Net/Http/FormUrlEncodedContent.cs | 12 +- .../System/Net/Http/Headers/AltSvcHeaderParser.cs | 17 +- .../System/Net/Http/Headers/AltSvcHeaderValue.cs | 4 +- .../Net/Http/Headers/AuthenticationHeaderValue.cs | 24 +- .../System/Net/Http/Headers/BaseHeaderParser.cs | 14 +- .../Net/Http/Headers/ByteArrayHeaderParser.cs | 3 +- .../Net/Http/Headers/CacheControlHeaderParser.cs | 6 +- .../Net/Http/Headers/CacheControlHeaderValue.cs | 30 +- .../Http/Headers/ContentDispositionHeaderValue.cs | 68 ++-- .../Net/Http/Headers/ContentRangeHeaderValue.cs | 23 +- .../System/Net/Http/Headers/DateHeaderParser.cs | 3 +- .../Net/Http/Headers/EntityTagHeaderValue.cs | 18 +- .../System/Net/Http/Headers/GenericHeaderParser.cs | 39 +-- .../System/Net/Http/Headers/HeaderDescriptor.cs | 19 +- .../src/System/Net/Http/Headers/HeaderUtilities.cs | 16 +- .../System/Net/Http/Headers/HttpContentHeaders.cs | 28 +- .../System/Net/Http/Headers/HttpGeneralHeaders.cs | 22 +- .../System/Net/Http/Headers/HttpHeaderParser.cs | 16 +- .../Net/Http/Headers/HttpHeaderValueCollection.cs | 30 +- .../src/System/Net/Http/Headers/HttpHeaders.cs | 155 ++++----- .../System/Net/Http/Headers/HttpRequestHeaders.cs | 45 ++- .../System/Net/Http/Headers/HttpResponseHeaders.cs | 24 +- .../Net/Http/Headers/Int32NumberHeaderParser.cs | 4 +- .../Net/Http/Headers/Int64NumberHeaderParser.cs | 4 +- .../src/System/Net/Http/Headers/KnownHeader.cs | 6 +- .../src/System/Net/Http/Headers/KnownHeaders.cs | 10 +- .../Net/Http/Headers/MediaTypeHeaderParser.cs | 7 +- .../Net/Http/Headers/MediaTypeHeaderValue.cs | 45 ++- .../Headers/MediaTypeWithQualityHeaderValue.cs | 8 +- .../Net/Http/Headers/NameValueHeaderValue.cs | 40 +-- .../Headers/NameValueWithParametersHeaderValue.cs | 23 +- .../System/Net/Http/Headers/ProductHeaderValue.cs | 21 +- .../Net/Http/Headers/ProductInfoHeaderParser.cs | 8 +- .../Net/Http/Headers/ProductInfoHeaderValue.cs | 28 +- .../Net/Http/Headers/RangeConditionHeaderValue.cs | 23 +- .../System/Net/Http/Headers/RangeHeaderValue.cs | 18 +- .../Net/Http/Headers/RangeItemHeaderValue.cs | 13 +- .../Net/Http/Headers/RetryConditionHeaderValue.cs | 17 +- .../Http/Headers/StringWithQualityHeaderValue.cs | 16 +- .../Net/Http/Headers/TimeSpanHeaderParser.cs | 4 +- .../Net/Http/Headers/TransferCodingHeaderParser.cs | 7 +- .../Net/Http/Headers/TransferCodingHeaderValue.cs | 20 +- .../TransferCodingWithQualityHeaderValue.cs | 8 +- .../src/System/Net/Http/Headers/UriHeaderParser.cs | 6 +- .../src/System/Net/Http/Headers/ViaHeaderValue.cs | 50 ++- .../System/Net/Http/Headers/WarningHeaderValue.cs | 30 +- .../src/System/Net/Http/HttpClient.cs | 96 +++--- .../src/System/Net/Http/HttpClientHandler.cs | 14 +- .../src/System/Net/Http/HttpContent.cs | 69 ++-- .../src/System/Net/Http/HttpMethod.cs | 18 +- .../src/System/Net/Http/HttpRequestException.cs | 8 +- .../src/System/Net/Http/HttpRequestMessage.cs | 28 +- .../src/System/Net/Http/HttpResponseMessage.cs | 16 +- .../src/System/Net/Http/HttpRuleParser.cs | 5 +- .../src/System/Net/Http/HttpUtilities.cs | 2 +- .../System/Net/Http/MessageProcessingHandler.cs | 4 +- .../src/System/Net/Http/MultipartContent.cs | 10 +- .../System/Net/Http/MultipartFormDataContent.cs | 4 +- .../src/System/Net/Http/NetEventSource.Http.cs | 18 +- .../src/System/Net/Http/ReadOnlyMemoryContent.cs | 6 +- .../AuthenticationHelper.Digest.cs | 28 +- .../AuthenticationHelper.NtAuth.cs | 19 +- .../SocketsHttpHandler/AuthenticationHelper.cs | 22 +- .../Http/SocketsHttpHandler/CancellationHelper.cs | 4 +- .../ChunkedEncodingReadStream.cs | 10 +- .../Net/Http/SocketsHttpHandler/ConnectHelper.cs | 20 +- .../ConnectionCloseReadStream.cs | 6 +- .../SocketsHttpHandler/ContentLengthReadStream.cs | 8 +- .../Net/Http/SocketsHttpHandler/CookieHelper.cs | 4 +- .../Net/Http/SocketsHttpHandler/CreditManager.cs | 9 +- .../Net/Http/SocketsHttpHandler/CreditWaiter.cs | 4 +- .../SocketsHttpHandler/DecompressionHandler.cs | 13 +- .../Net/Http/SocketsHttpHandler/Http2Connection.cs | 33 +- .../Net/Http/SocketsHttpHandler/Http2Stream.cs | 55 ++-- .../Net/Http/SocketsHttpHandler/Http3Connection.cs | 38 +-- .../Http/SocketsHttpHandler/Http3RequestStream.cs | 64 ++-- .../Net/Http/SocketsHttpHandler/HttpAuthority.cs | 5 +- .../Net/Http/SocketsHttpHandler/HttpBaseStream.cs | 4 +- .../Net/Http/SocketsHttpHandler/HttpConnection.cs | 50 +-- .../Http/SocketsHttpHandler/HttpConnectionBase.cs | 2 +- .../Http/SocketsHttpHandler/HttpConnectionPool.cs | 181 ++++++----- .../HttpConnectionPoolManager.cs | 53 +-- .../HttpConnectionResponseContent.cs | 6 +- .../SocketsHttpHandler/HttpConnectionSettings.cs | 20 +- .../SocketsHttpHandler/HttpContentReadStream.cs | 4 +- .../Http/SocketsHttpHandler/HttpContentStream.cs | 2 +- .../SocketsHttpHandler/HttpContentWriteStream.cs | 4 +- .../HttpEnvironmentProxy.Unix.cs | 12 +- .../HttpEnvironmentProxy.Windows.cs | 12 +- .../SocketsHttpHandler/HttpEnvironmentProxy.cs | 46 +-- .../Net/Http/SocketsHttpHandler/HttpNoProxy.cs | 4 +- .../Http/SocketsHttpHandler/HttpWindowsProxy.cs | 31 +- .../Net/Http/SocketsHttpHandler/IHttpTrace.cs | 2 +- .../System/Net/Http/SocketsHttpHandler/MacProxy.cs | 14 +- .../Net/Http/SocketsHttpHandler/MultiProxy.cs | 27 +- .../Http/SocketsHttpHandler/RawConnectionStream.cs | 12 +- .../Net/Http/SocketsHttpHandler/RedirectHandler.cs | 13 +- .../Http/SocketsHttpHandler/SocketsHttpHandler.cs | 18 +- .../Http/SocketsHttpHandler/SystemProxyInfo.OSX.cs | 2 +- .../SocketsHttpHandler/SystemProxyInfo.Unix.cs | 2 +- .../SocketsHttpHandler/SystemProxyInfo.Windows.cs | 2 +- .../src/System/Net/Http/StreamContent.cs | 8 +- .../src/System/Net/Http/StringContent.cs | 10 +- .../UnitTests/System.Net.Http.Unit.Tests.csproj | 1 + 157 files changed, 1531 insertions(+), 1454 deletions(-) diff --git a/src/libraries/Common/src/Interop/OSX/Interop.CoreFoundation.CFProxy.cs b/src/libraries/Common/src/Interop/OSX/Interop.CoreFoundation.CFProxy.cs index 2ed609b..580a3d8 100644 --- a/src/libraries/Common/src/Interop/OSX/Interop.CoreFoundation.CFProxy.cs +++ b/src/libraries/Common/src/Interop/OSX/Interop.CoreFoundation.CFProxy.cs @@ -50,12 +50,12 @@ internal static partial class Interop { private SafeCFDictionaryHandle _dictionary; - internal static readonly string kCFProxyTypeAutoConfigurationURL; - internal static readonly string kCFProxyTypeAutoConfigurationJavaScript; - internal static readonly string kCFProxyTypeFTP; - internal static readonly string kCFProxyTypeHTTP; - internal static readonly string kCFProxyTypeHTTPS; - internal static readonly string kCFProxyTypeSOCKS; + internal static readonly string? kCFProxyTypeAutoConfigurationURL; + internal static readonly string? kCFProxyTypeAutoConfigurationJavaScript; + internal static readonly string? kCFProxyTypeFTP; + internal static readonly string? kCFProxyTypeHTTP; + internal static readonly string? kCFProxyTypeHTTPS; + internal static readonly string? kCFProxyTypeSOCKS; private static readonly IntPtr kCFProxyAutoConfigurationJavaScriptKey; private static readonly IntPtr kCFProxyAutoConfigurationURLKey; @@ -109,7 +109,7 @@ internal static partial class Interop } } - private string GetString(IntPtr key) + private string? GetString(IntPtr key) { IntPtr dictValue = CFDictionaryGetValue(_dictionary, key); if (dictValue != IntPtr.Zero) @@ -122,10 +122,10 @@ internal static partial class Interop return null; } - public string ProxyType => GetString(kCFProxyTypeKey); - public string HostName => GetString(kCFProxyHostNameKey); - public string Username => GetString(kCFProxyUsernameKey); - public string Password => GetString(kCFProxyPasswordKey); + public string? ProxyType => GetString(kCFProxyTypeKey); + public string? HostName => GetString(kCFProxyHostNameKey); + public string? Username => GetString(kCFProxyUsernameKey); + public string? Password => GetString(kCFProxyPasswordKey); public int PortNumber { diff --git a/src/libraries/Common/src/Interop/Windows/WinHttp/Interop.SafeWinHttpHandle.cs b/src/libraries/Common/src/Interop/Windows/WinHttp/Interop.SafeWinHttpHandle.cs index 866a0bb..a2b2e72 100644 --- a/src/libraries/Common/src/Interop/Windows/WinHttp/Interop.SafeWinHttpHandle.cs +++ b/src/libraries/Common/src/Interop/Windows/WinHttp/Interop.SafeWinHttpHandle.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System; using System.Diagnostics; using System.Runtime.InteropServices; @@ -14,13 +15,13 @@ internal partial class Interop { internal class SafeWinHttpHandle : SafeHandleZeroOrMinusOneIsInvalid { - private SafeWinHttpHandle _parentHandle = null; + private SafeWinHttpHandle? _parentHandle = null; public SafeWinHttpHandle() : base(true) { } - public static void DisposeAndClearHandle(ref SafeWinHttpHandle safeHandle) + public static void DisposeAndClearHandle(ref SafeWinHttpHandle? safeHandle) { if (safeHandle != null) { diff --git a/src/libraries/Common/src/Interop/Windows/WinHttp/Interop.winhttp.cs b/src/libraries/Common/src/Interop/Windows/WinHttp/Interop.winhttp.cs index 8f72b74..3b5429b 100644 --- a/src/libraries/Common/src/Interop/Windows/WinHttp/Interop.winhttp.cs +++ b/src/libraries/Common/src/Interop/Windows/WinHttp/Interop.winhttp.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System; using System.Runtime.InteropServices; using System.Text; @@ -189,7 +190,7 @@ internal partial class Interop [DllImport(Interop.Libraries.WinHttp, CharSet = CharSet.Unicode, SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool WinHttpGetProxyForUrl( - SafeWinHttpHandle sessionHandle, string url, + SafeWinHttpHandle? sessionHandle, string url, ref WINHTTP_AUTOPROXY_OPTIONS autoProxyOptions, out WINHTTP_PROXY_INFO proxyInfo); diff --git a/src/libraries/Common/src/Interop/Windows/WinHttp/Interop.winhttp_types.cs b/src/libraries/Common/src/Interop/Windows/WinHttp/Interop.winhttp_types.cs index adf182e..4c1824f 100644 --- a/src/libraries/Common/src/Interop/Windows/WinHttp/Interop.winhttp_types.cs +++ b/src/libraries/Common/src/Interop/Windows/WinHttp/Interop.winhttp_types.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System; using System.Runtime.InteropServices; using System.Text; @@ -239,7 +240,7 @@ internal partial class Interop public uint Flags; public uint AutoDetectFlags; [MarshalAs(UnmanagedType.LPWStr)] - public string AutoConfigUrl; + public string? AutoConfigUrl; public IntPtr Reserved1; public uint Reserved2; [MarshalAs(UnmanagedType.Bool)] diff --git a/src/libraries/Common/src/System/IO/DelegatingStream.cs b/src/libraries/Common/src/System/IO/DelegatingStream.cs index 889bbb2..cbb3075 100644 --- a/src/libraries/Common/src/System/IO/DelegatingStream.cs +++ b/src/libraries/Common/src/System/IO/DelegatingStream.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Diagnostics; using System.IO; using System.Threading; @@ -113,7 +114,7 @@ namespace System.Net.Http return _innerStream.ReadAsync(buffer, cancellationToken); } - public override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback callback, object state) + public override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback? callback, object? state) { return _innerStream.BeginRead(buffer, offset, count, callback, state); } @@ -167,7 +168,7 @@ namespace System.Net.Http return _innerStream.WriteAsync(buffer, cancellationToken); } - public override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback callback, object state) + public override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback? callback, object? state) { return _innerStream.BeginWrite(buffer, offset, count, callback, state); } diff --git a/src/libraries/Common/src/System/IO/ReadOnlyMemoryStream.cs b/src/libraries/Common/src/System/IO/ReadOnlyMemoryStream.cs index 5ec499d..6c82660 100644 --- a/src/libraries/Common/src/System/IO/ReadOnlyMemoryStream.cs +++ b/src/libraries/Common/src/System/IO/ReadOnlyMemoryStream.cs @@ -105,7 +105,7 @@ namespace System.IO new ValueTask(Task.FromCanceled(cancellationToken)) : new ValueTask(Read(buffer.Span)); - public override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback callback, object state) => + public override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback? callback, object? state) => TaskToApm.Begin(ReadAsync(buffer, offset, count), callback, state); public override int EndRead(IAsyncResult asyncResult) => diff --git a/src/libraries/Common/src/System/Net/Http/NoWriteNoSeekStreamContent.cs b/src/libraries/Common/src/System/Net/Http/NoWriteNoSeekStreamContent.cs index dd8a295..de84102 100644 --- a/src/libraries/Common/src/System/Net/Http/NoWriteNoSeekStreamContent.cs +++ b/src/libraries/Common/src/System/Net/Http/NoWriteNoSeekStreamContent.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Diagnostics; using System.IO; using System.Threading; @@ -26,7 +27,7 @@ namespace System.Net.Http _content = content; } - protected override Task SerializeToStreamAsync(Stream stream, TransportContext context) => + protected override Task SerializeToStreamAsync(Stream stream, TransportContext? context) => SerializeToStreamAsync(stream, context, CancellationToken.None); #if NETCOREAPP @@ -34,7 +35,7 @@ namespace System.Net.Http #else internal #endif - Task SerializeToStreamAsync(Stream stream, TransportContext context, CancellationToken cancellationToken) + Task SerializeToStreamAsync(Stream stream, TransportContext? context, CancellationToken cancellationToken) { Debug.Assert(stream != null); @@ -54,7 +55,7 @@ namespace System.Net.Http { copyTask = copyTask.ContinueWith((t, s) => { - try { ((Stream)s).Dispose(); } catch { } + try { ((Stream)s!).Dispose(); } catch { } t.GetAwaiter().GetResult(); }, _content, CancellationToken.None, TaskContinuationOptions.ExecuteSynchronously, TaskScheduler.Default); } diff --git a/src/libraries/Common/src/System/Net/Http/WinInetProxyHelper.cs b/src/libraries/Common/src/System/Net/Http/WinInetProxyHelper.cs index ff1b71e..f597c7d 100644 --- a/src/libraries/Common/src/System/Net/Http/WinInetProxyHelper.cs +++ b/src/libraries/Common/src/System/Net/Http/WinInetProxyHelper.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System; using System.Runtime.InteropServices; @@ -14,7 +15,7 @@ namespace System.Net.Http internal class WinInetProxyHelper { private const int RecentAutoDetectionInterval = 120_000; // 2 minutes in milliseconds. - private readonly string _autoConfigUrl, _proxy, _proxyBypass; + private readonly string? _autoConfigUrl, _proxy, _proxyBypass; private readonly bool _autoDetect; private readonly bool _useProxy = false; private bool _autoDetectionFailed; @@ -28,10 +29,10 @@ namespace System.Net.Http { if (Interop.WinHttp.WinHttpGetIEProxyConfigForCurrentUser(out proxyConfig)) { - _autoConfigUrl = Marshal.PtrToStringUni(proxyConfig.AutoConfigUrl); + _autoConfigUrl = Marshal.PtrToStringUni(proxyConfig.AutoConfigUrl)!; _autoDetect = proxyConfig.AutoDetect; - _proxy = Marshal.PtrToStringUni(proxyConfig.Proxy); - _proxyBypass = Marshal.PtrToStringUni(proxyConfig.ProxyBypass); + _proxy = Marshal.PtrToStringUni(proxyConfig.Proxy)!; + _proxyBypass = Marshal.PtrToStringUni(proxyConfig.ProxyBypass)!; if (NetEventSource.IsEnabled) { @@ -59,7 +60,7 @@ namespace System.Net.Http } } - public string AutoConfigUrl => _autoConfigUrl; + public string? AutoConfigUrl => _autoConfigUrl; public bool AutoDetect => _autoDetect; @@ -69,16 +70,16 @@ namespace System.Net.Http public bool ManualSettingsOnly => !AutoSettingsUsed && ManualSettingsUsed; - public string Proxy => _proxy; + public string? Proxy => _proxy; - public string ProxyBypass => _proxyBypass; + public string? ProxyBypass => _proxyBypass; public bool RecentAutoDetectionFailure => _autoDetectionFailed && Environment.TickCount - _lastTimeAutoDetectionFailed <= RecentAutoDetectionInterval; public bool GetProxyForUrl( - SafeWinHttpHandle sessionHandle, + SafeWinHttpHandle? sessionHandle, Uri uri, out Interop.WinHttp.WINHTTP_PROXY_INFO proxyInfo) { @@ -123,7 +124,7 @@ namespace System.Net.Http { _autoDetectionFailed = false; if (Interop.WinHttp.WinHttpGetProxyForUrl( - sessionHandle, + sessionHandle!, uri.AbsoluteUri, ref autoProxyOptions, out proxyInfo)) diff --git a/src/libraries/Common/src/System/Net/Http/aspnetcore/Http2/Hpack/HPackDecoder.cs b/src/libraries/Common/src/System/Net/Http/aspnetcore/Http2/Hpack/HPackDecoder.cs index 41eb1c6..3fe3c86 100644 --- a/src/libraries/Common/src/System/Net/Http/aspnetcore/Http2/Hpack/HPackDecoder.cs +++ b/src/libraries/Common/src/System/Net/Http/aspnetcore/Http2/Hpack/HPackDecoder.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Buffers; using System.Diagnostics; #if KESTREL @@ -93,7 +94,7 @@ namespace System.Net.Http.HPack private byte[] _headerValueOctets; private State _state = State.Ready; - private byte[] _headerName; + private byte[]? _headerName; private int _stringIndex; private int _stringLength; private int _headerNameLength; @@ -129,13 +130,13 @@ namespace System.Net.Http.HPack CheckIncompleteHeaderBlock(endHeaders); } - public void Decode(ReadOnlySpan data, bool endHeaders, IHttpHeadersHandler handler) + public void Decode(ReadOnlySpan data, bool endHeaders, IHttpHeadersHandler? handler) { DecodeInternal(data, endHeaders, handler); CheckIncompleteHeaderBlock(endHeaders); } - private void DecodeInternal(ReadOnlySpan data, bool endHeaders, IHttpHeadersHandler handler) + private void DecodeInternal(ReadOnlySpan data, bool endHeaders, IHttpHeadersHandler? handler) { int intResult; @@ -370,7 +371,7 @@ namespace System.Net.Http.HPack } } - private void ProcessHeaderValue(IHttpHeadersHandler handler) + private void ProcessHeaderValue(IHttpHeadersHandler? handler) { OnString(nextState: State.Ready); @@ -394,7 +395,7 @@ namespace System.Net.Http.HPack } } - private void OnIndexedHeaderField(int index, IHttpHeadersHandler handler) + private void OnIndexedHeaderField(int index, IHttpHeadersHandler? handler) { HeaderField header = GetHeader(index); handler?.OnHeader(header.Name, header.Value); diff --git a/src/libraries/Common/src/System/Net/Http/aspnetcore/Http2/Hpack/HPackEncoder.cs b/src/libraries/Common/src/System/Net/Http/aspnetcore/Http2/Hpack/HPackEncoder.cs index 15aec6c..d09f184 100644 --- a/src/libraries/Common/src/System/Net/Http/aspnetcore/Http2/Hpack/HPackEncoder.cs +++ b/src/libraries/Common/src/System/Net/Http/aspnetcore/Http2/Hpack/HPackEncoder.cs @@ -2,6 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable +using System.Collections.Generic; using System.Diagnostics; namespace System.Net.Http.HPack @@ -370,7 +372,7 @@ namespace System.Net.Http.HPack return false; } - public static bool EncodeStringLiterals(ReadOnlySpan values, string separator, Span destination, out int bytesWritten) + public static bool EncodeStringLiterals(ReadOnlySpan values, string? separator, Span destination, out int bytesWritten) { bytesWritten = 0; @@ -393,6 +395,7 @@ namespace System.Net.Http.HPack valueLength = checked((int)(valueLength + part.Length)); } + Debug.Assert(separator != null); valueLength = checked((int)(valueLength + (values.Length - 1) * separator.Length)); destination[0] = 0; diff --git a/src/libraries/Common/src/System/Net/Http/aspnetcore/Http3/QPack/QPackDecoder.cs b/src/libraries/Common/src/System/Net/Http/aspnetcore/Http3/QPack/QPackDecoder.cs index 958dfac..e3b8587 100644 --- a/src/libraries/Common/src/System/Net/Http/aspnetcore/Http3/QPack/QPackDecoder.cs +++ b/src/libraries/Common/src/System/Net/Http/aspnetcore/Http3/QPack/QPackDecoder.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Buffers; using System.Diagnostics; using System.Net.Http.HPack; @@ -118,7 +119,7 @@ namespace System.Net.Http.QPack private bool _huffman; private int? _index; - private byte[] _headerName; + private byte[]? _headerName; private int _headerNameLength; private int _headerValueLength; private int _stringLength; @@ -130,7 +131,7 @@ namespace System.Net.Http.QPack private static void ReturnAndGetNewPooledArray(ref byte[] buffer, int newSize) { byte[] old = buffer; - buffer = null; + buffer = null!; Pool.Return(old, clearArray: true); buffer = Pool.Rent(newSize); @@ -151,19 +152,19 @@ namespace System.Net.Http.QPack if (_stringOctets != null) { Pool.Return(_stringOctets, true); - _stringOctets = null; + _stringOctets = null!; } if (_headerNameOctets != null) { Pool.Return(_headerNameOctets, true); - _headerNameOctets = null; + _headerNameOctets = null!; } if (_headerValueOctets != null) { Pool.Return(_headerValueOctets, true); - _headerValueOctets = null; + _headerValueOctets = null!; } } diff --git a/src/libraries/Common/src/System/Net/Http/aspnetcore/Http3/QPack/QPackEncoder.cs b/src/libraries/Common/src/System/Net/Http/aspnetcore/Http3/QPack/QPackEncoder.cs index ecf0f1e..c956095 100644 --- a/src/libraries/Common/src/System/Net/Http/aspnetcore/Http3/QPack/QPackEncoder.cs +++ b/src/libraries/Common/src/System/Net/Http/aspnetcore/Http3/QPack/QPackEncoder.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Collections.Generic; using System.Diagnostics; using System.Net.Http.HPack; @@ -10,7 +11,7 @@ namespace System.Net.Http.QPack { internal class QPackEncoder { - private IEnumerator> _enumerator; + private IEnumerator>? _enumerator; // https://tools.ietf.org/html/draft-ietf-quic-qpack-11#section-4.5.2 // 0 1 2 3 4 5 6 7 @@ -194,7 +195,7 @@ namespace System.Net.Http.QPack /// /// Encodes a value by concatenating a collection of strings, separated by a separator string. /// - public static bool EncodeValueString(ReadOnlySpan values, string separator, Span buffer, out int length) + public static bool EncodeValueString(ReadOnlySpan values, string? separator, Span buffer, out int length) { if (values.Length == 1) { @@ -209,6 +210,7 @@ namespace System.Net.Http.QPack if (buffer.Length > 0) { + Debug.Assert(separator != null); int valueLength = separator.Length * (values.Length - 1); for (int i = 0; i < values.Length; ++i) { @@ -386,7 +388,7 @@ namespace System.Net.Http.QPack do { - if (!EncodeLiteralHeaderFieldWithoutNameReference(_enumerator.Current.Key, _enumerator.Current.Value, buffer.Slice(length), out int headerLength)) + if (!EncodeLiteralHeaderFieldWithoutNameReference(_enumerator!.Current.Key, _enumerator.Current.Value, buffer.Slice(length), out int headerLength)) { if (length == 0 && throwIfNoneEncoded) { diff --git a/src/libraries/Common/src/System/Net/Http/aspnetcore/Quic/Implementations/Mock/MockConnection.cs b/src/libraries/Common/src/System/Net/Http/aspnetcore/Quic/Implementations/Mock/MockConnection.cs index d9ab070..ae40406 100644 --- a/src/libraries/Common/src/System/Net/Http/aspnetcore/Quic/Implementations/Mock/MockConnection.cs +++ b/src/libraries/Common/src/System/Net/Http/aspnetcore/Quic/Implementations/Mock/MockConnection.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Buffers.Binary; using System.Net.Security; using System.Net.Sockets; @@ -14,17 +15,17 @@ namespace System.Net.Quic.Implementations.Mock { private readonly bool _isClient; private bool _disposed = false; - private IPEndPoint _remoteEndPoint; - private IPEndPoint _localEndPoint; + private IPEndPoint? _remoteEndPoint; + private IPEndPoint? _localEndPoint; private object _syncObject = new object(); - private Socket _socket = null; - private IPEndPoint _peerListenEndPoint = null; - private TcpListener _inboundListener = null; + private Socket? _socket = null; + private IPEndPoint? _peerListenEndPoint = null; + private TcpListener? _inboundListener = null; private long _nextOutboundBidirectionalStream; private long _nextOutboundUnidirectionalStream; // Constructor for outbound connections - internal MockConnection(IPEndPoint remoteEndPoint, SslClientAuthenticationOptions sslClientAuthenticationOptions, IPEndPoint localEndPoint = null) + internal MockConnection(IPEndPoint? remoteEndPoint, SslClientAuthenticationOptions? sslClientAuthenticationOptions, IPEndPoint? localEndPoint = null) { _remoteEndPoint = remoteEndPoint; _localEndPoint = localEndPoint; @@ -43,8 +44,8 @@ namespace System.Net.Quic.Implementations.Mock _socket = socket; _peerListenEndPoint = peerListenEndPoint; _inboundListener = inboundListener; - _localEndPoint = (IPEndPoint)socket.LocalEndPoint; - _remoteEndPoint = (IPEndPoint)socket.RemoteEndPoint; + _localEndPoint = (IPEndPoint?)socket.LocalEndPoint; + _remoteEndPoint = (IPEndPoint?)socket.RemoteEndPoint; } internal override bool Connected @@ -57,9 +58,9 @@ namespace System.Net.Quic.Implementations.Mock } } - internal override IPEndPoint LocalEndPoint => new IPEndPoint(_localEndPoint.Address, _localEndPoint.Port); + internal override IPEndPoint LocalEndPoint => new IPEndPoint(_localEndPoint!.Address, _localEndPoint.Port); - internal override IPEndPoint RemoteEndPoint => new IPEndPoint(_remoteEndPoint.Address, _remoteEndPoint.Port); + internal override IPEndPoint RemoteEndPoint => new IPEndPoint(_remoteEndPoint!.Address, _remoteEndPoint.Port); internal override SslApplicationProtocol NegotiatedApplicationProtocol => throw new NotImplementedException(); @@ -73,14 +74,14 @@ namespace System.Net.Quic.Implementations.Mock throw new InvalidOperationException("Already connected"); } - Socket socket = new Socket(_remoteEndPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp); + Socket socket = new Socket(_remoteEndPoint!.AddressFamily, SocketType.Stream, ProtocolType.Tcp); await socket.ConnectAsync(_remoteEndPoint).ConfigureAwait(false); socket.NoDelay = true; - _localEndPoint = (IPEndPoint)socket.LocalEndPoint; + _localEndPoint = (IPEndPoint?)socket.LocalEndPoint; // Listen on a new local endpoint for inbound streams - TcpListener inboundListener = new TcpListener(_localEndPoint.Address, 0); + TcpListener inboundListener = new TcpListener(_localEndPoint!.Address, 0); inboundListener.Start(); int inboundListenPort = ((IPEndPoint)inboundListener.LocalEndpoint).Port; @@ -97,7 +98,7 @@ namespace System.Net.Quic.Implementations.Mock } while (bytesRead != buffer.Length); int peerListenPort = BinaryPrimitives.ReadInt32LittleEndian(buffer); - IPEndPoint peerListenEndPoint = new IPEndPoint(((IPEndPoint)socket.RemoteEndPoint).Address, peerListenPort); + IPEndPoint peerListenEndPoint = new IPEndPoint(((IPEndPoint)socket.RemoteEndPoint!).Address, peerListenPort); _socket = socket; _peerListenEndPoint = peerListenEndPoint; @@ -141,7 +142,7 @@ namespace System.Net.Quic.Implementations.Mock internal async Task CreateOutboundMockStreamAsync(long streamId) { Socket socket = new Socket(SocketType.Stream, ProtocolType.Tcp); - await socket.ConnectAsync(_peerListenEndPoint).ConfigureAwait(false); + await socket.ConnectAsync(_peerListenEndPoint!).ConfigureAwait(false); socket.NoDelay = true; // Write stream ID to socket so server can read it @@ -156,7 +157,7 @@ namespace System.Net.Quic.Implementations.Mock { CheckDisposed(); - Socket socket = await _inboundListener.AcceptSocketAsync().ConfigureAwait(false); + Socket socket = await _inboundListener!.AcceptSocketAsync().ConfigureAwait(false); // Read first bytes to get stream ID byte[] buffer = new byte[8]; diff --git a/src/libraries/Common/src/System/Net/Http/aspnetcore/Quic/Implementations/Mock/MockImplementationProvider.cs b/src/libraries/Common/src/System/Net/Http/aspnetcore/Quic/Implementations/Mock/MockImplementationProvider.cs index b70a113..56a5a11 100644 --- a/src/libraries/Common/src/System/Net/Http/aspnetcore/Quic/Implementations/Mock/MockImplementationProvider.cs +++ b/src/libraries/Common/src/System/Net/Http/aspnetcore/Quic/Implementations/Mock/MockImplementationProvider.cs @@ -10,7 +10,7 @@ namespace System.Net.Quic.Implementations.Mock { internal override QuicListenerProvider CreateListener(QuicListenerOptions options) { - return new MockListener(options.ListenEndPoint, options.ServerAuthenticationOptions); + return new MockListener(options.ListenEndPoint!, options.ServerAuthenticationOptions); } internal override QuicConnectionProvider CreateConnection(QuicClientConnectionOptions options) diff --git a/src/libraries/Common/src/System/Net/Http/aspnetcore/Quic/Implementations/Mock/MockListener.cs b/src/libraries/Common/src/System/Net/Http/aspnetcore/Quic/Implementations/Mock/MockListener.cs index 911f189..88297bd 100644 --- a/src/libraries/Common/src/System/Net/Http/aspnetcore/Quic/Implementations/Mock/MockListener.cs +++ b/src/libraries/Common/src/System/Net/Http/aspnetcore/Quic/Implementations/Mock/MockListener.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Net.Sockets; using System.Net.Security; using System.Threading.Tasks; @@ -13,11 +14,11 @@ namespace System.Net.Quic.Implementations.Mock internal sealed class MockListener : QuicListenerProvider { private bool _disposed = false; - private SslServerAuthenticationOptions _sslOptions; + private SslServerAuthenticationOptions? _sslOptions; private IPEndPoint _listenEndPoint; - private TcpListener _tcpListener = null; + private TcpListener _tcpListener; - internal MockListener(IPEndPoint listenEndPoint, SslServerAuthenticationOptions sslServerAuthenticationOptions) + internal MockListener(IPEndPoint listenEndPoint, SslServerAuthenticationOptions? sslServerAuthenticationOptions) { if (listenEndPoint == null) { @@ -49,7 +50,7 @@ namespace System.Net.Quic.Implementations.Mock } while (bytesRead != buffer.Length); int peerListenPort = BinaryPrimitives.ReadInt32LittleEndian(buffer); - IPEndPoint peerListenEndPoint = new IPEndPoint(((IPEndPoint)socket.RemoteEndPoint).Address, peerListenPort); + IPEndPoint peerListenEndPoint = new IPEndPoint(((IPEndPoint)socket.RemoteEndPoint!).Address, peerListenPort); // Listen on a new local endpoint for inbound streams TcpListener inboundListener = new TcpListener(_listenEndPoint.Address, 0); @@ -96,7 +97,7 @@ namespace System.Net.Quic.Implementations.Mock if (disposing) { _tcpListener?.Stop(); - _tcpListener = null; + _tcpListener = null!; } // TODO: free unmanaged resources (unmanaged objects) and override a finalizer below. diff --git a/src/libraries/Common/src/System/Net/Http/aspnetcore/Quic/Implementations/Mock/MockStream.cs b/src/libraries/Common/src/System/Net/Http/aspnetcore/Quic/Implementations/Mock/MockStream.cs index 187ba68..f367d98 100644 --- a/src/libraries/Common/src/System/Net/Http/aspnetcore/Quic/Implementations/Mock/MockStream.cs +++ b/src/libraries/Common/src/System/Net/Http/aspnetcore/Quic/Implementations/Mock/MockStream.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Buffers; using System.Diagnostics; using System.Net.Sockets; @@ -17,9 +18,9 @@ namespace System.Net.Quic.Implementations.Mock private bool _canRead; private bool _canWrite; - private MockConnection _connection; + private MockConnection? _connection; - private Socket _socket = null; + private Socket? _socket = null; // Constructor for outbound streams internal MockStream(MockConnection connection, long streamId, bool bidirectional) @@ -69,7 +70,7 @@ namespace System.Net.Quic.Implementations.Mock throw new NotSupportedException(); } - return _socket.Receive(buffer); + return _socket!.Receive(buffer); } internal override async ValueTask ReadAsync(Memory buffer, CancellationToken cancellationToken = default) @@ -86,7 +87,7 @@ namespace System.Net.Quic.Implementations.Mock await ConnectAsync(cancellationToken).ConfigureAwait(false); } - return await _socket.ReceiveAsync(buffer, SocketFlags.None, cancellationToken).ConfigureAwait(false); + return await _socket!.ReceiveAsync(buffer, SocketFlags.None, cancellationToken).ConfigureAwait(false); } internal override bool CanWrite => _canWrite; @@ -100,7 +101,7 @@ namespace System.Net.Quic.Implementations.Mock throw new NotSupportedException(); } - _socket.Send(buffer); + _socket!.Send(buffer); } internal override ValueTask WriteAsync(ReadOnlyMemory buffer, CancellationToken cancellationToken = default) @@ -121,11 +122,11 @@ namespace System.Net.Quic.Implementations.Mock { await ConnectAsync(cancellationToken).ConfigureAwait(false); } - await _socket.SendAsync(buffer, SocketFlags.None, cancellationToken).ConfigureAwait(false); + await _socket!.SendAsync(buffer, SocketFlags.None, cancellationToken).ConfigureAwait(false); if (endStream) { - _socket.Shutdown(SocketShutdown.Send); + _socket!.Shutdown(SocketShutdown.Send); } } @@ -149,12 +150,12 @@ namespace System.Net.Quic.Implementations.Mock foreach (ReadOnlyMemory buffer in buffers) { - await _socket.SendAsync(buffer, SocketFlags.None, cancellationToken).ConfigureAwait(false); + await _socket!.SendAsync(buffer, SocketFlags.None, cancellationToken).ConfigureAwait(false); } if (endStream) { - _socket.Shutdown(SocketShutdown.Send); + _socket!.Shutdown(SocketShutdown.Send); } } @@ -178,12 +179,12 @@ namespace System.Net.Quic.Implementations.Mock foreach (ReadOnlyMemory buffer in buffers.ToArray()) { - await _socket.SendAsync(buffer, SocketFlags.None, cancellationToken).ConfigureAwait(false); + await _socket!.SendAsync(buffer, SocketFlags.None, cancellationToken).ConfigureAwait(false); } if (endStream) { - _socket.Shutdown(SocketShutdown.Send); + _socket!.Shutdown(SocketShutdown.Send); } } @@ -221,7 +222,7 @@ namespace System.Net.Quic.Implementations.Mock { CheckDisposed(); - _socket.Shutdown(SocketShutdown.Send); + _socket!.Shutdown(SocketShutdown.Send); } private void CheckDisposed() diff --git a/src/libraries/Common/src/System/Net/Http/aspnetcore/Quic/Implementations/MsQuic/Internal/MsQuicApi.cs b/src/libraries/Common/src/System/Net/Http/aspnetcore/Quic/Implementations/MsQuic/Internal/MsQuicApi.cs index 977af1d..0b98933 100644 --- a/src/libraries/Common/src/System/Net/Http/aspnetcore/Quic/Implementations/MsQuic/Internal/MsQuicApi.cs +++ b/src/libraries/Common/src/System/Net/Http/aspnetcore/Quic/Implementations/MsQuic/Internal/MsQuicApi.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.IO; using System.Net.Security; using System.Runtime.InteropServices; @@ -127,7 +128,7 @@ namespace System.Net.Quic.Implementations.MsQuic.Internal _registrationContext = ctx; } - internal static MsQuicApi Api { get; } + internal static MsQuicApi Api { get; } = null!; internal static bool IsQuicSupported { get; } @@ -221,10 +222,10 @@ namespace System.Net.Quic.Implementations.MsQuic.Internal buf); } - public async ValueTask CreateSecurityConfig(X509Certificate certificate, string certFilePath, string privateKeyFilePath) + public async ValueTask CreateSecurityConfig(X509Certificate certificate, string? certFilePath, string? privateKeyFilePath) { - MsQuicSecurityConfig secConfig = null; - var tcs = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously); + MsQuicSecurityConfig? secConfig = null; + var tcs = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously); uint secConfigCreateStatus = MsQuicStatusCodes.InternalError; uint createConfigStatus; IntPtr unmanagedAddr = IntPtr.Zero; diff --git a/src/libraries/Common/src/System/Net/Http/aspnetcore/Quic/Implementations/MsQuic/Internal/MsQuicSession.cs b/src/libraries/Common/src/System/Net/Http/aspnetcore/Quic/Implementations/MsQuic/Internal/MsQuicSession.cs index 89dd99f..0f19506 100644 --- a/src/libraries/Common/src/System/Net/Http/aspnetcore/Quic/Implementations/MsQuic/Internal/MsQuicSession.cs +++ b/src/libraries/Common/src/System/Net/Http/aspnetcore/Quic/Implementations/MsQuic/Internal/MsQuicSession.cs @@ -22,7 +22,7 @@ namespace System.Net.Quic.Implementations.MsQuic.Internal { if (!_opened) { - OpenSession(options.ClientAuthenticationOptions.ApplicationProtocols[0].Protocol.ToArray(), + OpenSession(options.ClientAuthenticationOptions!.ApplicationProtocols![0].Protocol.ToArray(), (ushort)options.MaxBidirectionalStreams, (ushort)options.MaxUnidirectionalStreams); } @@ -50,7 +50,7 @@ namespace System.Net.Quic.Implementations.MsQuic.Internal { if (!_opened) { - OpenSession(options.ServerAuthenticationOptions.ApplicationProtocols[0].Protocol.ToArray(), + OpenSession(options.ServerAuthenticationOptions!.ApplicationProtocols![0].Protocol.ToArray(), (ushort)options.MaxBidirectionalStreams, (ushort)options.MaxUnidirectionalStreams); } diff --git a/src/libraries/Common/src/System/Net/Http/aspnetcore/Quic/Implementations/MsQuic/Internal/QuicExceptionHelpers.cs b/src/libraries/Common/src/System/Net/Http/aspnetcore/Quic/Implementations/MsQuic/Internal/QuicExceptionHelpers.cs index 1b8ab8e..bca44c0 100644 --- a/src/libraries/Common/src/System/Net/Http/aspnetcore/Quic/Implementations/MsQuic/Internal/QuicExceptionHelpers.cs +++ b/src/libraries/Common/src/System/Net/Http/aspnetcore/Quic/Implementations/MsQuic/Internal/QuicExceptionHelpers.cs @@ -2,11 +2,12 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable namespace System.Net.Quic.Implementations.MsQuic.Internal { internal static class QuicExceptionHelpers { - internal static void ThrowIfFailed(uint status, string message = null, Exception innerException = null) + internal static void ThrowIfFailed(uint status, string? message = null, Exception? innerException = null) { if (!MsQuicStatusHelper.SuccessfulStatusCode(status)) { diff --git a/src/libraries/Common/src/System/Net/Http/aspnetcore/Quic/Implementations/MsQuic/Internal/ResettableCompletionSource.cs b/src/libraries/Common/src/System/Net/Http/aspnetcore/Quic/Implementations/MsQuic/Internal/ResettableCompletionSource.cs index 4bcf0a9..4164663 100644 --- a/src/libraries/Common/src/System/Net/Http/aspnetcore/Quic/Implementations/MsQuic/Internal/ResettableCompletionSource.cs +++ b/src/libraries/Common/src/System/Net/Http/aspnetcore/Quic/Implementations/MsQuic/Internal/ResettableCompletionSource.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Threading.Tasks; using System.Threading.Tasks.Sources; @@ -35,7 +36,7 @@ namespace System.Net.Quic.Implementations.MsQuic.Internal return _valueTaskSource.GetStatus(token); } - public void OnCompleted(Action continuation, object state, short token, ValueTaskSourceOnCompletedFlags flags) + public void OnCompleted(Action continuation, object? state, short token, ValueTaskSourceOnCompletedFlags flags) { _valueTaskSource.OnCompleted(continuation, state, token, flags); } diff --git a/src/libraries/Common/src/System/Net/Http/aspnetcore/Quic/Implementations/MsQuic/MsQuicConnection.cs b/src/libraries/Common/src/System/Net/Http/aspnetcore/Quic/Implementations/MsQuic/MsQuicConnection.cs index 1d914c2..0fdecc6 100644 --- a/src/libraries/Common/src/System/Net/Http/aspnetcore/Quic/Implementations/MsQuic/MsQuicConnection.cs +++ b/src/libraries/Common/src/System/Net/Http/aspnetcore/Quic/Implementations/MsQuic/MsQuicConnection.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.IO; using System.Net.Quic.Implementations.MsQuic.Internal; using System.Net.Security; @@ -16,7 +17,7 @@ namespace System.Net.Quic.Implementations.MsQuic { internal sealed class MsQuicConnection : QuicConnectionProvider { - private MsQuicSession _session; + private MsQuicSession? _session; // Pointer to the underlying connection // TODO replace all IntPtr with SafeHandles @@ -27,10 +28,10 @@ namespace System.Net.Quic.Implementations.MsQuic // Delegate that wraps the static function that will be called when receiving an event. // TODO investigate if the delegate can be static instead. - private ConnectionCallbackDelegate _connectionDelegate; + private ConnectionCallbackDelegate? _connectionDelegate; // Endpoint to either connect to or the endpoint already accepted. - private IPEndPoint _localEndPoint; + private IPEndPoint? _localEndPoint; private readonly IPEndPoint _remoteEndPoint; private readonly ResettableCompletionSource _connectTcs = new ResettableCompletionSource(); @@ -38,7 +39,7 @@ namespace System.Net.Quic.Implementations.MsQuic private bool _disposed; private bool _connected; - private MsQuicSecurityConfig _securityConfig; + private MsQuicSecurityConfig? _securityConfig; private long _abortErrorCode = -1; // Queue for accepted streams @@ -70,7 +71,7 @@ namespace System.Net.Quic.Implementations.MsQuic // Creating a session per connection isn't ideal. _session = new MsQuicSession(); _ptr = _session.ConnectionOpen(options); - _remoteEndPoint = options.RemoteEndPoint; + _remoteEndPoint = options.RemoteEndPoint!; SetCallbackHandler(); SetIdleTimeout(options.IdleTimeout); @@ -82,15 +83,15 @@ namespace System.Net.Quic.Implementations.MsQuic { get { - return new IPEndPoint(_localEndPoint.Address, _localEndPoint.Port); + return new IPEndPoint(_localEndPoint!.Address, _localEndPoint.Port); } } - internal async ValueTask SetSecurityConfigForConnection(X509Certificate cert, string certFilePath, string privateKeyFilePath) + internal async ValueTask SetSecurityConfigForConnection(X509Certificate cert, string? certFilePath, string? privateKeyFilePath) { _securityConfig = await MsQuicApi.Api.CreateSecurityConfig(cert, certFilePath, privateKeyFilePath); // TODO this isn't being set correctly - MsQuicParameterHelpers.SetSecurityConfig(MsQuicApi.Api, _ptr, (uint)QUIC_PARAM_LEVEL.CONNECTION, (uint)QUIC_PARAM_CONN.SEC_CONFIG, _securityConfig.NativeObjPtr); + MsQuicParameterHelpers.SetSecurityConfig(MsQuicApi.Api, _ptr, (uint)QUIC_PARAM_LEVEL.CONNECTION, (uint)QUIC_PARAM_CONN.SEC_CONFIG, _securityConfig!.NativeObjPtr); } internal override IPEndPoint RemoteEndPoint => new IPEndPoint(_remoteEndPoint.Address, _remoteEndPoint.Port); @@ -355,7 +356,7 @@ namespace System.Net.Quic.Implementations.MsQuic ref ConnectionEvent connectionEventStruct) { GCHandle handle = GCHandle.FromIntPtr(context); - MsQuicConnection quicConnection = (MsQuicConnection)handle.Target; + MsQuicConnection quicConnection = (MsQuicConnection)handle.Target!; return quicConnection.HandleEvent(ref connectionEventStruct); } diff --git a/src/libraries/Common/src/System/Net/Http/aspnetcore/Quic/Implementations/MsQuic/MsQuicListener.cs b/src/libraries/Common/src/System/Net/Http/aspnetcore/Quic/Implementations/MsQuic/MsQuicListener.cs index 14323d9..e87126b 100644 --- a/src/libraries/Common/src/System/Net/Http/aspnetcore/Quic/Implementations/MsQuic/MsQuicListener.cs +++ b/src/libraries/Common/src/System/Net/Http/aspnetcore/Quic/Implementations/MsQuic/MsQuicListener.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Net.Quic.Implementations.MsQuic.Internal; using System.Net.Security; using System.Runtime.InteropServices; @@ -25,7 +26,7 @@ namespace System.Net.Quic.Implementations.MsQuic private GCHandle _handle; // Delegate that wraps the static function that will be called when receiving an event. - private ListenerCallbackDelegate _listenerDelegate; + private ListenerCallbackDelegate? _listenerDelegate; // Ssl listening options (ALPN, cert, etc) private SslServerAuthenticationOptions _sslOptions; @@ -46,8 +47,8 @@ namespace System.Net.Quic.Implementations.MsQuic }); _options = options; - _sslOptions = options.ServerAuthenticationOptions; - _listenEndPoint = options.ListenEndPoint; + _sslOptions = options.ServerAuthenticationOptions!; + _listenEndPoint = options.ListenEndPoint!; _ptr = _session.ListenerOpen(options); } @@ -77,7 +78,7 @@ namespace System.Net.Quic.Implementations.MsQuic throw new QuicOperationAbortedException(); } - await connection.SetSecurityConfigForConnection(_sslOptions.ServerCertificate, + await connection.SetSecurityConfigForConnection(_sslOptions.ServerCertificate!, _options.CertificateFilePath, _options.PrivateKeyFilePath); @@ -187,7 +188,7 @@ namespace System.Net.Quic.Implementations.MsQuic ref ListenerEvent connectionEventStruct) { GCHandle handle = GCHandle.FromIntPtr(context); - MsQuicListener quicListener = (MsQuicListener)handle.Target; + MsQuicListener quicListener = (MsQuicListener)handle.Target!; return quicListener.ListenerCallbackHandler(ref connectionEventStruct); } diff --git a/src/libraries/Common/src/System/Net/Http/aspnetcore/Quic/Implementations/MsQuic/MsQuicStream.cs b/src/libraries/Common/src/System/Net/Http/aspnetcore/Quic/Implementations/MsQuic/MsQuicStream.cs index 00ca779..b8b6282 100644 --- a/src/libraries/Common/src/System/Net/Http/aspnetcore/Quic/Implementations/MsQuic/MsQuicStream.cs +++ b/src/libraries/Common/src/System/Net/Http/aspnetcore/Quic/Implementations/MsQuic/MsQuicStream.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Buffers; using System.Collections.Generic; using System.Diagnostics; @@ -23,7 +24,7 @@ namespace System.Net.Quic.Implementations.MsQuic private GCHandle _handle; // Delegate that wraps the static function that will be called when receiving an event. - private StreamCallbackDelegate _callback; + private StreamCallbackDelegate? _callback; // Backing for StreamId private long _streamId = -1; @@ -424,7 +425,7 @@ namespace System.Net.Quic.Implementations.MsQuic { ThrowIfDisposed(); - return default; + return default!; } public override ValueTask DisposeAsync() @@ -500,7 +501,7 @@ namespace System.Net.Quic.Implementations.MsQuic ref StreamEvent streamEvent) { var handle = GCHandle.FromIntPtr(context); - var quicStream = (MsQuicStream)handle.Target; + var quicStream = (MsQuicStream)handle.Target!; return quicStream.HandleEvent(ref streamEvent); } diff --git a/src/libraries/Common/src/System/Net/Http/aspnetcore/Quic/Interop/MsQuicNativeMethods.cs b/src/libraries/Common/src/System/Net/Http/aspnetcore/Quic/Interop/MsQuicNativeMethods.cs index 6f7edba..31ab416 100644 --- a/src/libraries/Common/src/System/Net/Http/aspnetcore/Quic/Interop/MsQuicNativeMethods.cs +++ b/src/libraries/Common/src/System/Net/Http/aspnetcore/Quic/Interop/MsQuicNativeMethods.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Net.Sockets; using System.Runtime.InteropServices; using System.Text; @@ -90,7 +91,7 @@ namespace System.Net.Quic.Implementations.MsQuic.Internal IntPtr registrationContext, uint flags, IntPtr certificate, - [MarshalAs(UnmanagedType.LPStr)]string principal, + [MarshalAs(UnmanagedType.LPStr)]string? principal, IntPtr context, SecConfigCreateCompleteDelegate completionHandler); diff --git a/src/libraries/Common/src/System/Net/Http/aspnetcore/Quic/QuicClientConnectionOptions.cs b/src/libraries/Common/src/System/Net/Http/aspnetcore/Quic/QuicClientConnectionOptions.cs index a9a9b0e..3e7d10a 100644 --- a/src/libraries/Common/src/System/Net/Http/aspnetcore/Quic/QuicClientConnectionOptions.cs +++ b/src/libraries/Common/src/System/Net/Http/aspnetcore/Quic/QuicClientConnectionOptions.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Net.Security; namespace System.Net.Quic @@ -14,17 +15,17 @@ namespace System.Net.Quic /// /// Client authentication options to use when establishing a . /// - public SslClientAuthenticationOptions ClientAuthenticationOptions { get; set; } + public SslClientAuthenticationOptions? ClientAuthenticationOptions { get; set; } /// /// The local endpoint that will be bound to. /// - public IPEndPoint LocalEndPoint { get; set; } + public IPEndPoint? LocalEndPoint { get; set; } /// /// The endpoint to connect to. /// - public IPEndPoint RemoteEndPoint { get; set; } + public IPEndPoint? RemoteEndPoint { get; set; } /// /// Limit on the number of bidirectional streams the peer connection can create diff --git a/src/libraries/Common/src/System/Net/Http/aspnetcore/Quic/QuicConnection.cs b/src/libraries/Common/src/System/Net/Http/aspnetcore/Quic/QuicConnection.cs index 877421a..c2bbceb 100644 --- a/src/libraries/Common/src/System/Net/Http/aspnetcore/Quic/QuicConnection.cs +++ b/src/libraries/Common/src/System/Net/Http/aspnetcore/Quic/QuicConnection.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Net.Quic.Implementations; using System.Net.Quic.Implementations.MsQuic.Internal; using System.Net.Security; @@ -22,13 +23,13 @@ namespace System.Net.Quic /// The remote endpoint to connect to. /// TLS options /// The local endpoint to connect from. - public QuicConnection(IPEndPoint remoteEndPoint, SslClientAuthenticationOptions sslClientAuthenticationOptions, IPEndPoint localEndPoint = null) + public QuicConnection(IPEndPoint remoteEndPoint, SslClientAuthenticationOptions? sslClientAuthenticationOptions, IPEndPoint? localEndPoint = null) : this(QuicImplementationProviders.Default, remoteEndPoint, sslClientAuthenticationOptions, localEndPoint) { } // !!! TEMPORARY: Remove "implementationProvider" before shipping - public QuicConnection(QuicImplementationProvider implementationProvider, IPEndPoint remoteEndPoint, SslClientAuthenticationOptions sslClientAuthenticationOptions, IPEndPoint localEndPoint = null) + public QuicConnection(QuicImplementationProvider implementationProvider, IPEndPoint remoteEndPoint, SslClientAuthenticationOptions? sslClientAuthenticationOptions, IPEndPoint? localEndPoint = null) : this(implementationProvider, new QuicClientConnectionOptions() { RemoteEndPoint = remoteEndPoint, ClientAuthenticationOptions = sslClientAuthenticationOptions, LocalEndPoint = localEndPoint }) { } diff --git a/src/libraries/Common/src/System/Net/Http/aspnetcore/Quic/QuicListenerOptions.cs b/src/libraries/Common/src/System/Net/Http/aspnetcore/Quic/QuicListenerOptions.cs index f9eae30..934c7a8 100644 --- a/src/libraries/Common/src/System/Net/Http/aspnetcore/Quic/QuicListenerOptions.cs +++ b/src/libraries/Common/src/System/Net/Http/aspnetcore/Quic/QuicListenerOptions.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Net.Security; namespace System.Net.Quic @@ -14,22 +15,22 @@ namespace System.Net.Quic /// /// Server Ssl options to use for ALPN, SNI, etc. /// - public SslServerAuthenticationOptions ServerAuthenticationOptions { get; set; } + public SslServerAuthenticationOptions? ServerAuthenticationOptions { get; set; } /// /// Optional path to certificate file to configure the security configuration. /// - public string CertificateFilePath { get; set; } + public string? CertificateFilePath { get; set; } /// /// Optional path to private key file to configure the security configuration. /// - public string PrivateKeyFilePath { get; set; } + public string? PrivateKeyFilePath { get; set; } /// /// The endpoint to listen on. /// - public IPEndPoint ListenEndPoint { get; set; } + public IPEndPoint? ListenEndPoint { get; set; } /// /// Number of connections to be held without accepting the connection. diff --git a/src/libraries/Common/src/System/Net/Http/aspnetcore/Quic/QuicStream.cs b/src/libraries/Common/src/System/Net/Http/aspnetcore/Quic/QuicStream.cs index 6e52bb0..4e1af6d 100644 --- a/src/libraries/Common/src/System/Net/Http/aspnetcore/Quic/QuicStream.cs +++ b/src/libraries/Common/src/System/Net/Http/aspnetcore/Quic/QuicStream.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Buffers; using System.IO; using System.Net.Quic.Implementations; @@ -29,13 +30,13 @@ namespace System.Net.Quic public override void SetLength(long value) => throw new NotSupportedException(); public override long Position { get => throw new NotSupportedException(); set => throw new NotSupportedException(); } - public override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback callback, object state) => + public override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback? callback, object? state) => TaskToApm.Begin(ReadAsync(buffer, offset, count, default), callback, state); public override int EndRead(IAsyncResult asyncResult) => TaskToApm.End(asyncResult); - public override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback callback, object state) => + public override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback? callback, object? state) => TaskToApm.Begin(WriteAsync(buffer, offset, count, default), callback, state); public override void EndWrite(IAsyncResult asyncResult) => diff --git a/src/libraries/Common/src/System/Net/HttpKnownHeaderNames.TryGetHeaderName.cs b/src/libraries/Common/src/System/Net/HttpKnownHeaderNames.TryGetHeaderName.cs index 22c3cc7..b96dbd0 100644 --- a/src/libraries/Common/src/System/Net/HttpKnownHeaderNames.TryGetHeaderName.cs +++ b/src/libraries/Common/src/System/Net/HttpKnownHeaderNames.TryGetHeaderName.cs @@ -2,7 +2,9 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; namespace System.Net { @@ -15,7 +17,7 @@ namespace System.Net /// Gets a known header name string from a matching char[] array segment, using a case-sensitive /// ordinal comparison. Used to avoid allocating new strings for known header names. /// - public static bool TryGetHeaderName(char[] array, int startIndex, int length, out string name) + public static bool TryGetHeaderName(char[] array, int startIndex, int length, [NotNullWhen(true)] out string? name) { CharArrayHelpers.DebugAssertArrayInputs(array, startIndex, length); @@ -30,7 +32,7 @@ namespace System.Net /// Gets a known header name string from a matching IntPtr buffer, using a case-sensitive /// ordinal comparison. Used to avoid allocating new strings for known header names. /// - public static unsafe bool TryGetHeaderName(IntPtr buffer, int length, out string name) + public static unsafe bool TryGetHeaderName(IntPtr buffer, int length, out string? name) { Debug.Assert(length >= 0); @@ -84,7 +86,7 @@ namespace System.Net T key, int startIndex, int length, Func charAt, Func equals, - out string name) + [NotNullWhen(true)] out string? name) { Debug.Assert(key != null); Debug.Assert(startIndex >= 0); @@ -110,7 +112,7 @@ namespace System.Net // // Matching is case-sensitive: we only want to return a known header that exactly matches the key. - string potentialHeader = null; + string potentialHeader; switch (length) { @@ -340,7 +342,7 @@ namespace System.Net /// Returns true if matches the char[] array segment, /// using an ordinal comparison. /// - private static bool TryMatch(string known, T key, int startIndex, int length, Func equals, out string name) + private static bool TryMatch(string known, T key, int startIndex, int length, Func equals, [NotNullWhen(true)] out string? name) { Debug.Assert(known != null); Debug.Assert(known.Length > 0); diff --git a/src/libraries/Common/src/System/Net/HttpStatusDescription.cs b/src/libraries/Common/src/System/Net/HttpStatusDescription.cs index dc13fd0..809cffd 100644 --- a/src/libraries/Common/src/System/Net/HttpStatusDescription.cs +++ b/src/libraries/Common/src/System/Net/HttpStatusDescription.cs @@ -2,14 +2,15 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable namespace System.Net { internal static class HttpStatusDescription { - internal static string Get(HttpStatusCode code) => + internal static string? Get(HttpStatusCode code) => Get((int)code); - internal static string Get(int code) => + internal static string? Get(int code) => code switch { 100 => "Continue", diff --git a/src/libraries/Common/src/System/Net/Logging/NetEventSource.Common.cs b/src/libraries/Common/src/System/Net/Logging/NetEventSource.Common.cs index 29abfe2..f476d85 100644 --- a/src/libraries/Common/src/System/Net/Logging/NetEventSource.Common.cs +++ b/src/libraries/Common/src/System/Net/Logging/NetEventSource.Common.cs @@ -424,7 +424,7 @@ namespace System.Net public static string IdOf(object? value) => value != null ? value.GetType().Name + "#" + GetHashCode(value) : NullInstance; [NonEvent] - public static int GetHashCode(object value) => value?.GetHashCode() ?? 0; + public static int GetHashCode(object? value) => value?.GetHashCode() ?? 0; [NonEvent] public static object Format(object? value) diff --git a/src/libraries/Common/src/System/Net/Mail/MailAddress.cs b/src/libraries/Common/src/System/Net/Mail/MailAddress.cs index 6c61c58..c2a9430 100644 --- a/src/libraries/Common/src/System/Net/Mail/MailAddress.cs +++ b/src/libraries/Common/src/System/Net/Mail/MailAddress.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Text; namespace System.Net.Mail @@ -13,7 +14,7 @@ namespace System.Net.Mail MailAddressParser.TryParseAddress(address, out ParseAddressInfo _, throwExceptionIfFail: true); } - internal MailAddress(string displayName, string localPart, string domain, Encoding displayNameEncoding) + internal MailAddress(string displayName, string localPart, string domain, Encoding? displayNameEncoding) { } } diff --git a/src/libraries/Common/src/System/Net/Mail/MailAddressParser.cs b/src/libraries/Common/src/System/Net/Mail/MailAddressParser.cs index 6b1e8e5..896cb03 100644 --- a/src/libraries/Common/src/System/Net/Mail/MailAddressParser.cs +++ b/src/libraries/Common/src/System/Net/Mail/MailAddressParser.cs @@ -2,8 +2,10 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Collections.Generic; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Net.Mime; namespace System.Net.Mail @@ -69,7 +71,7 @@ namespace System.Net.Mail Debug.Assert(index >= 0 && index < data.Length, "Index out of range: " + index + ", " + data.Length); // Parsed components to be assembled as a MailAddress later - string displayName; + string? displayName; // Skip comments and whitespace if (!TryReadCfwsAndThrowIfIncomplete(data, index, out index, throwExceptionIfFail)) @@ -87,7 +89,7 @@ namespace System.Net.Mail index--; } - if (!TryParseDomain(data, ref index, out string domain, throwExceptionIfFail)) + if (!TryParseDomain(data, ref index, out string? domain, throwExceptionIfFail)) { parseAddressInfo = default; return false; @@ -110,7 +112,7 @@ namespace System.Net.Mail // Skip the '@' symbol index--; - if (!TryParseLocalPart(data, ref index, expectAngleBracket, expectMultipleAddresses, out string localPart, throwExceptionIfFail)) + if (!TryParseLocalPart(data, ref index, expectAngleBracket, expectMultipleAddresses, out string? localPart, throwExceptionIfFail)) { parseAddressInfo = default; return false; @@ -206,7 +208,7 @@ namespace System.Net.Mail // Throws a FormatException or returns false: // - For invalid un-escaped chars, including Unicode // - If the start of the data string is reached - private static bool TryParseDomain(string data, ref int index, out string domain, bool throwExceptionIfFail) + private static bool TryParseDomain(string data, ref int index, [NotNullWhen(true)] out string? domain, bool throwExceptionIfFail) { // Skip comments and whitespace if (!TryReadCfwsAndThrowIfIncomplete(data, index, out index, throwExceptionIfFail)) @@ -268,7 +270,7 @@ namespace System.Net.Mail // - For invalid un-escaped chars, including Unicode // - If the final value of data[index] is not a valid character to precede the local-part private static bool TryParseLocalPart(string data, ref int index, bool expectAngleBracket, - bool expectMultipleAddresses, out string localPart, bool throwExceptionIfFail) + bool expectMultipleAddresses, [NotNullWhen(true)] out string? localPart, bool throwExceptionIfFail) { // Skip comments and whitespace if (!TryReadCfwsAndThrowIfIncomplete(data, index, out index, throwExceptionIfFail)) @@ -354,7 +356,7 @@ namespace System.Net.Mail // Throws a FormatException or false is returned: // - For invalid un-escaped chars, except Unicode // - If the postconditions cannot be met. - private static bool TryParseDisplayName(string data, ref int index, bool expectMultipleAddresses, out string displayName, bool throwExceptionIfFail) + private static bool TryParseDisplayName(string data, ref int index, bool expectMultipleAddresses, [NotNullWhen(true)] out string? displayName, bool throwExceptionIfFail) { // Whatever is left over must be the display name. The display name should be a single word/atom or a // quoted string, but for robustness we allow the quotes to be omitted, so long as we can find the comma @@ -432,7 +434,7 @@ namespace System.Net.Mail return true; } - internal static bool TryNormalizeOrThrow(string input, out string normalizedString, bool throwExceptionIfFail) + internal static bool TryNormalizeOrThrow(string input, [NotNullWhen(true)] out string? normalizedString, bool throwExceptionIfFail) { try { diff --git a/src/libraries/Common/src/System/Net/Mail/MailBnfHelper.cs b/src/libraries/Common/src/System/Net/Mail/MailBnfHelper.cs index 1137a44..bd368ce 100644 --- a/src/libraries/Common/src/System/Net/Mail/MailBnfHelper.cs +++ b/src/libraries/Common/src/System/Net/Mail/MailBnfHelper.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Diagnostics; using System.Text; @@ -189,12 +190,12 @@ namespace System.Net.Mime throw new FormatException(SR.InvalidHeaderName); } - internal static string ReadQuotedString(string data, ref int offset, StringBuilder builder) + internal static string? ReadQuotedString(string data, ref int offset, StringBuilder builder) { return ReadQuotedString(data, ref offset, builder, false, false); } - internal static string ReadQuotedString(string data, ref int offset, StringBuilder builder, bool doesntRequireQuotes, bool permitUnicodeInDisplayName) + internal static string? ReadQuotedString(string data, ref int offset, StringBuilder? builder, bool doesntRequireQuotes, bool permitUnicodeInDisplayName) { // assume first char is the opening quote if (!doesntRequireQuotes) @@ -246,7 +247,7 @@ namespace System.Net.Mime throw new FormatException(SR.MailHeaderFieldMalformedHeader); } - internal static string ReadParameterAttribute(string data, ref int offset, StringBuilder builder) + internal static string? ReadParameterAttribute(string data, ref int offset, StringBuilder builder) { if (!SkipCFWS(data, ref offset)) return null; // @@ -254,7 +255,7 @@ namespace System.Net.Mime return ReadToken(data, ref offset, null); } - internal static string ReadToken(string data, ref int offset, StringBuilder builder) + internal static string ReadToken(string data, ref int offset, StringBuilder? builder) { int start = offset; for (; offset < data.Length; offset++) @@ -277,9 +278,9 @@ namespace System.Net.Mime return data.Substring(start, offset - start); } - private static readonly string[] s_months = new string[] { null, "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; + private static readonly string?[] s_months = new string?[] { null, "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; - internal static string GetDateTimeString(DateTime value, StringBuilder builder) + internal static string? GetDateTimeString(DateTime value, StringBuilder? builder) { StringBuilder localBuilder = (builder != null ? builder : new StringBuilder()); localBuilder.Append(value.Day); diff --git a/src/libraries/Common/src/System/Net/NTAuthentication.Common.cs b/src/libraries/Common/src/System/Net/NTAuthentication.Common.cs index 03a98ef..839c96f 100644 --- a/src/libraries/Common/src/System/Net/NTAuthentication.Common.cs +++ b/src/libraries/Common/src/System/Net/NTAuthentication.Common.cs @@ -28,7 +28,7 @@ namespace System.Net private string? _protocolName; private string? _clientSpecifiedSpn; - private ChannelBinding _channelBinding = null!; + private ChannelBinding? _channelBinding = null; // If set, no more calls should be made. internal bool IsCompleted => _isCompleted; @@ -92,12 +92,12 @@ namespace System.Net // // This overload does not attempt to impersonate because the caller either did it already or the original thread context is still preserved. // - internal NTAuthentication(bool isServer, string package, NetworkCredential credential, string spn, ContextFlagsPal requestedContextFlags, ChannelBinding channelBinding) + internal NTAuthentication(bool isServer, string package, NetworkCredential credential, string spn, ContextFlagsPal requestedContextFlags, ChannelBinding? channelBinding) { Initialize(isServer, package, credential, spn, requestedContextFlags, channelBinding); } - private void Initialize(bool isServer, string package, NetworkCredential credential, string spn, ContextFlagsPal requestedContextFlags, ChannelBinding channelBinding) + private void Initialize(bool isServer, string package, NetworkCredential credential, string spn, ContextFlagsPal requestedContextFlags, ChannelBinding? channelBinding) { if (NetEventSource.IsEnabled) NetEventSource.Enter(this, package, spn, requestedContextFlags); @@ -167,7 +167,7 @@ namespace System.Net return NegotiateStreamPal.MakeSignature(_securityContext!, buffer, offset, count, ref output); } - internal string? GetOutgoingBlob(string incomingBlob) + internal string? GetOutgoingBlob(string? incomingBlob) { byte[]? decodedIncomingBlob = null; if (incomingBlob != null && incomingBlob.Length > 0) diff --git a/src/libraries/Common/src/System/Net/Security/CertificateHelper.Unix.cs b/src/libraries/Common/src/System/Net/Security/CertificateHelper.Unix.cs index 1120a04..d69563e 100644 --- a/src/libraries/Common/src/System/Net/Security/CertificateHelper.Unix.cs +++ b/src/libraries/Common/src/System/Net/Security/CertificateHelper.Unix.cs @@ -8,7 +8,7 @@ namespace System.Net.Security { internal static partial class CertificateHelper { - internal static X509Certificate2 GetEligibleClientCertificate() + internal static X509Certificate2? GetEligibleClientCertificate() { // Get initial list of client certificates from the MY store. X509Certificate2Collection candidateCerts; diff --git a/src/libraries/Common/src/System/Net/Security/CertificateHelper.Windows.cs b/src/libraries/Common/src/System/Net/Security/CertificateHelper.Windows.cs index 7bb5d10..fcb49a0 100644 --- a/src/libraries/Common/src/System/Net/Security/CertificateHelper.Windows.cs +++ b/src/libraries/Common/src/System/Net/Security/CertificateHelper.Windows.cs @@ -2,13 +2,14 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Security.Cryptography.X509Certificates; namespace System.Net.Security { internal static partial class CertificateHelper { - internal static X509Certificate2 GetEligibleClientCertificate() + internal static X509Certificate2? GetEligibleClientCertificate() { // Get initial list of client certificates from the MY store. X509Certificate2Collection candidateCerts; diff --git a/src/libraries/Common/src/System/Net/Security/CertificateHelper.cs b/src/libraries/Common/src/System/Net/Security/CertificateHelper.cs index 84ab203..30c8f93 100644 --- a/src/libraries/Common/src/System/Net/Security/CertificateHelper.cs +++ b/src/libraries/Common/src/System/Net/Security/CertificateHelper.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using Microsoft.Win32.SafeHandles; using System.Diagnostics; using System.Globalization; @@ -14,7 +15,7 @@ namespace System.Net.Security { private const string ClientAuthenticationOID = "1.3.6.1.5.5.7.3.2"; - internal static X509Certificate2 GetEligibleClientCertificate(X509CertificateCollection candidateCerts) + internal static X509Certificate2? GetEligibleClientCertificate(X509CertificateCollection candidateCerts) { if (candidateCerts.Count == 0) { @@ -27,7 +28,7 @@ namespace System.Net.Security return GetEligibleClientCertificate(certs); } - internal static X509Certificate2 GetEligibleClientCertificate(X509Certificate2Collection candidateCerts) + internal static X509Certificate2? GetEligibleClientCertificate(X509Certificate2Collection candidateCerts) { if (candidateCerts.Count == 0) { diff --git a/src/libraries/Common/src/System/Net/Security/NegotiateStreamPal.Unix.cs b/src/libraries/Common/src/System/Net/Security/NegotiateStreamPal.Unix.cs index 1fdcd69..441706c 100644 --- a/src/libraries/Common/src/System/Net/Security/NegotiateStreamPal.Unix.cs +++ b/src/libraries/Common/src/System/Net/Security/NegotiateStreamPal.Unix.cs @@ -100,7 +100,7 @@ namespace System.Net.Security ref SafeGssContextHandle? context, SafeGssCredHandle credential, bool isNtlm, - ChannelBinding channelBinding, + ChannelBinding? channelBinding, SafeGssNameHandle? targetName, Interop.NetSecurityNative.GssFlags inFlags, byte[]? buffer, @@ -279,7 +279,7 @@ namespace System.Net.Security private static SecurityStatusPal EstablishSecurityContext( SafeFreeNegoCredentials credential, ref SafeDeleteContext? context, - ChannelBinding channelBinding, + ChannelBinding? channelBinding, string targetName, ContextFlagsPal inFlags, byte[]? incomingBlob, @@ -361,7 +361,7 @@ namespace System.Net.Security string spn, ContextFlagsPal requestedContextFlags, byte[]? incomingBlob, - ChannelBinding channelBinding, + ChannelBinding? channelBinding, ref byte[]? resultBlob, ref ContextFlagsPal contextFlags) { @@ -400,7 +400,7 @@ namespace System.Net.Security ref SafeDeleteContext? securityContext, ContextFlagsPal requestedContextFlags, byte[]? incomingBlob, - ChannelBinding channelBinding, + ChannelBinding? channelBinding, ref byte[] resultBlob, ref ContextFlagsPal contextFlags) { diff --git a/src/libraries/Common/src/System/Net/Security/NegotiateStreamPal.Windows.cs b/src/libraries/Common/src/System/Net/Security/NegotiateStreamPal.Windows.cs index a1f306e..56a8793 100644 --- a/src/libraries/Common/src/System/Net/Security/NegotiateStreamPal.Windows.cs +++ b/src/libraries/Common/src/System/Net/Security/NegotiateStreamPal.Windows.cs @@ -77,7 +77,7 @@ namespace System.Net.Security string spn, ContextFlagsPal requestedContextFlags, byte[]? incomingBlob, - ChannelBinding channelBinding, + ChannelBinding? channelBinding, ref byte[]? resultBlob, ref ContextFlagsPal contextFlags) { @@ -134,7 +134,7 @@ namespace System.Net.Security ref SafeDeleteContext? securityContext, ContextFlagsPal requestedContextFlags, byte[]? incomingBlob, - ChannelBinding channelBinding, + ChannelBinding? channelBinding, ref byte[]? resultBlob, ref ContextFlagsPal contextFlags) { diff --git a/src/libraries/Common/src/System/Net/Security/SslClientAuthenticationOptionsExtensions.cs b/src/libraries/Common/src/System/Net/Security/SslClientAuthenticationOptionsExtensions.cs index 6b33d10..fcc2fb9 100644 --- a/src/libraries/Common/src/System/Net/Security/SslClientAuthenticationOptionsExtensions.cs +++ b/src/libraries/Common/src/System/Net/Security/SslClientAuthenticationOptionsExtensions.cs @@ -33,12 +33,12 @@ namespace System.Net.Security // Try to detect if a property gets added that we're not copying correctly. foreach (PropertyInfo pi in options.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly)) { - object origValue = pi.GetValue(options); - object cloneValue = pi.GetValue(clone); + object? origValue = pi.GetValue(options); + object? cloneValue = pi.GetValue(clone); if (origValue is IEnumerable origEnumerable) { - IEnumerable cloneEnumerable = cloneValue as IEnumerable; + IEnumerable? cloneEnumerable = cloneValue as IEnumerable; Debug.Assert(cloneEnumerable != null, $"{pi.Name}. Expected enumerable cloned value."); IEnumerator e1 = origEnumerable.GetEnumerator(); diff --git a/src/libraries/Common/src/System/Runtime/ExceptionServices/ExceptionStackTrace.cs b/src/libraries/Common/src/System/Runtime/ExceptionServices/ExceptionStackTrace.cs index c8b633c..57647f3 100644 --- a/src/libraries/Common/src/System/Runtime/ExceptionServices/ExceptionStackTrace.cs +++ b/src/libraries/Common/src/System/Runtime/ExceptionServices/ExceptionStackTrace.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Diagnostics; using System.Reflection; @@ -16,12 +17,12 @@ namespace System.Runtime.ExceptionServices Debug.Assert(exception != null, "Expected non-null Exception"); const string ExceptionRemoteStackTraceStringName = "_remoteStackTraceString"; - FieldInfo fi = typeof(Exception).GetField(ExceptionRemoteStackTraceStringName, BindingFlags.NonPublic | BindingFlags.Instance); + FieldInfo? fi = typeof(Exception).GetField(ExceptionRemoteStackTraceStringName, BindingFlags.NonPublic | BindingFlags.Instance); if (fi != null) { string text = - (string)fi.GetValue(exception) + + (string?)fi.GetValue(exception) + Environment.StackTrace + Environment.NewLine + "--- End of stack trace from AddCurrentStack ---" + Environment.NewLine; fi.SetValue(exception, text); diff --git a/src/libraries/Common/src/System/StrongToWeakReference.cs b/src/libraries/Common/src/System/StrongToWeakReference.cs index f49a9f1..83dfd05 100644 --- a/src/libraries/Common/src/System/StrongToWeakReference.cs +++ b/src/libraries/Common/src/System/StrongToWeakReference.cs @@ -9,7 +9,7 @@ namespace System /// Provides an object wrapper that can transition between strong and weak references to the object. internal sealed class StrongToWeakReference : WeakReference where T : class { - private T _strongRef; + private T? _strongRef; /// Initializes the instance with a strong reference to the specified object. /// The object to wrap. @@ -30,9 +30,9 @@ namespace System } /// Gets the wrapped object. - public new T Target => _strongRef ?? WeakTarget; + public new T? Target => _strongRef ?? WeakTarget; /// Gets the wrapped object via its weak reference. - private T WeakTarget => base.Target as T; + private T? WeakTarget => base.Target as T; } } diff --git a/src/libraries/Common/src/System/Threading/Tasks/RendezvousAwaitable.cs b/src/libraries/Common/src/System/Threading/Tasks/RendezvousAwaitable.cs index 8413488..890c1ab 100644 --- a/src/libraries/Common/src/System/Threading/Tasks/RendezvousAwaitable.cs +++ b/src/libraries/Common/src/System/Threading/Tasks/RendezvousAwaitable.cs @@ -2,7 +2,9 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Runtime.CompilerServices; using System.Runtime.ExceptionServices; @@ -19,11 +21,11 @@ namespace System.Threading.Tasks /// The continuation to invoke when the operation completes, or if the operation /// has completed before OnCompleted is called. /// - private Action _continuation; + private Action? _continuation; /// The exception representing the failed async operation, if it failed. - private ExceptionDispatchInfo _error; + private ExceptionDispatchInfo? _error; /// The result of the async operation, if it succeeded. - private TResult _result; + [AllowNull] private TResult _result = default; #if DEBUG private bool _resultSet; #endif @@ -39,7 +41,7 @@ namespace System.Threading.Tasks { get { - Action c = Volatile.Read(ref _continuation); + Action? c = Volatile.Read(ref _continuation); Debug.Assert(c == null || c == s_completionSentinel); return c != null; } @@ -55,7 +57,7 @@ namespace System.Threading.Tasks // Propagate any error if there is one, clearing it out first to prepare for reuse. // We don't need to clear a result, as result and error are mutually exclusive. - ExceptionDispatchInfo error = _error; + ExceptionDispatchInfo? error = _error; if (error != null) { _error = null; @@ -101,7 +103,7 @@ namespace System.Threading.Tasks /// Alerts any awaiter that the operation has completed. private void NotifyAwaiter() { - Action c = _continuation ?? Interlocked.CompareExchange(ref _continuation, s_completionSentinel, null); + Action? c = _continuation ?? Interlocked.CompareExchange(ref _continuation, s_completionSentinel, null); if (c != null) { Debug.Assert(c != s_completionSentinel); @@ -122,7 +124,7 @@ namespace System.Threading.Tasks { Debug.Assert(continuation != null); - Action c = _continuation ?? Interlocked.CompareExchange(ref _continuation, continuation, null); + Action? c = _continuation ?? Interlocked.CompareExchange(ref _continuation, continuation, null); if (c != null) { Debug.Assert(c == s_completionSentinel); diff --git a/src/libraries/Common/tests/Common.Tests.csproj b/src/libraries/Common/tests/Common.Tests.csproj index 85bcb69..18a311e 100644 --- a/src/libraries/Common/tests/Common.Tests.csproj +++ b/src/libraries/Common/tests/Common.Tests.csproj @@ -4,6 +4,7 @@ false true $(NetCoreAppCurrent)-Windows_NT;$(NetCoreAppCurrent)-Linux;$(NetCoreAppCurrent)-OSX + annotations diff --git a/src/libraries/System.Net.Http.WinHttpHandler/src/System.Net.Http.WinHttpHandler.csproj b/src/libraries/System.Net.Http.WinHttpHandler/src/System.Net.Http.WinHttpHandler.csproj index e4c330f..c402b8d 100644 --- a/src/libraries/System.Net.Http.WinHttpHandler/src/System.Net.Http.WinHttpHandler.csproj +++ b/src/libraries/System.Net.Http.WinHttpHandler/src/System.Net.Http.WinHttpHandler.csproj @@ -7,6 +7,7 @@ true true $(DefineConstants);WINHTTPHANDLER_DLL + annotations diff --git a/src/libraries/System.Net.Http.WinHttpHandler/tests/UnitTests/System.Net.Http.WinHttpHandler.Unit.Tests.csproj b/src/libraries/System.Net.Http.WinHttpHandler/tests/UnitTests/System.Net.Http.WinHttpHandler.Unit.Tests.csproj index 4ed356e..9d1e3ba 100644 --- a/src/libraries/System.Net.Http.WinHttpHandler/tests/UnitTests/System.Net.Http.WinHttpHandler.Unit.Tests.csproj +++ b/src/libraries/System.Net.Http.WinHttpHandler/tests/UnitTests/System.Net.Http.WinHttpHandler.Unit.Tests.csproj @@ -5,6 +5,7 @@ ../../src/Resources/Strings.resx $(NetCoreAppCurrent)-Windows_NT $(DefineConstants);WINHTTPHANDLER_DLL + annotations diff --git a/src/libraries/System.Net.Http/ref/System.Net.Http.cs b/src/libraries/System.Net.Http/ref/System.Net.Http.cs index b1c02bb..1b6630a 100644 --- a/src/libraries/System.Net.Http/ref/System.Net.Http.cs +++ b/src/libraries/System.Net.Http/ref/System.Net.Http.cs @@ -12,8 +12,8 @@ namespace System.Net.Http public ByteArrayContent(byte[] content) { } public ByteArrayContent(byte[] content, int offset, int count) { } protected override System.Threading.Tasks.Task CreateContentReadStreamAsync() { throw null; } - protected override System.Threading.Tasks.Task SerializeToStreamAsync(System.IO.Stream stream, System.Net.TransportContext context) { throw null; } - protected override System.Threading.Tasks.Task SerializeToStreamAsync(System.IO.Stream stream, System.Net.TransportContext context, System.Threading.CancellationToken cancellationToken) { throw null; } + protected override System.Threading.Tasks.Task SerializeToStreamAsync(System.IO.Stream stream, System.Net.TransportContext? context) { throw null; } + protected override System.Threading.Tasks.Task SerializeToStreamAsync(System.IO.Stream stream, System.Net.TransportContext? context, System.Threading.CancellationToken cancellationToken) { throw null; } protected internal override bool TryComputeLength(out long length) { throw null; } } public enum ClientCertificateOption @@ -25,64 +25,65 @@ namespace System.Net.Http { protected DelegatingHandler() { } protected DelegatingHandler(System.Net.Http.HttpMessageHandler innerHandler) { } - public System.Net.Http.HttpMessageHandler InnerHandler { get { throw null; } set { } } + [System.Diagnostics.CodeAnalysis.DisallowNullAttribute] + public System.Net.Http.HttpMessageHandler? InnerHandler { get { throw null; } set { } } protected override void Dispose(bool disposing) { } protected internal override System.Threading.Tasks.Task SendAsync(System.Net.Http.HttpRequestMessage request, System.Threading.CancellationToken cancellationToken) { throw null; } } public partial class FormUrlEncodedContent : System.Net.Http.ByteArrayContent { - public FormUrlEncodedContent(System.Collections.Generic.IEnumerable> nameValueCollection) : base (default(byte[])) { } - protected override System.Threading.Tasks.Task SerializeToStreamAsync(System.IO.Stream stream, System.Net.TransportContext context, System.Threading.CancellationToken cancellationToken) { throw null; } + public FormUrlEncodedContent(System.Collections.Generic.IEnumerable> nameValueCollection) : base (default(byte[])) { } + protected override System.Threading.Tasks.Task SerializeToStreamAsync(System.IO.Stream stream, System.Net.TransportContext? context, System.Threading.CancellationToken cancellationToken) { throw null; } } public partial class HttpClient : System.Net.Http.HttpMessageInvoker { public HttpClient() : base (default(System.Net.Http.HttpMessageHandler)) { } public HttpClient(System.Net.Http.HttpMessageHandler handler) : base (default(System.Net.Http.HttpMessageHandler)) { } public HttpClient(System.Net.Http.HttpMessageHandler handler, bool disposeHandler) : base (default(System.Net.Http.HttpMessageHandler)) { } - public System.Uri BaseAddress { get { throw null; } set { } } + public System.Uri? BaseAddress { get { throw null; } set { } } public static System.Net.IWebProxy DefaultProxy { get { throw null; } set { } } public System.Net.Http.Headers.HttpRequestHeaders DefaultRequestHeaders { get { throw null; } } public System.Version DefaultRequestVersion { get { throw null; } set { } } public long MaxResponseContentBufferSize { get { throw null; } set { } } public System.TimeSpan Timeout { get { throw null; } set { } } public void CancelPendingRequests() { } - public System.Threading.Tasks.Task DeleteAsync(string requestUri) { throw null; } - public System.Threading.Tasks.Task DeleteAsync(string requestUri, System.Threading.CancellationToken cancellationToken) { throw null; } - public System.Threading.Tasks.Task DeleteAsync(System.Uri requestUri) { throw null; } - public System.Threading.Tasks.Task DeleteAsync(System.Uri requestUri, System.Threading.CancellationToken cancellationToken) { throw null; } + public System.Threading.Tasks.Task DeleteAsync(string? requestUri) { throw null; } + public System.Threading.Tasks.Task DeleteAsync(string? requestUri, System.Threading.CancellationToken cancellationToken) { throw null; } + public System.Threading.Tasks.Task DeleteAsync(System.Uri? requestUri) { throw null; } + public System.Threading.Tasks.Task DeleteAsync(System.Uri? requestUri, System.Threading.CancellationToken cancellationToken) { throw null; } protected override void Dispose(bool disposing) { } - public System.Threading.Tasks.Task GetAsync(string requestUri) { throw null; } - public System.Threading.Tasks.Task GetAsync(string requestUri, System.Net.Http.HttpCompletionOption completionOption) { throw null; } - public System.Threading.Tasks.Task GetAsync(string requestUri, System.Net.Http.HttpCompletionOption completionOption, System.Threading.CancellationToken cancellationToken) { throw null; } - public System.Threading.Tasks.Task GetAsync(string requestUri, System.Threading.CancellationToken cancellationToken) { throw null; } - public System.Threading.Tasks.Task GetAsync(System.Uri requestUri) { throw null; } - public System.Threading.Tasks.Task GetAsync(System.Uri requestUri, System.Net.Http.HttpCompletionOption completionOption) { throw null; } - public System.Threading.Tasks.Task GetAsync(System.Uri requestUri, System.Net.Http.HttpCompletionOption completionOption, System.Threading.CancellationToken cancellationToken) { throw null; } - public System.Threading.Tasks.Task GetAsync(System.Uri requestUri, System.Threading.CancellationToken cancellationToken) { throw null; } - public System.Threading.Tasks.Task GetByteArrayAsync(string requestUri) { throw null; } - public System.Threading.Tasks.Task GetByteArrayAsync(string requestUri, System.Threading.CancellationToken cancellationToken) { throw null; } - public System.Threading.Tasks.Task GetByteArrayAsync(System.Uri requestUri) { throw null; } - public System.Threading.Tasks.Task GetByteArrayAsync(System.Uri requestUri, System.Threading.CancellationToken cancellationToken) { throw null; } - public System.Threading.Tasks.Task GetStreamAsync(string requestUri) { throw null; } - public System.Threading.Tasks.Task GetStreamAsync(string requestUri, System.Threading.CancellationToken cancellationToken) { throw null; } - public System.Threading.Tasks.Task GetStreamAsync(System.Uri requestUri) { throw null; } - public System.Threading.Tasks.Task GetStreamAsync(System.Uri requestUri, System.Threading.CancellationToken cancellationToken) { throw null; } - public System.Threading.Tasks.Task GetStringAsync(string requestUri) { throw null; } - public System.Threading.Tasks.Task GetStringAsync(string requestUri, System.Threading.CancellationToken cancellationToken) { throw null; } - public System.Threading.Tasks.Task GetStringAsync(System.Uri requestUri) { throw null; } - public System.Threading.Tasks.Task GetStringAsync(System.Uri requestUri, System.Threading.CancellationToken cancellationToken) { throw null; } - public System.Threading.Tasks.Task PatchAsync(string requestUri, System.Net.Http.HttpContent content) { throw null; } - public System.Threading.Tasks.Task PatchAsync(string requestUri, System.Net.Http.HttpContent content, System.Threading.CancellationToken cancellationToken) { throw null; } - public System.Threading.Tasks.Task PatchAsync(System.Uri requestUri, System.Net.Http.HttpContent content) { throw null; } - public System.Threading.Tasks.Task PatchAsync(System.Uri requestUri, System.Net.Http.HttpContent content, System.Threading.CancellationToken cancellationToken) { throw null; } - public System.Threading.Tasks.Task PostAsync(string requestUri, System.Net.Http.HttpContent content) { throw null; } - public System.Threading.Tasks.Task PostAsync(string requestUri, System.Net.Http.HttpContent content, System.Threading.CancellationToken cancellationToken) { throw null; } - public System.Threading.Tasks.Task PostAsync(System.Uri requestUri, System.Net.Http.HttpContent content) { throw null; } - public System.Threading.Tasks.Task PostAsync(System.Uri requestUri, System.Net.Http.HttpContent content, System.Threading.CancellationToken cancellationToken) { throw null; } - public System.Threading.Tasks.Task PutAsync(string requestUri, System.Net.Http.HttpContent content) { throw null; } - public System.Threading.Tasks.Task PutAsync(string requestUri, System.Net.Http.HttpContent content, System.Threading.CancellationToken cancellationToken) { throw null; } - public System.Threading.Tasks.Task PutAsync(System.Uri requestUri, System.Net.Http.HttpContent content) { throw null; } - public System.Threading.Tasks.Task PutAsync(System.Uri requestUri, System.Net.Http.HttpContent content, System.Threading.CancellationToken cancellationToken) { throw null; } + public System.Threading.Tasks.Task GetAsync(string? requestUri) { throw null; } + public System.Threading.Tasks.Task GetAsync(string? requestUri, System.Net.Http.HttpCompletionOption completionOption) { throw null; } + public System.Threading.Tasks.Task GetAsync(string? requestUri, System.Net.Http.HttpCompletionOption completionOption, System.Threading.CancellationToken cancellationToken) { throw null; } + public System.Threading.Tasks.Task GetAsync(string? requestUri, System.Threading.CancellationToken cancellationToken) { throw null; } + public System.Threading.Tasks.Task GetAsync(System.Uri? requestUri) { throw null; } + public System.Threading.Tasks.Task GetAsync(System.Uri? requestUri, System.Net.Http.HttpCompletionOption completionOption) { throw null; } + public System.Threading.Tasks.Task GetAsync(System.Uri? requestUri, System.Net.Http.HttpCompletionOption completionOption, System.Threading.CancellationToken cancellationToken) { throw null; } + public System.Threading.Tasks.Task GetAsync(System.Uri? requestUri, System.Threading.CancellationToken cancellationToken) { throw null; } + public System.Threading.Tasks.Task GetByteArrayAsync(string? requestUri) { throw null; } + public System.Threading.Tasks.Task GetByteArrayAsync(string? requestUri, System.Threading.CancellationToken cancellationToken) { throw null; } + public System.Threading.Tasks.Task GetByteArrayAsync(System.Uri? requestUri) { throw null; } + public System.Threading.Tasks.Task GetByteArrayAsync(System.Uri? requestUri, System.Threading.CancellationToken cancellationToken) { throw null; } + public System.Threading.Tasks.Task GetStreamAsync(string? requestUri) { throw null; } + public System.Threading.Tasks.Task GetStreamAsync(string? requestUri, System.Threading.CancellationToken cancellationToken) { throw null; } + public System.Threading.Tasks.Task GetStreamAsync(System.Uri? requestUri) { throw null; } + public System.Threading.Tasks.Task GetStreamAsync(System.Uri? requestUri, System.Threading.CancellationToken cancellationToken) { throw null; } + public System.Threading.Tasks.Task GetStringAsync(string? requestUri) { throw null; } + public System.Threading.Tasks.Task GetStringAsync(string? requestUri, System.Threading.CancellationToken cancellationToken) { throw null; } + public System.Threading.Tasks.Task GetStringAsync(System.Uri? requestUri) { throw null; } + public System.Threading.Tasks.Task GetStringAsync(System.Uri? requestUri, System.Threading.CancellationToken cancellationToken) { throw null; } + public System.Threading.Tasks.Task PatchAsync(string? requestUri, System.Net.Http.HttpContent content) { throw null; } + public System.Threading.Tasks.Task PatchAsync(string? requestUri, System.Net.Http.HttpContent content, System.Threading.CancellationToken cancellationToken) { throw null; } + public System.Threading.Tasks.Task PatchAsync(System.Uri? requestUri, System.Net.Http.HttpContent content) { throw null; } + public System.Threading.Tasks.Task PatchAsync(System.Uri? requestUri, System.Net.Http.HttpContent content, System.Threading.CancellationToken cancellationToken) { throw null; } + public System.Threading.Tasks.Task PostAsync(string? requestUri, System.Net.Http.HttpContent content) { throw null; } + public System.Threading.Tasks.Task PostAsync(string? requestUri, System.Net.Http.HttpContent content, System.Threading.CancellationToken cancellationToken) { throw null; } + public System.Threading.Tasks.Task PostAsync(System.Uri? requestUri, System.Net.Http.HttpContent content) { throw null; } + public System.Threading.Tasks.Task PostAsync(System.Uri? requestUri, System.Net.Http.HttpContent content, System.Threading.CancellationToken cancellationToken) { throw null; } + public System.Threading.Tasks.Task PutAsync(string? requestUri, System.Net.Http.HttpContent content) { throw null; } + public System.Threading.Tasks.Task PutAsync(string? requestUri, System.Net.Http.HttpContent content, System.Threading.CancellationToken cancellationToken) { throw null; } + public System.Threading.Tasks.Task PutAsync(System.Uri? requestUri, System.Net.Http.HttpContent content) { throw null; } + public System.Threading.Tasks.Task PutAsync(System.Uri? requestUri, System.Net.Http.HttpContent content, System.Threading.CancellationToken cancellationToken) { throw null; } public System.Threading.Tasks.Task SendAsync(System.Net.Http.HttpRequestMessage request) { throw null; } public System.Threading.Tasks.Task SendAsync(System.Net.Http.HttpRequestMessage request, System.Net.Http.HttpCompletionOption completionOption) { throw null; } public System.Threading.Tasks.Task SendAsync(System.Net.Http.HttpRequestMessage request, System.Net.Http.HttpCompletionOption completionOption, System.Threading.CancellationToken cancellationToken) { throw null; } @@ -97,17 +98,17 @@ namespace System.Net.Http public System.Net.Http.ClientCertificateOption ClientCertificateOptions { get { throw null; } set { } } public System.Security.Cryptography.X509Certificates.X509CertificateCollection ClientCertificates { get { throw null; } } public System.Net.CookieContainer CookieContainer { get { throw null; } set { } } - public System.Net.ICredentials Credentials { get { throw null; } set { } } + public System.Net.ICredentials? Credentials { get { throw null; } set { } } public static System.Func DangerousAcceptAnyServerCertificateValidator { get { throw null; } } - public System.Net.ICredentials DefaultProxyCredentials { get { throw null; } set { } } + public System.Net.ICredentials? DefaultProxyCredentials { get { throw null; } set { } } public int MaxAutomaticRedirections { get { throw null; } set { } } public int MaxConnectionsPerServer { get { throw null; } set { } } public long MaxRequestContentBufferSize { get { throw null; } set { } } public int MaxResponseHeadersLength { get { throw null; } set { } } public bool PreAuthenticate { get { throw null; } set { } } - public System.Collections.Generic.IDictionary Properties { get { throw null; } } - public System.Net.IWebProxy Proxy { get { throw null; } set { } } - public System.Func ServerCertificateCustomValidationCallback { get { throw null; } set { } } + public System.Collections.Generic.IDictionary Properties { get { throw null; } } + public System.Net.IWebProxy? Proxy { get { throw null; } set { } } + public System.Func? ServerCertificateCustomValidationCallback { get { throw null; } set { } } public System.Security.Authentication.SslProtocols SslProtocols { get { throw null; } set { } } public virtual bool SupportsAutomaticDecompression { get { throw null; } } public virtual bool SupportsProxy { get { throw null; } } @@ -128,8 +129,8 @@ namespace System.Net.Http protected HttpContent() { } public System.Net.Http.Headers.HttpContentHeaders Headers { get { throw null; } } public System.Threading.Tasks.Task CopyToAsync(System.IO.Stream stream) { throw null; } - public System.Threading.Tasks.Task CopyToAsync(System.IO.Stream stream, System.Net.TransportContext context) { throw null; } - public System.Threading.Tasks.Task CopyToAsync(System.IO.Stream stream, System.Net.TransportContext context, System.Threading.CancellationToken cancellationToken) { throw null; } + public System.Threading.Tasks.Task CopyToAsync(System.IO.Stream stream, System.Net.TransportContext? context) { throw null; } + public System.Threading.Tasks.Task CopyToAsync(System.IO.Stream stream, System.Net.TransportContext? context, System.Threading.CancellationToken cancellationToken) { throw null; } public System.Threading.Tasks.Task CopyToAsync(System.IO.Stream stream, System.Threading.CancellationToken cancellationToken) { throw null; } protected virtual System.Threading.Tasks.Task CreateContentReadStreamAsync() { throw null; } protected virtual System.Threading.Tasks.Task CreateContentReadStreamAsync(System.Threading.CancellationToken cancellationToken) { throw null; } @@ -143,8 +144,8 @@ namespace System.Net.Http public System.Threading.Tasks.Task ReadAsStreamAsync(System.Threading.CancellationToken cancellationToken) { throw null; } public System.Threading.Tasks.Task ReadAsStringAsync() { throw null; } public System.Threading.Tasks.Task ReadAsStringAsync(System.Threading.CancellationToken cancellationToken) { throw null; } - protected abstract System.Threading.Tasks.Task SerializeToStreamAsync(System.IO.Stream stream, System.Net.TransportContext context); - protected virtual System.Threading.Tasks.Task SerializeToStreamAsync(System.IO.Stream stream, System.Net.TransportContext context, System.Threading.CancellationToken cancellationToken) { throw null; } + protected abstract System.Threading.Tasks.Task SerializeToStreamAsync(System.IO.Stream stream, System.Net.TransportContext? context); + protected virtual System.Threading.Tasks.Task SerializeToStreamAsync(System.IO.Stream stream, System.Net.TransportContext? context, System.Threading.CancellationToken cancellationToken) { throw null; } protected internal abstract bool TryComputeLength(out long length); } public abstract partial class HttpMessageHandler : System.IDisposable @@ -174,31 +175,31 @@ namespace System.Net.Http public static System.Net.Http.HttpMethod Post { get { throw null; } } public static System.Net.Http.HttpMethod Put { get { throw null; } } public static System.Net.Http.HttpMethod Trace { get { throw null; } } - public bool Equals(System.Net.Http.HttpMethod other) { throw null; } - public override bool Equals(object obj) { throw null; } + public bool Equals(System.Net.Http.HttpMethod? other) { throw null; } + public override bool Equals(object? obj) { throw null; } public override int GetHashCode() { throw null; } - public static bool operator ==(System.Net.Http.HttpMethod left, System.Net.Http.HttpMethod right) { throw null; } - public static bool operator !=(System.Net.Http.HttpMethod left, System.Net.Http.HttpMethod right) { throw null; } + public static bool operator ==(System.Net.Http.HttpMethod? left, System.Net.Http.HttpMethod? right) { throw null; } + public static bool operator !=(System.Net.Http.HttpMethod? left, System.Net.Http.HttpMethod? right) { throw null; } public override string ToString() { throw null; } } public partial class HttpRequestException : System.Exception { public HttpRequestException() { } - public HttpRequestException(string message) { } - public HttpRequestException(string message, System.Exception inner) { } - public HttpRequestException(string message, System.Exception inner, System.Net.HttpStatusCode? statusCode) { } + public HttpRequestException(string? message) { } + public HttpRequestException(string? message, System.Exception? inner) { } + public HttpRequestException(string? message, System.Exception? inner, System.Net.HttpStatusCode? statusCode) { } public System.Net.HttpStatusCode? StatusCode { get { throw null; } } } public partial class HttpRequestMessage : System.IDisposable { public HttpRequestMessage() { } - public HttpRequestMessage(System.Net.Http.HttpMethod method, string requestUri) { } - public HttpRequestMessage(System.Net.Http.HttpMethod method, System.Uri requestUri) { } - public System.Net.Http.HttpContent Content { get { throw null; } set { } } + public HttpRequestMessage(System.Net.Http.HttpMethod method, string? requestUri) { } + public HttpRequestMessage(System.Net.Http.HttpMethod method, System.Uri? requestUri) { } + public System.Net.Http.HttpContent? Content { get { throw null; } set { } } public System.Net.Http.Headers.HttpRequestHeaders Headers { get { throw null; } } public System.Net.Http.HttpMethod Method { get { throw null; } set { } } - public System.Collections.Generic.IDictionary Properties { get { throw null; } } - public System.Uri RequestUri { get { throw null; } set { } } + public System.Collections.Generic.IDictionary Properties { get { throw null; } } + public System.Uri? RequestUri { get { throw null; } set { } } public System.Version Version { get { throw null; } set { } } public void Dispose() { } protected virtual void Dispose(bool disposing) { } @@ -208,11 +209,11 @@ namespace System.Net.Http { public HttpResponseMessage() { } public HttpResponseMessage(System.Net.HttpStatusCode statusCode) { } - public System.Net.Http.HttpContent Content { get { throw null; } set { } } + public System.Net.Http.HttpContent? Content { get { throw null; } set { } } public System.Net.Http.Headers.HttpResponseHeaders Headers { get { throw null; } } public bool IsSuccessStatusCode { get { throw null; } } - public string ReasonPhrase { get { throw null; } set { } } - public System.Net.Http.HttpRequestMessage RequestMessage { get { throw null; } set { } } + public string? ReasonPhrase { get { throw null; } set { } } + public System.Net.Http.HttpRequestMessage? RequestMessage { get { throw null; } set { } } public System.Net.HttpStatusCode StatusCode { get { throw null; } set { } } public System.Net.Http.Headers.HttpResponseHeaders TrailingHeaders { get { throw null; } } public System.Version Version { get { throw null; } set { } } @@ -239,8 +240,8 @@ namespace System.Net.Http protected override System.Threading.Tasks.Task CreateContentReadStreamAsync(System.Threading.CancellationToken cancellationToken) { throw null; } protected override void Dispose(bool disposing) { } public System.Collections.Generic.IEnumerator GetEnumerator() { throw null; } - protected override System.Threading.Tasks.Task SerializeToStreamAsync(System.IO.Stream stream, System.Net.TransportContext context) { throw null; } - protected override System.Threading.Tasks.Task SerializeToStreamAsync(System.IO.Stream stream, System.Net.TransportContext context, System.Threading.CancellationToken cancellationToken) { throw null; } + protected override System.Threading.Tasks.Task SerializeToStreamAsync(System.IO.Stream stream, System.Net.TransportContext? context) { throw null; } + protected override System.Threading.Tasks.Task SerializeToStreamAsync(System.IO.Stream stream, System.Net.TransportContext? context, System.Threading.CancellationToken cancellationToken) { throw null; } System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { throw null; } protected internal override bool TryComputeLength(out long length) { throw null; } } @@ -251,14 +252,14 @@ namespace System.Net.Http public override void Add(System.Net.Http.HttpContent content) { } public void Add(System.Net.Http.HttpContent content, string name) { } public void Add(System.Net.Http.HttpContent content, string name, string fileName) { } - protected override System.Threading.Tasks.Task SerializeToStreamAsync(System.IO.Stream stream, System.Net.TransportContext context, System.Threading.CancellationToken cancellationToken) { throw null; } + protected override System.Threading.Tasks.Task SerializeToStreamAsync(System.IO.Stream stream, System.Net.TransportContext? context, System.Threading.CancellationToken cancellationToken) { throw null; } } public sealed partial class ReadOnlyMemoryContent : System.Net.Http.HttpContent { public ReadOnlyMemoryContent(System.ReadOnlyMemory content) { } protected override System.Threading.Tasks.Task CreateContentReadStreamAsync() { throw null; } - protected override System.Threading.Tasks.Task SerializeToStreamAsync(System.IO.Stream stream, System.Net.TransportContext context) { throw null; } - protected override System.Threading.Tasks.Task SerializeToStreamAsync(System.IO.Stream stream, System.Net.TransportContext context, System.Threading.CancellationToken cancellationToken) { throw null; } + protected override System.Threading.Tasks.Task SerializeToStreamAsync(System.IO.Stream stream, System.Net.TransportContext? context) { throw null; } + protected override System.Threading.Tasks.Task SerializeToStreamAsync(System.IO.Stream stream, System.Net.TransportContext? context, System.Threading.CancellationToken cancellationToken) { throw null; } protected internal override bool TryComputeLength(out long length) { throw null; } } public sealed partial class SocketsHttpHandler : System.Net.Http.HttpMessageHandler @@ -268,8 +269,8 @@ namespace System.Net.Http public System.Net.DecompressionMethods AutomaticDecompression { get { throw null; } set { } } public System.TimeSpan ConnectTimeout { get { throw null; } set { } } public System.Net.CookieContainer CookieContainer { get { throw null; } set { } } - public System.Net.ICredentials Credentials { get { throw null; } set { } } - public System.Net.ICredentials DefaultProxyCredentials { get { throw null; } set { } } + public System.Net.ICredentials? Credentials { get { throw null; } set { } } + public System.Net.ICredentials? DefaultProxyCredentials { get { throw null; } set { } } public System.TimeSpan Expect100ContinueTimeout { get { throw null; } set { } } public int MaxAutomaticRedirections { get { throw null; } set { } } public int MaxConnectionsPerServer { get { throw null; } set { } } @@ -278,9 +279,10 @@ namespace System.Net.Http public System.TimeSpan PooledConnectionIdleTimeout { get { throw null; } set { } } public System.TimeSpan PooledConnectionLifetime { get { throw null; } set { } } public bool PreAuthenticate { get { throw null; } set { } } - public System.Collections.Generic.IDictionary Properties { get { throw null; } } - public System.Net.IWebProxy Proxy { get { throw null; } set { } } + public System.Collections.Generic.IDictionary Properties { get { throw null; } } + public System.Net.IWebProxy? Proxy { get { throw null; } set { } } public System.TimeSpan ResponseDrainTimeout { get { throw null; } set { } } + [System.Diagnostics.CodeAnalysis.AllowNullAttribute] public System.Net.Security.SslClientAuthenticationOptions SslOptions { get { throw null; } set { } } public bool UseCookies { get { throw null; } set { } } public bool UseProxy { get { throw null; } set { } } @@ -293,16 +295,16 @@ namespace System.Net.Http public StreamContent(System.IO.Stream content, int bufferSize) { } protected override System.Threading.Tasks.Task CreateContentReadStreamAsync() { throw null; } protected override void Dispose(bool disposing) { } - protected override System.Threading.Tasks.Task SerializeToStreamAsync(System.IO.Stream stream, System.Net.TransportContext context) { throw null; } - protected override System.Threading.Tasks.Task SerializeToStreamAsync(System.IO.Stream stream, System.Net.TransportContext context, System.Threading.CancellationToken cancellationToken) { throw null; } + protected override System.Threading.Tasks.Task SerializeToStreamAsync(System.IO.Stream stream, System.Net.TransportContext? context) { throw null; } + protected override System.Threading.Tasks.Task SerializeToStreamAsync(System.IO.Stream stream, System.Net.TransportContext? context, System.Threading.CancellationToken cancellationToken) { throw null; } protected internal override bool TryComputeLength(out long length) { throw null; } } public partial class StringContent : System.Net.Http.ByteArrayContent { public StringContent(string content) : base (default(byte[])) { } - public StringContent(string content, System.Text.Encoding encoding) : base (default(byte[])) { } - public StringContent(string content, System.Text.Encoding encoding, string mediaType) : base (default(byte[])) { } - protected override System.Threading.Tasks.Task SerializeToStreamAsync(System.IO.Stream stream, System.Net.TransportContext context, System.Threading.CancellationToken cancellationToken) { throw null; } + public StringContent(string content, System.Text.Encoding? encoding) : base (default(byte[])) { } + public StringContent(string content, System.Text.Encoding? encoding, string? mediaType) : base (default(byte[])) { } + protected override System.Threading.Tasks.Task SerializeToStreamAsync(System.IO.Stream stream, System.Net.TransportContext? context, System.Threading.CancellationToken cancellationToken) { throw null; } } } namespace System.Net.Http.Headers @@ -310,15 +312,15 @@ namespace System.Net.Http.Headers public partial class AuthenticationHeaderValue : System.ICloneable { public AuthenticationHeaderValue(string scheme) { } - public AuthenticationHeaderValue(string scheme, string parameter) { } - public string Parameter { get { throw null; } } + public AuthenticationHeaderValue(string scheme, string? parameter) { } + public string? Parameter { get { throw null; } } public string Scheme { get { throw null; } } - public override bool Equals(object obj) { throw null; } + public override bool Equals(object? obj) { throw null; } public override int GetHashCode() { throw null; } - public static System.Net.Http.Headers.AuthenticationHeaderValue Parse(string input) { throw null; } + public static System.Net.Http.Headers.AuthenticationHeaderValue Parse(string? input) { throw null; } object System.ICloneable.Clone() { throw null; } public override string ToString() { throw null; } - public static bool TryParse(string input, out System.Net.Http.Headers.AuthenticationHeaderValue parsedValue) { throw null; } + public static bool TryParse(string? input, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out System.Net.Http.Headers.AuthenticationHeaderValue? parsedValue) { throw null; } } public partial class CacheControlHeaderValue : System.ICloneable { @@ -339,12 +341,12 @@ namespace System.Net.Http.Headers public bool ProxyRevalidate { get { throw null; } set { } } public bool Public { get { throw null; } set { } } public System.TimeSpan? SharedMaxAge { get { throw null; } set { } } - public override bool Equals(object obj) { throw null; } + public override bool Equals(object? obj) { throw null; } public override int GetHashCode() { throw null; } - public static System.Net.Http.Headers.CacheControlHeaderValue Parse(string input) { throw null; } + public static System.Net.Http.Headers.CacheControlHeaderValue Parse(string? input) { throw null; } object System.ICloneable.Clone() { throw null; } public override string ToString() { throw null; } - public static bool TryParse(string input, out System.Net.Http.Headers.CacheControlHeaderValue parsedValue) { throw null; } + public static bool TryParse(string? input, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out System.Net.Http.Headers.CacheControlHeaderValue? parsedValue) { throw null; } } public partial class ContentDispositionHeaderValue : System.ICloneable { @@ -352,19 +354,19 @@ namespace System.Net.Http.Headers public ContentDispositionHeaderValue(string dispositionType) { } public System.DateTimeOffset? CreationDate { get { throw null; } set { } } public string DispositionType { get { throw null; } set { } } - public string FileName { get { throw null; } set { } } - public string FileNameStar { get { throw null; } set { } } + public string? FileName { get { throw null; } set { } } + public string? FileNameStar { get { throw null; } set { } } public System.DateTimeOffset? ModificationDate { get { throw null; } set { } } - public string Name { get { throw null; } set { } } + public string? Name { get { throw null; } set { } } public System.Collections.Generic.ICollection Parameters { get { throw null; } } public System.DateTimeOffset? ReadDate { get { throw null; } set { } } public long? Size { get { throw null; } set { } } - public override bool Equals(object obj) { throw null; } + public override bool Equals(object? obj) { throw null; } public override int GetHashCode() { throw null; } - public static System.Net.Http.Headers.ContentDispositionHeaderValue Parse(string input) { throw null; } + public static System.Net.Http.Headers.ContentDispositionHeaderValue Parse(string? input) { throw null; } object System.ICloneable.Clone() { throw null; } public override string ToString() { throw null; } - public static bool TryParse(string input, out System.Net.Http.Headers.ContentDispositionHeaderValue parsedValue) { throw null; } + public static bool TryParse(string? input, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out System.Net.Http.Headers.ContentDispositionHeaderValue? parsedValue) { throw null; } } public partial class ContentRangeHeaderValue : System.ICloneable { @@ -377,12 +379,12 @@ namespace System.Net.Http.Headers public long? Length { get { throw null; } } public long? To { get { throw null; } } public string Unit { get { throw null; } set { } } - public override bool Equals(object obj) { throw null; } + public override bool Equals(object? obj) { throw null; } public override int GetHashCode() { throw null; } - public static System.Net.Http.Headers.ContentRangeHeaderValue Parse(string input) { throw null; } + public static System.Net.Http.Headers.ContentRangeHeaderValue Parse(string? input) { throw null; } object System.ICloneable.Clone() { throw null; } public override string ToString() { throw null; } - public static bool TryParse(string input, out System.Net.Http.Headers.ContentRangeHeaderValue parsedValue) { throw null; } + public static bool TryParse(string? input, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out System.Net.Http.Headers.ContentRangeHeaderValue? parsedValue) { throw null; } } public partial class EntityTagHeaderValue : System.ICloneable { @@ -391,33 +393,33 @@ namespace System.Net.Http.Headers public static System.Net.Http.Headers.EntityTagHeaderValue Any { get { throw null; } } public bool IsWeak { get { throw null; } } public string Tag { get { throw null; } } - public override bool Equals(object obj) { throw null; } + public override bool Equals(object? obj) { throw null; } public override int GetHashCode() { throw null; } - public static System.Net.Http.Headers.EntityTagHeaderValue Parse(string input) { throw null; } + public static System.Net.Http.Headers.EntityTagHeaderValue Parse(string? input) { throw null; } object System.ICloneable.Clone() { throw null; } public override string ToString() { throw null; } - public static bool TryParse(string input, out System.Net.Http.Headers.EntityTagHeaderValue parsedValue) { throw null; } + public static bool TryParse(string? input, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out System.Net.Http.Headers.EntityTagHeaderValue? parsedValue) { throw null; } } public sealed partial class HttpContentHeaders : System.Net.Http.Headers.HttpHeaders { internal HttpContentHeaders() { } public System.Collections.Generic.ICollection Allow { get { throw null; } } - public System.Net.Http.Headers.ContentDispositionHeaderValue ContentDisposition { get { throw null; } set { } } + public System.Net.Http.Headers.ContentDispositionHeaderValue? ContentDisposition { get { throw null; } set { } } public System.Collections.Generic.ICollection ContentEncoding { get { throw null; } } public System.Collections.Generic.ICollection ContentLanguage { get { throw null; } } public long? ContentLength { get { throw null; } set { } } - public System.Uri ContentLocation { get { throw null; } set { } } - public byte[] ContentMD5 { get { throw null; } set { } } - public System.Net.Http.Headers.ContentRangeHeaderValue ContentRange { get { throw null; } set { } } - public System.Net.Http.Headers.MediaTypeHeaderValue ContentType { get { throw null; } set { } } + public System.Uri? ContentLocation { get { throw null; } set { } } + public byte[]? ContentMD5 { get { throw null; } set { } } + public System.Net.Http.Headers.ContentRangeHeaderValue? ContentRange { get { throw null; } set { } } + public System.Net.Http.Headers.MediaTypeHeaderValue? ContentType { get { throw null; } set { } } public System.DateTimeOffset? Expires { get { throw null; } set { } } public System.DateTimeOffset? LastModified { get { throw null; } set { } } } public abstract partial class HttpHeaders : System.Collections.Generic.IEnumerable>>, System.Collections.IEnumerable { protected HttpHeaders() { } - public void Add(string name, System.Collections.Generic.IEnumerable values) { } - public void Add(string name, string value) { } + public void Add(string name, System.Collections.Generic.IEnumerable values) { } + public void Add(string name, string? value) { } public void Clear() { } public bool Contains(string name) { throw null; } public System.Collections.Generic.IEnumerator>> GetEnumerator() { throw null; } @@ -425,9 +427,9 @@ namespace System.Net.Http.Headers public bool Remove(string name) { throw null; } System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { throw null; } public override string ToString() { throw null; } - public bool TryAddWithoutValidation(string name, System.Collections.Generic.IEnumerable values) { throw null; } - public bool TryAddWithoutValidation(string name, string value) { throw null; } - public bool TryGetValues(string name, out System.Collections.Generic.IEnumerable values) { throw null; } + public bool TryAddWithoutValidation(string name, System.Collections.Generic.IEnumerable values) { throw null; } + public bool TryAddWithoutValidation(string name, string? value) { throw null; } + public bool TryGetValues(string name, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out System.Collections.Generic.IEnumerable? values) { throw null; } } public sealed partial class HttpHeaderValueCollection : System.Collections.Generic.ICollection, System.Collections.Generic.IEnumerable, System.Collections.IEnumerable where T : class { @@ -439,11 +441,11 @@ namespace System.Net.Http.Headers public bool Contains(T item) { throw null; } public void CopyTo(T[] array, int arrayIndex) { } public System.Collections.Generic.IEnumerator GetEnumerator() { throw null; } - public void ParseAdd(string input) { } + public void ParseAdd(string? input) { } public bool Remove(T item) { throw null; } System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { throw null; } public override string ToString() { throw null; } - public bool TryParseAdd(string input) { throw null; } + public bool TryParseAdd(string? input) { throw null; } } public sealed partial class HttpRequestHeaders : System.Net.Http.Headers.HttpHeaders { @@ -452,25 +454,25 @@ namespace System.Net.Http.Headers public System.Net.Http.Headers.HttpHeaderValueCollection AcceptCharset { get { throw null; } } public System.Net.Http.Headers.HttpHeaderValueCollection AcceptEncoding { get { throw null; } } public System.Net.Http.Headers.HttpHeaderValueCollection AcceptLanguage { get { throw null; } } - public System.Net.Http.Headers.AuthenticationHeaderValue Authorization { get { throw null; } set { } } - public System.Net.Http.Headers.CacheControlHeaderValue CacheControl { get { throw null; } set { } } + public System.Net.Http.Headers.AuthenticationHeaderValue? Authorization { get { throw null; } set { } } + public System.Net.Http.Headers.CacheControlHeaderValue? CacheControl { get { throw null; } set { } } public System.Net.Http.Headers.HttpHeaderValueCollection Connection { get { throw null; } } public bool? ConnectionClose { get { throw null; } set { } } public System.DateTimeOffset? Date { get { throw null; } set { } } public System.Net.Http.Headers.HttpHeaderValueCollection Expect { get { throw null; } } public bool? ExpectContinue { get { throw null; } set { } } - public string From { get { throw null; } set { } } - public string Host { get { throw null; } set { } } + public string? From { get { throw null; } set { } } + public string? Host { get { throw null; } set { } } public System.Net.Http.Headers.HttpHeaderValueCollection IfMatch { get { throw null; } } public System.DateTimeOffset? IfModifiedSince { get { throw null; } set { } } public System.Net.Http.Headers.HttpHeaderValueCollection IfNoneMatch { get { throw null; } } - public System.Net.Http.Headers.RangeConditionHeaderValue IfRange { get { throw null; } set { } } + public System.Net.Http.Headers.RangeConditionHeaderValue? IfRange { get { throw null; } set { } } public System.DateTimeOffset? IfUnmodifiedSince { get { throw null; } set { } } public int? MaxForwards { get { throw null; } set { } } public System.Net.Http.Headers.HttpHeaderValueCollection Pragma { get { throw null; } } - public System.Net.Http.Headers.AuthenticationHeaderValue ProxyAuthorization { get { throw null; } set { } } - public System.Net.Http.Headers.RangeHeaderValue Range { get { throw null; } set { } } - public System.Uri Referrer { get { throw null; } set { } } + public System.Net.Http.Headers.AuthenticationHeaderValue? ProxyAuthorization { get { throw null; } set { } } + public System.Net.Http.Headers.RangeHeaderValue? Range { get { throw null; } set { } } + public System.Uri? Referrer { get { throw null; } set { } } public System.Net.Http.Headers.HttpHeaderValueCollection TE { get { throw null; } } public System.Net.Http.Headers.HttpHeaderValueCollection Trailer { get { throw null; } } public System.Net.Http.Headers.HttpHeaderValueCollection TransferEncoding { get { throw null; } } @@ -485,15 +487,15 @@ namespace System.Net.Http.Headers internal HttpResponseHeaders() { } public System.Net.Http.Headers.HttpHeaderValueCollection AcceptRanges { get { throw null; } } public System.TimeSpan? Age { get { throw null; } set { } } - public System.Net.Http.Headers.CacheControlHeaderValue CacheControl { get { throw null; } set { } } + public System.Net.Http.Headers.CacheControlHeaderValue? CacheControl { get { throw null; } set { } } public System.Net.Http.Headers.HttpHeaderValueCollection Connection { get { throw null; } } public bool? ConnectionClose { get { throw null; } set { } } public System.DateTimeOffset? Date { get { throw null; } set { } } - public System.Net.Http.Headers.EntityTagHeaderValue ETag { get { throw null; } set { } } - public System.Uri Location { get { throw null; } set { } } + public System.Net.Http.Headers.EntityTagHeaderValue? ETag { get { throw null; } set { } } + public System.Uri? Location { get { throw null; } set { } } public System.Net.Http.Headers.HttpHeaderValueCollection Pragma { get { throw null; } } public System.Net.Http.Headers.HttpHeaderValueCollection ProxyAuthenticate { get { throw null; } } - public System.Net.Http.Headers.RetryConditionHeaderValue RetryAfter { get { throw null; } set { } } + public System.Net.Http.Headers.RetryConditionHeaderValue? RetryAfter { get { throw null; } set { } } public System.Net.Http.Headers.HttpHeaderValueCollection Server { get { throw null; } } public System.Net.Http.Headers.HttpHeaderValueCollection Trailer { get { throw null; } } public System.Net.Http.Headers.HttpHeaderValueCollection TransferEncoding { get { throw null; } } @@ -508,78 +510,79 @@ namespace System.Net.Http.Headers { protected MediaTypeHeaderValue(System.Net.Http.Headers.MediaTypeHeaderValue source) { } public MediaTypeHeaderValue(string mediaType) { } - public string CharSet { get { throw null; } set { } } - public string MediaType { get { throw null; } set { } } + public string? CharSet { get { throw null; } set { } } + [System.Diagnostics.CodeAnalysis.DisallowNullAttribute] + public string? MediaType { get { throw null; } set { } } public System.Collections.Generic.ICollection Parameters { get { throw null; } } - public override bool Equals(object obj) { throw null; } + public override bool Equals(object? obj) { throw null; } public override int GetHashCode() { throw null; } - public static System.Net.Http.Headers.MediaTypeHeaderValue Parse(string input) { throw null; } + public static System.Net.Http.Headers.MediaTypeHeaderValue Parse(string? input) { throw null; } object System.ICloneable.Clone() { throw null; } public override string ToString() { throw null; } - public static bool TryParse(string input, out System.Net.Http.Headers.MediaTypeHeaderValue parsedValue) { throw null; } + public static bool TryParse(string? input, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out System.Net.Http.Headers.MediaTypeHeaderValue? parsedValue) { throw null; } } public sealed partial class MediaTypeWithQualityHeaderValue : System.Net.Http.Headers.MediaTypeHeaderValue, System.ICloneable { public MediaTypeWithQualityHeaderValue(string mediaType) : base (default(System.Net.Http.Headers.MediaTypeHeaderValue)) { } public MediaTypeWithQualityHeaderValue(string mediaType, double quality) : base (default(System.Net.Http.Headers.MediaTypeHeaderValue)) { } public double? Quality { get { throw null; } set { } } - public static new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue Parse(string input) { throw null; } + public static new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue Parse(string? input) { throw null; } object System.ICloneable.Clone() { throw null; } - public static bool TryParse(string input, out System.Net.Http.Headers.MediaTypeWithQualityHeaderValue parsedValue) { throw null; } + public static bool TryParse(string? input, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out System.Net.Http.Headers.MediaTypeWithQualityHeaderValue? parsedValue) { throw null; } } public partial class NameValueHeaderValue : System.ICloneable { protected NameValueHeaderValue(System.Net.Http.Headers.NameValueHeaderValue source) { } public NameValueHeaderValue(string name) { } - public NameValueHeaderValue(string name, string value) { } + public NameValueHeaderValue(string name, string? value) { } public string Name { get { throw null; } } - public string Value { get { throw null; } set { } } - public override bool Equals(object obj) { throw null; } + public string? Value { get { throw null; } set { } } + public override bool Equals(object? obj) { throw null; } public override int GetHashCode() { throw null; } - public static System.Net.Http.Headers.NameValueHeaderValue Parse(string input) { throw null; } + public static System.Net.Http.Headers.NameValueHeaderValue Parse(string? input) { throw null; } object System.ICloneable.Clone() { throw null; } public override string ToString() { throw null; } - public static bool TryParse(string input, out System.Net.Http.Headers.NameValueHeaderValue parsedValue) { throw null; } + public static bool TryParse(string? input, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out System.Net.Http.Headers.NameValueHeaderValue? parsedValue) { throw null; } } public partial class NameValueWithParametersHeaderValue : System.Net.Http.Headers.NameValueHeaderValue, System.ICloneable { protected NameValueWithParametersHeaderValue(System.Net.Http.Headers.NameValueWithParametersHeaderValue source) : base (default(string)) { } public NameValueWithParametersHeaderValue(string name) : base (default(string)) { } - public NameValueWithParametersHeaderValue(string name, string value) : base (default(string)) { } + public NameValueWithParametersHeaderValue(string name, string? value) : base (default(string)) { } public System.Collections.Generic.ICollection Parameters { get { throw null; } } - public override bool Equals(object obj) { throw null; } + public override bool Equals(object? obj) { throw null; } public override int GetHashCode() { throw null; } - public static new System.Net.Http.Headers.NameValueWithParametersHeaderValue Parse(string input) { throw null; } + public static new System.Net.Http.Headers.NameValueWithParametersHeaderValue Parse(string? input) { throw null; } object System.ICloneable.Clone() { throw null; } public override string ToString() { throw null; } - public static bool TryParse(string input, out System.Net.Http.Headers.NameValueWithParametersHeaderValue parsedValue) { throw null; } + public static bool TryParse(string? input, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out System.Net.Http.Headers.NameValueWithParametersHeaderValue? parsedValue) { throw null; } } public partial class ProductHeaderValue : System.ICloneable { public ProductHeaderValue(string name) { } - public ProductHeaderValue(string name, string version) { } + public ProductHeaderValue(string name, string? version) { } public string Name { get { throw null; } } - public string Version { get { throw null; } } - public override bool Equals(object obj) { throw null; } + public string? Version { get { throw null; } } + public override bool Equals(object? obj) { throw null; } public override int GetHashCode() { throw null; } - public static System.Net.Http.Headers.ProductHeaderValue Parse(string input) { throw null; } + public static System.Net.Http.Headers.ProductHeaderValue Parse(string? input) { throw null; } object System.ICloneable.Clone() { throw null; } public override string ToString() { throw null; } - public static bool TryParse(string input, out System.Net.Http.Headers.ProductHeaderValue parsedValue) { throw null; } + public static bool TryParse(string? input, out System.Net.Http.Headers.ProductHeaderValue? parsedValue) { throw null; } } public partial class ProductInfoHeaderValue : System.ICloneable { public ProductInfoHeaderValue(System.Net.Http.Headers.ProductHeaderValue product) { } public ProductInfoHeaderValue(string comment) { } - public ProductInfoHeaderValue(string productName, string productVersion) { } - public string Comment { get { throw null; } } - public System.Net.Http.Headers.ProductHeaderValue Product { get { throw null; } } - public override bool Equals(object obj) { throw null; } + public ProductInfoHeaderValue(string productName, string? productVersion) { } + public string? Comment { get { throw null; } } + public System.Net.Http.Headers.ProductHeaderValue? Product { get { throw null; } } + public override bool Equals(object? obj) { throw null; } public override int GetHashCode() { throw null; } public static System.Net.Http.Headers.ProductInfoHeaderValue Parse(string input) { throw null; } object System.ICloneable.Clone() { throw null; } public override string ToString() { throw null; } - public static bool TryParse(string input, out System.Net.Http.Headers.ProductInfoHeaderValue parsedValue) { throw null; } + public static bool TryParse(string input, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out System.Net.Http.Headers.ProductInfoHeaderValue? parsedValue) { throw null; } } public partial class RangeConditionHeaderValue : System.ICloneable { @@ -587,13 +590,13 @@ namespace System.Net.Http.Headers public RangeConditionHeaderValue(System.Net.Http.Headers.EntityTagHeaderValue entityTag) { } public RangeConditionHeaderValue(string entityTag) { } public System.DateTimeOffset? Date { get { throw null; } } - public System.Net.Http.Headers.EntityTagHeaderValue EntityTag { get { throw null; } } - public override bool Equals(object obj) { throw null; } + public System.Net.Http.Headers.EntityTagHeaderValue? EntityTag { get { throw null; } } + public override bool Equals(object? obj) { throw null; } public override int GetHashCode() { throw null; } - public static System.Net.Http.Headers.RangeConditionHeaderValue Parse(string input) { throw null; } + public static System.Net.Http.Headers.RangeConditionHeaderValue Parse(string? input) { throw null; } object System.ICloneable.Clone() { throw null; } public override string ToString() { throw null; } - public static bool TryParse(string input, out System.Net.Http.Headers.RangeConditionHeaderValue parsedValue) { throw null; } + public static bool TryParse(string? input, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out System.Net.Http.Headers.RangeConditionHeaderValue? parsedValue) { throw null; } } public partial class RangeHeaderValue : System.ICloneable { @@ -601,19 +604,19 @@ namespace System.Net.Http.Headers public RangeHeaderValue(long? from, long? to) { } public System.Collections.Generic.ICollection Ranges { get { throw null; } } public string Unit { get { throw null; } set { } } - public override bool Equals(object obj) { throw null; } + public override bool Equals(object? obj) { throw null; } public override int GetHashCode() { throw null; } - public static System.Net.Http.Headers.RangeHeaderValue Parse(string input) { throw null; } + public static System.Net.Http.Headers.RangeHeaderValue Parse(string? input) { throw null; } object System.ICloneable.Clone() { throw null; } public override string ToString() { throw null; } - public static bool TryParse(string input, out System.Net.Http.Headers.RangeHeaderValue parsedValue) { throw null; } + public static bool TryParse(string? input, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out System.Net.Http.Headers.RangeHeaderValue? parsedValue) { throw null; } } public partial class RangeItemHeaderValue : System.ICloneable { public RangeItemHeaderValue(long? from, long? to) { } public long? From { get { throw null; } } public long? To { get { throw null; } } - public override bool Equals(object obj) { throw null; } + public override bool Equals(object? obj) { throw null; } public override int GetHashCode() { throw null; } object System.ICloneable.Clone() { throw null; } public override string ToString() { throw null; } @@ -624,12 +627,12 @@ namespace System.Net.Http.Headers public RetryConditionHeaderValue(System.TimeSpan delta) { } public System.DateTimeOffset? Date { get { throw null; } } public System.TimeSpan? Delta { get { throw null; } } - public override bool Equals(object obj) { throw null; } + public override bool Equals(object? obj) { throw null; } public override int GetHashCode() { throw null; } - public static System.Net.Http.Headers.RetryConditionHeaderValue Parse(string input) { throw null; } + public static System.Net.Http.Headers.RetryConditionHeaderValue Parse(string? input) { throw null; } object System.ICloneable.Clone() { throw null; } public override string ToString() { throw null; } - public static bool TryParse(string input, out System.Net.Http.Headers.RetryConditionHeaderValue parsedValue) { throw null; } + public static bool TryParse(string? input, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out System.Net.Http.Headers.RetryConditionHeaderValue? parsedValue) { throw null; } } public partial class StringWithQualityHeaderValue : System.ICloneable { @@ -637,12 +640,12 @@ namespace System.Net.Http.Headers public StringWithQualityHeaderValue(string value, double quality) { } public double? Quality { get { throw null; } } public string Value { get { throw null; } } - public override bool Equals(object obj) { throw null; } + public override bool Equals(object? obj) { throw null; } public override int GetHashCode() { throw null; } - public static System.Net.Http.Headers.StringWithQualityHeaderValue Parse(string input) { throw null; } + public static System.Net.Http.Headers.StringWithQualityHeaderValue Parse(string? input) { throw null; } object System.ICloneable.Clone() { throw null; } public override string ToString() { throw null; } - public static bool TryParse(string input, out System.Net.Http.Headers.StringWithQualityHeaderValue parsedValue) { throw null; } + public static bool TryParse(string? input, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out System.Net.Http.Headers.StringWithQualityHeaderValue? parsedValue) { throw null; } } public partial class TransferCodingHeaderValue : System.ICloneable { @@ -650,37 +653,37 @@ namespace System.Net.Http.Headers public TransferCodingHeaderValue(string value) { } public System.Collections.Generic.ICollection Parameters { get { throw null; } } public string Value { get { throw null; } } - public override bool Equals(object obj) { throw null; } + public override bool Equals(object? obj) { throw null; } public override int GetHashCode() { throw null; } - public static System.Net.Http.Headers.TransferCodingHeaderValue Parse(string input) { throw null; } + public static System.Net.Http.Headers.TransferCodingHeaderValue Parse(string? input) { throw null; } object System.ICloneable.Clone() { throw null; } public override string ToString() { throw null; } - public static bool TryParse(string input, out System.Net.Http.Headers.TransferCodingHeaderValue parsedValue) { throw null; } + public static bool TryParse(string? input, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out System.Net.Http.Headers.TransferCodingHeaderValue? parsedValue) { throw null; } } public sealed partial class TransferCodingWithQualityHeaderValue : System.Net.Http.Headers.TransferCodingHeaderValue, System.ICloneable { public TransferCodingWithQualityHeaderValue(string value) : base (default(System.Net.Http.Headers.TransferCodingHeaderValue)) { } public TransferCodingWithQualityHeaderValue(string value, double quality) : base (default(System.Net.Http.Headers.TransferCodingHeaderValue)) { } public double? Quality { get { throw null; } set { } } - public static new System.Net.Http.Headers.TransferCodingWithQualityHeaderValue Parse(string input) { throw null; } + public static new System.Net.Http.Headers.TransferCodingWithQualityHeaderValue Parse(string? input) { throw null; } object System.ICloneable.Clone() { throw null; } - public static bool TryParse(string input, out System.Net.Http.Headers.TransferCodingWithQualityHeaderValue parsedValue) { throw null; } + public static bool TryParse(string? input, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out System.Net.Http.Headers.TransferCodingWithQualityHeaderValue? parsedValue) { throw null; } } public partial class ViaHeaderValue : System.ICloneable { public ViaHeaderValue(string protocolVersion, string receivedBy) { } - public ViaHeaderValue(string protocolVersion, string receivedBy, string protocolName) { } - public ViaHeaderValue(string protocolVersion, string receivedBy, string protocolName, string comment) { } - public string Comment { get { throw null; } } - public string ProtocolName { get { throw null; } } + public ViaHeaderValue(string protocolVersion, string receivedBy, string? protocolName) { } + public ViaHeaderValue(string protocolVersion, string receivedBy, string? protocolName, string? comment) { } + public string? Comment { get { throw null; } } + public string? ProtocolName { get { throw null; } } public string ProtocolVersion { get { throw null; } } public string ReceivedBy { get { throw null; } } - public override bool Equals(object obj) { throw null; } + public override bool Equals(object? obj) { throw null; } public override int GetHashCode() { throw null; } - public static System.Net.Http.Headers.ViaHeaderValue Parse(string input) { throw null; } + public static System.Net.Http.Headers.ViaHeaderValue Parse(string? input) { throw null; } object System.ICloneable.Clone() { throw null; } public override string ToString() { throw null; } - public static bool TryParse(string input, out System.Net.Http.Headers.ViaHeaderValue parsedValue) { throw null; } + public static bool TryParse(string? input, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out System.Net.Http.Headers.ViaHeaderValue? parsedValue) { throw null; } } public partial class WarningHeaderValue : System.ICloneable { @@ -690,11 +693,11 @@ namespace System.Net.Http.Headers public int Code { get { throw null; } } public System.DateTimeOffset? Date { get { throw null; } } public string Text { get { throw null; } } - public override bool Equals(object obj) { throw null; } + public override bool Equals(object? obj) { throw null; } public override int GetHashCode() { throw null; } - public static System.Net.Http.Headers.WarningHeaderValue Parse(string input) { throw null; } + public static System.Net.Http.Headers.WarningHeaderValue Parse(string? input) { throw null; } object System.ICloneable.Clone() { throw null; } public override string ToString() { throw null; } - public static bool TryParse(string input, out System.Net.Http.Headers.WarningHeaderValue parsedValue) { throw null; } + public static bool TryParse(string? input, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out System.Net.Http.Headers.WarningHeaderValue? parsedValue) { throw null; } } } diff --git a/src/libraries/System.Net.Http/ref/System.Net.Http.csproj b/src/libraries/System.Net.Http/ref/System.Net.Http.csproj index 0a4ab50..9f96fca 100644 --- a/src/libraries/System.Net.Http/ref/System.Net.Http.csproj +++ b/src/libraries/System.Net.Http/ref/System.Net.Http.csproj @@ -1,6 +1,7 @@ $(NetCoreAppCurrent) + enable diff --git a/src/libraries/System.Net.Http/src/System.Net.Http.csproj b/src/libraries/System.Net.Http/src/System.Net.Http.csproj index 98aa395..669571d 100644 --- a/src/libraries/System.Net.Http/src/System.Net.Http.csproj +++ b/src/libraries/System.Net.Http/src/System.Net.Http.csproj @@ -8,6 +8,7 @@ true $(DefineConstants);HTTP_DLL $(NetCoreAppCurrent)-Windows_NT;$(NetCoreAppCurrent)-Linux;$(NetCoreAppCurrent)-OSX;$(NetCoreAppCurrent)-iOS + enable $(DefineConstants);SYSNETHTTP_NO_OPENSSL diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/ByteArrayContent.cs b/src/libraries/System.Net.Http/src/System/Net/Http/ByteArrayContent.cs index c6e85c0..9b1e9b0 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/ByteArrayContent.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/ByteArrayContent.cs @@ -51,10 +51,10 @@ namespace System.Net.Http SetBuffer(_content, _offset, _count); } - protected override Task SerializeToStreamAsync(Stream stream, TransportContext context) => + protected override Task SerializeToStreamAsync(Stream stream, TransportContext? context) => SerializeToStreamAsyncCore(stream, default); - protected override Task SerializeToStreamAsync(Stream stream, TransportContext context, CancellationToken cancellationToken) => + protected override Task SerializeToStreamAsync(Stream stream, TransportContext? context, CancellationToken cancellationToken) => // Only skip the original protected virtual SerializeToStreamAsync if this // isn't a derived type that may have overridden the behavior. GetType() == typeof(ByteArrayContent) ? SerializeToStreamAsyncCore(stream, cancellationToken) : @@ -72,7 +72,7 @@ namespace System.Net.Http protected override Task CreateContentReadStreamAsync() => Task.FromResult(CreateMemoryStreamForByteArray()); - internal override Stream TryCreateContentReadStream() => + internal override Stream? TryCreateContentReadStream() => GetType() == typeof(ByteArrayContent) ? CreateMemoryStreamForByteArray() : // type check ensures we use possible derived type's CreateContentReadStreamAsync override null; diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/DelegatingHandler.cs b/src/libraries/System.Net.Http/src/System/Net/Http/DelegatingHandler.cs index eb3651b..7fb7b5e 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/DelegatingHandler.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/DelegatingHandler.cs @@ -7,16 +7,18 @@ using System.Collections.Generic; using System.Text; using System.Threading; using System.Threading.Tasks; +using System.Diagnostics.CodeAnalysis; namespace System.Net.Http { public abstract class DelegatingHandler : HttpMessageHandler { - private HttpMessageHandler _innerHandler; + private HttpMessageHandler? _innerHandler; private volatile bool _operationStarted = false; private volatile bool _disposed = false; - public HttpMessageHandler InnerHandler + [DisallowNull] + public HttpMessageHandler? InnerHandler { get { @@ -51,7 +53,7 @@ namespace System.Net.Http throw new ArgumentNullException(nameof(request), SR.net_http_handler_norequest); } SetOperationStarted(); - return _innerHandler.SendAsync(request, cancellationToken); + return _innerHandler!.SendAsync(request, cancellationToken); } protected override void Dispose(bool disposing) diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/DiagnosticsHandler.cs b/src/libraries/System.Net.Http/src/System/Net/Http/DiagnosticsHandler.cs index 682e91c..3e4cf7f 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/DiagnosticsHandler.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/DiagnosticsHandler.cs @@ -45,7 +45,7 @@ namespace System.Net.Http throw new ArgumentNullException(nameof(request), SR.net_http_handler_norequest); } - Activity activity = null; + Activity? activity = null; // if there is no listener, but propagation is enabled (with previous IsEnabled() check) // do not write any events just start/stop Activity and propagate Ids @@ -92,13 +92,13 @@ namespace System.Net.Http } // If we are on at all, we propagate current activity information - Activity currentActivity = Activity.Current; + Activity? currentActivity = Activity.Current; if (currentActivity != null) { InjectHeaders(currentActivity, request); } - Task responseTask = null; + Task? responseTask = null; try { responseTask = base.SendAsync(request, cancellationToken); @@ -164,14 +164,14 @@ namespace System.Net.Http private sealed class ActivityStopData { - internal ActivityStopData(HttpResponseMessage response, HttpRequestMessage request, TaskStatus requestTaskStatus) + internal ActivityStopData(HttpResponseMessage? response, HttpRequestMessage request, TaskStatus requestTaskStatus) { Response = response; Request = request; RequestTaskStatus = requestTaskStatus; } - public HttpResponseMessage Response { get; } + public HttpResponseMessage? Response { get; } public HttpRequestMessage Request { get; } public TaskStatus RequestTaskStatus { get; } @@ -210,7 +210,7 @@ namespace System.Net.Http private sealed class ResponseData { - internal ResponseData(HttpResponseMessage response, Guid loggingRequestId, long timestamp, TaskStatus requestTaskStatus) + internal ResponseData(HttpResponseMessage? response, Guid loggingRequestId, long timestamp, TaskStatus requestTaskStatus) { Response = response; LoggingRequestId = loggingRequestId; @@ -218,7 +218,7 @@ namespace System.Net.Http RequestTaskStatus = requestTaskStatus; } - public HttpResponseMessage Response { get; } + public HttpResponseMessage? Response { get; } public Guid LoggingRequestId { get; } public long Timestamp { get; } public TaskStatus RequestTaskStatus { get; } @@ -240,7 +240,7 @@ namespace System.Net.Http } // AppContext switch wasn't used. Check the environment variable to determine which handler should be used. - string envVar = Environment.GetEnvironmentVariable(EnableActivityPropagationEnvironmentVariableSettingName); + string? envVar = Environment.GetEnvironmentVariable(EnableActivityPropagationEnvironmentVariableSettingName); if (envVar != null && (envVar.Equals("false", StringComparison.OrdinalIgnoreCase) || envVar.Equals("0"))) { // Suppress Activity propagation. @@ -273,14 +273,14 @@ namespace System.Net.Http } // we expect baggage to be empty or contain a few items - using (IEnumerator> e = currentActivity.Baggage.GetEnumerator()) + using (IEnumerator> e = currentActivity.Baggage.GetEnumerator()) { if (e.MoveNext()) { var baggage = new List(); do { - KeyValuePair item = e.Current; + KeyValuePair item = e.Current; baggage.Add(new NameValueHeaderValue(WebUtility.UrlEncode(item.Key), WebUtility.UrlEncode(item.Value)).ToString()); } while (e.MoveNext()); diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/FormUrlEncodedContent.cs b/src/libraries/System.Net.Http/src/System/Net/Http/FormUrlEncodedContent.cs index 85051d1..7ca4a99 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/FormUrlEncodedContent.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/FormUrlEncodedContent.cs @@ -13,13 +13,13 @@ namespace System.Net.Http { public class FormUrlEncodedContent : ByteArrayContent { - public FormUrlEncodedContent(IEnumerable> nameValueCollection) + public FormUrlEncodedContent(IEnumerable> nameValueCollection) : base(GetContentByteArray(nameValueCollection)) { Headers.ContentType = new MediaTypeHeaderValue("application/x-www-form-urlencoded"); } - private static byte[] GetContentByteArray(IEnumerable> nameValueCollection) + private static byte[] GetContentByteArray(IEnumerable> nameValueCollection) { if (nameValueCollection == null) { @@ -28,7 +28,7 @@ namespace System.Net.Http // Encode and concatenate data StringBuilder builder = new StringBuilder(); - foreach (KeyValuePair pair in nameValueCollection) + foreach (KeyValuePair pair in nameValueCollection) { if (builder.Length > 0) { @@ -43,7 +43,7 @@ namespace System.Net.Http return HttpRuleParser.DefaultHttpEncoding.GetBytes(builder.ToString()); } - private static string Encode(string data) + private static string Encode(string? data) { if (string.IsNullOrEmpty(data)) { @@ -53,13 +53,13 @@ namespace System.Net.Http return Uri.EscapeDataString(data).Replace("%20", "+"); } - protected override Task SerializeToStreamAsync(Stream stream, TransportContext context, CancellationToken cancellationToken) => + protected override Task SerializeToStreamAsync(Stream stream, TransportContext? context, CancellationToken cancellationToken) => // Only skip the original protected virtual SerializeToStreamAsync if this // isn't a derived type that may have overridden the behavior. GetType() == typeof(FormUrlEncodedContent) ? SerializeToStreamAsyncCore(stream, cancellationToken) : base.SerializeToStreamAsync(stream, context, cancellationToken); - internal override Stream TryCreateContentReadStream() => + internal override Stream? TryCreateContentReadStream() => GetType() == typeof(FormUrlEncodedContent) ? CreateMemoryStreamForByteArray() : // type check ensures we use possible derived type's CreateContentReadStreamAsync override null; } diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/AltSvcHeaderParser.cs b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/AltSvcHeaderParser.cs index b51ff21..9990f48 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/AltSvcHeaderParser.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/AltSvcHeaderParser.cs @@ -5,6 +5,7 @@ using System; using System.Collections.Generic; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Resources; using System.Text; @@ -27,8 +28,8 @@ namespace System.Net.Http.Headers { } - protected override int GetParsedValueLength(string value, int startIndex, object storeValue, - out object parsedValue) + protected override int GetParsedValueLength(string value, int startIndex, object? storeValue, + out object? parsedValue) { Debug.Assert(startIndex >= 0); Debug.Assert(startIndex < value.Length); @@ -41,7 +42,7 @@ namespace System.Net.Http.Headers int idx = startIndex; - if (!TryReadPercentEncodedAlpnProtocolName(value, idx, out string alpnProtocolName, out int alpnProtocolNameLength)) + if (!TryReadPercentEncodedAlpnProtocolName(value, idx, out string? alpnProtocolName, out int alpnProtocolNameLength)) { parsedValue = null; return 0; @@ -68,7 +69,7 @@ namespace System.Net.Http.Headers return 0; } - if (!TryReadQuotedAltAuthority(value, idx, out string altAuthorityHost, out int altAuthorityPort, out int altAuthorityLength)) + if (!TryReadQuotedAltAuthority(value, idx, out string? altAuthorityHost, out int altAuthorityPort, out int altAuthorityLength)) { parsedValue = null; return 0; @@ -189,7 +190,7 @@ namespace System.Net.Http.Headers return ch == ' ' || ch == '\t'; } - private static bool TryReadPercentEncodedAlpnProtocolName(string value, int startIndex, out string result, out int readLength) + private static bool TryReadPercentEncodedAlpnProtocolName(string value, int startIndex, [NotNullWhen(true)] out string? result, out int readLength) { int tokenLength = HttpRuleParser.GetTokenLength(value, startIndex); @@ -260,7 +261,7 @@ namespace System.Net.Http.Headers return TryReadUnknownPercentEncodedAlpnProtocolName(span, out result); } - private static bool TryReadUnknownPercentEncodedAlpnProtocolName(ReadOnlySpan value, out string result) + private static bool TryReadUnknownPercentEncodedAlpnProtocolName(ReadOnlySpan value, [NotNullWhen(true)] out string? result) { int idx = value.IndexOf('%'); @@ -322,7 +323,7 @@ namespace System.Net.Http.Headers return false; } - private static bool TryReadQuotedAltAuthority(string value, int startIndex, out string host, out int port, out int readLength) + private static bool TryReadQuotedAltAuthority(string value, int startIndex, out string? host, out int port, out int readLength) { if (HttpRuleParser.GetQuotedStringLength(value, startIndex, out int quotedLength) != HttpParseResult.Parsed) { @@ -364,7 +365,7 @@ namespace System.Net.Http.Headers return false; } - private static bool TryReadQuotedValue(ReadOnlySpan value, out string result) + private static bool TryReadQuotedValue(ReadOnlySpan value, out string? result) { int idx = value.IndexOf('\\'); diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/AltSvcHeaderValue.cs b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/AltSvcHeaderValue.cs index f6d84bf..39dfed8 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/AltSvcHeaderValue.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/AltSvcHeaderValue.cs @@ -13,7 +13,7 @@ namespace System.Net.Http.Headers { public static AltSvcHeaderValue Clear { get; } = new AltSvcHeaderValue("clear", host: null, port: 0, maxAge: TimeSpan.Zero, persist: false); - public AltSvcHeaderValue(string alpnProtocolName, string host, int port, TimeSpan maxAge, bool persist) + public AltSvcHeaderValue(string alpnProtocolName, string? host, int port, TimeSpan maxAge, bool persist) { AlpnProtocolName = alpnProtocolName; Host = host; @@ -28,7 +28,7 @@ namespace System.Net.Http.Headers /// The name of the host serving this alternate service. /// If null, the alternate service is on the same host this header was received from. /// - public string Host { get; } + public string? Host { get; } public int Port { get; } diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/AuthenticationHeaderValue.cs b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/AuthenticationHeaderValue.cs index 5eaa822..4959ac9 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/AuthenticationHeaderValue.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/AuthenticationHeaderValue.cs @@ -3,13 +3,14 @@ // See the LICENSE file in the project root for more information. using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; namespace System.Net.Http.Headers { public class AuthenticationHeaderValue : ICloneable { - private string _scheme; - private string _parameter; + private string _scheme = null!; + private string? _parameter; public string Scheme { @@ -25,7 +26,7 @@ namespace System.Net.Http.Headers // Due to Base64 encoding we have two final "=". The value is neither a token nor a quoted-string, so it must // be an auth-param according to the RFC definition. But that's also incorrect: auth-param means that we // consider the value before the first "=" as "name" and the final "=" as "value". - public string Parameter + public string? Parameter { get { return _parameter; } } @@ -35,7 +36,7 @@ namespace System.Net.Http.Headers { } - public AuthenticationHeaderValue(string scheme, string parameter) + public AuthenticationHeaderValue(string scheme, string? parameter) { HeaderUtilities.CheckValidToken(scheme, nameof(scheme)); _scheme = scheme; @@ -63,9 +64,9 @@ namespace System.Net.Http.Headers return _scheme + " " + _parameter; } - public override bool Equals(object obj) + public override bool Equals(object? obj) { - AuthenticationHeaderValue other = obj as AuthenticationHeaderValue; + AuthenticationHeaderValue? other = obj as AuthenticationHeaderValue; if (other == null) { @@ -96,20 +97,19 @@ namespace System.Net.Http.Headers return result; } - public static AuthenticationHeaderValue Parse(string input) + public static AuthenticationHeaderValue Parse(string? input) { int index = 0; return (AuthenticationHeaderValue)GenericHeaderParser.SingleValueAuthenticationParser.ParseValue( input, null, ref index); } - public static bool TryParse(string input, out AuthenticationHeaderValue parsedValue) + public static bool TryParse(string? input, [NotNullWhen(true)] out AuthenticationHeaderValue? parsedValue) { int index = 0; - object output; parsedValue = null; - if (GenericHeaderParser.SingleValueAuthenticationParser.TryParseValue(input, null, ref index, out output)) + if (GenericHeaderParser.SingleValueAuthenticationParser.TryParseValue(input, null, ref index, out object? output)) { parsedValue = (AuthenticationHeaderValue)output; return true; @@ -117,7 +117,7 @@ namespace System.Net.Http.Headers return false; } - internal static int GetAuthenticationLength(string input, int startIndex, out object parsedValue) + internal static int GetAuthenticationLength(string? input, int startIndex, out object? parsedValue) { Debug.Assert(startIndex >= 0); @@ -137,7 +137,7 @@ namespace System.Net.Http.Headers } var result = new AuthenticationHeaderValue(); - string targetScheme = null; + string? targetScheme = null; switch (schemeLength) { // Avoid allocating a scheme string for the most common cases. diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/BaseHeaderParser.cs b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/BaseHeaderParser.cs index 0b4162c..ea0a5cc 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/BaseHeaderParser.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/BaseHeaderParser.cs @@ -3,6 +3,7 @@ // See the LICENSE file in the project root for more information. using System; +using System.Diagnostics.CodeAnalysis; namespace System.Net.Http.Headers { @@ -21,11 +22,11 @@ namespace System.Net.Http.Headers /// /// The resulting value parsed. /// If a value could be parsed, the number of characters used to parse that value. Otherwise, 0. - protected abstract int GetParsedValueLength(string value, int startIndex, object storeValue, - out object parsedValue); + protected abstract int GetParsedValueLength(string value, int startIndex, object? storeValue, + out object? parsedValue); - public sealed override bool TryParseValue(string value, object storeValue, ref int index, - out object parsedValue) + public sealed override bool TryParseValue(string? value, object? storeValue, ref int index, + [NotNullWhen(true)] out object? parsedValue) { parsedValue = null; @@ -57,8 +58,7 @@ namespace System.Net.Http.Headers return SupportsMultipleValues; } - object result = null; - int length = GetParsedValueLength(value, current, storeValue, out result); + int length = GetParsedValueLength(value, current, storeValue, out object? result); if (length == 0) { @@ -76,7 +76,7 @@ namespace System.Net.Http.Headers } index = current; - parsedValue = result; + parsedValue = result!; return true; } } diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/ByteArrayHeaderParser.cs b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/ByteArrayHeaderParser.cs index b4e24e4..3519356 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/ByteArrayHeaderParser.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/ByteArrayHeaderParser.cs @@ -3,6 +3,7 @@ // See the LICENSE file in the project root for more information. using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; namespace System.Net.Http.Headers { @@ -24,7 +25,7 @@ namespace System.Net.Http.Headers return Convert.ToBase64String((byte[])value); } - public override bool TryParseValue(string value, object storeValue, ref int index, out object parsedValue) + public override bool TryParseValue(string? value, object? storeValue, ref int index, [NotNullWhen(true)] out object? parsedValue) { parsedValue = null; diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/CacheControlHeaderParser.cs b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/CacheControlHeaderParser.cs index b3f6ed2..6c312dc 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/CacheControlHeaderParser.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/CacheControlHeaderParser.cs @@ -20,10 +20,10 @@ namespace System.Net.Http.Headers { } - protected override int GetParsedValueLength(string value, int startIndex, object storeValue, - out object parsedValue) + protected override int GetParsedValueLength(string value, int startIndex, object? storeValue, + out object? parsedValue) { - CacheControlHeaderValue temp = storeValue as CacheControlHeaderValue; + CacheControlHeaderValue? temp = storeValue as CacheControlHeaderValue; Debug.Assert(storeValue == null || temp != null, "'storeValue' is not of type CacheControlHeaderValue"); int resultLength = CacheControlHeaderValue.GetCacheControlLength(value, startIndex, temp, out temp); diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/CacheControlHeaderValue.cs b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/CacheControlHeaderValue.cs index 83b3cb2..fee7d4a 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/CacheControlHeaderValue.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/CacheControlHeaderValue.cs @@ -4,6 +4,7 @@ using System.Collections.Generic; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.IO; using System.Text; @@ -29,7 +30,7 @@ namespace System.Net.Http.Headers private static readonly Action s_checkIsValidToken = CheckIsValidToken; private bool _noCache; - private ObjectCollection _noCacheHeaders; + private ObjectCollection? _noCacheHeaders; private bool _noStore; private TimeSpan? _maxAge; private TimeSpan? _sharedMaxAge; @@ -40,10 +41,10 @@ namespace System.Net.Http.Headers private bool _onlyIfCached; private bool _publicField; private bool _privateField; - private ObjectCollection _privateHeaders; + private ObjectCollection? _privateHeaders; private bool _mustRevalidate; private bool _proxyRevalidate; - private ObjectCollection _extensions; + private ObjectCollection? _extensions; public bool NoCache { @@ -315,9 +316,9 @@ namespace System.Net.Http.Headers return StringBuilderCache.GetStringAndRelease(sb); } - public override bool Equals(object obj) + public override bool Equals(object? obj) { - CacheControlHeaderValue other = obj as CacheControlHeaderValue; + CacheControlHeaderValue? other = obj as CacheControlHeaderValue; if (other == null) { @@ -398,19 +399,18 @@ namespace System.Net.Http.Headers return result; } - public static CacheControlHeaderValue Parse(string input) + public static CacheControlHeaderValue Parse(string? input) { int index = 0; return (CacheControlHeaderValue)CacheControlHeaderParser.Parser.ParseValue(input, null, ref index); } - public static bool TryParse(string input, out CacheControlHeaderValue parsedValue) + public static bool TryParse(string? input, [NotNullWhen(true)] out CacheControlHeaderValue? parsedValue) { int index = 0; - object output; parsedValue = null; - if (CacheControlHeaderParser.Parser.TryParseValue(input, null, ref index, out output)) + if (CacheControlHeaderParser.Parser.TryParseValue(input, null, ref index, out object? output)) { parsedValue = (CacheControlHeaderValue)output; return true; @@ -418,8 +418,8 @@ namespace System.Net.Http.Headers return false; } - internal static int GetCacheControlLength(string input, int startIndex, CacheControlHeaderValue storeValue, - out CacheControlHeaderValue parsedValue) + internal static int GetCacheControlLength(string? input, int startIndex, CacheControlHeaderValue? storeValue, + out CacheControlHeaderValue? parsedValue) { Debug.Assert(startIndex >= 0); @@ -433,7 +433,7 @@ namespace System.Net.Http.Headers // Cache-Control header consists of a list of name/value pairs, where the value is optional. So use an // instance of NameValueHeaderParser to parse the string. int current = startIndex; - object nameValue = null; + object? nameValue; List nameValueList = new List(); while (current < input.Length) { @@ -442,7 +442,7 @@ namespace System.Net.Http.Headers return 0; } - nameValueList.Add(nameValue as NameValueHeaderValue); + nameValueList.Add((NameValueHeaderValue)nameValue); } // If we get here, we were able to successfully parse the string as list of name/value pairs. Now analyze @@ -451,7 +451,7 @@ namespace System.Net.Http.Headers // Cache-Control is a header supporting lists of values. However, expose the header as an instance of // CacheControlHeaderValue. So if we already have an instance of CacheControlHeaderValue, add the values // from this string to the existing instances. - CacheControlHeaderValue result = storeValue; + CacheControlHeaderValue? result = storeValue; if (result == null) { result = new CacheControlHeaderValue(); @@ -562,7 +562,7 @@ namespace System.Net.Http.Headers } private static bool TrySetOptionalTokenList(NameValueHeaderValue nameValue, ref bool boolField, - ref ObjectCollection destination) + ref ObjectCollection? destination) { Debug.Assert(nameValue != null); diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/ContentDispositionHeaderValue.cs b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/ContentDispositionHeaderValue.cs index a999f77..06b19e7 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/ContentDispositionHeaderValue.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/ContentDispositionHeaderValue.cs @@ -4,6 +4,7 @@ using System.Collections.Generic; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.Text; @@ -22,8 +23,8 @@ namespace System.Net.Http.Headers private const string size = "size"; // Use ObjectCollection since we may have multiple parameters with the same name. - private ObjectCollection _parameters; - private string _dispositionType; + private ObjectCollection? _parameters; + private string _dispositionType = null!; #endregion Fields @@ -51,19 +52,19 @@ namespace System.Net.Http.Headers } } - public string Name + public string? Name { get { return GetName(name); } set { SetName(name, value); } } - public string FileName + public string? FileName { get { return GetName(fileName); } set { SetName(fileName, value); } } - public string FileNameStar + public string? FileNameStar { get { return GetName(fileNameStar); } set { SetName(fileNameStar, value); } @@ -91,11 +92,11 @@ namespace System.Net.Http.Headers { get { - NameValueHeaderValue sizeParameter = NameValueHeaderValue.Find(_parameters, size); + NameValueHeaderValue? sizeParameter = NameValueHeaderValue.Find(_parameters, size); ulong value; if (sizeParameter != null) { - string sizeString = sizeParameter.Value; + string? sizeString = sizeParameter.Value; if (ulong.TryParse(sizeString, NumberStyles.Integer, CultureInfo.InvariantCulture, out value)) { return (long)value; @@ -105,13 +106,13 @@ namespace System.Net.Http.Headers } set { - NameValueHeaderValue sizeParameter = NameValueHeaderValue.Find(_parameters, size); + NameValueHeaderValue? sizeParameter = NameValueHeaderValue.Find(_parameters, size); if (value == null) { // Remove parameter. if (sizeParameter != null) { - _parameters.Remove(sizeParameter); + _parameters!.Remove(sizeParameter); } } else if (value < 0) @@ -172,9 +173,9 @@ namespace System.Net.Http.Headers return StringBuilderCache.GetStringAndRelease(sb); } - public override bool Equals(object obj) + public override bool Equals(object? obj) { - ContentDispositionHeaderValue other = obj as ContentDispositionHeaderValue; + ContentDispositionHeaderValue? other = obj as ContentDispositionHeaderValue; if (other == null) { @@ -201,20 +202,19 @@ namespace System.Net.Http.Headers #region Parsing - public static ContentDispositionHeaderValue Parse(string input) + public static ContentDispositionHeaderValue Parse(string? input) { int index = 0; return (ContentDispositionHeaderValue)GenericHeaderParser.ContentDispositionParser.ParseValue(input, null, ref index); } - public static bool TryParse(string input, out ContentDispositionHeaderValue parsedValue) + public static bool TryParse(string? input, [NotNullWhen(true)] out ContentDispositionHeaderValue? parsedValue) { int index = 0; - object output; parsedValue = null; - if (GenericHeaderParser.ContentDispositionParser.TryParseValue(input, null, ref index, out output)) + if (GenericHeaderParser.ContentDispositionParser.TryParseValue(input, null, ref index, out object? output)) { parsedValue = (ContentDispositionHeaderValue)output; return true; @@ -222,7 +222,7 @@ namespace System.Net.Http.Headers return false; } - internal static int GetDispositionTypeLength(string input, int startIndex, out object parsedValue) + internal static int GetDispositionTypeLength(string? input, int startIndex, out object? parsedValue) { Debug.Assert(startIndex >= 0); @@ -234,7 +234,7 @@ namespace System.Net.Http.Headers } // Caller must remove leading whitespace. If not, we'll return 0. - string dispositionType = null; + string? dispositionType; int dispositionTypeLength = GetDispositionTypeExpressionLength(input, startIndex, out dispositionType); if (dispositionTypeLength == 0) @@ -245,7 +245,7 @@ namespace System.Net.Http.Headers int current = startIndex + dispositionTypeLength; current = current + HttpRuleParser.GetWhitespaceLength(input, current); ContentDispositionHeaderValue contentDispositionHeader = new ContentDispositionHeaderValue(); - contentDispositionHeader._dispositionType = dispositionType; + contentDispositionHeader._dispositionType = dispositionType!; // If we're not done and we have a parameter delimiter, then we have a list of parameters. if ((current < input.Length) && (input[current] == ';')) @@ -268,7 +268,7 @@ namespace System.Net.Http.Headers return current - startIndex; } - private static int GetDispositionTypeExpressionLength(string input, int startIndex, out string dispositionType) + private static int GetDispositionTypeExpressionLength(string input, int startIndex, out string? dispositionType) { Debug.Assert((input != null) && (input.Length > 0) && (startIndex < input.Length)); @@ -296,9 +296,8 @@ namespace System.Net.Http.Headers } // When adding values using strongly typed objects, no leading/trailing LWS (whitespace) are allowed. - string tempDispositionType; - int dispositionTypeLength = GetDispositionTypeExpressionLength(dispositionType, 0, out tempDispositionType); - if ((dispositionTypeLength == 0) || (tempDispositionType.Length != dispositionType.Length)) + int dispositionTypeLength = GetDispositionTypeExpressionLength(dispositionType, 0, out string? tempDispositionType); + if ((dispositionTypeLength == 0) || (tempDispositionType!.Length != dispositionType.Length)) { throw new FormatException(SR.Format(System.Globalization.CultureInfo.InvariantCulture, SR.net_http_headers_invalid_value, dispositionType)); @@ -313,7 +312,7 @@ namespace System.Net.Http.Headers // Returns null if the parameter is not present or the format is incorrect. private DateTimeOffset? GetDate(string parameter) { - NameValueHeaderValue dateParameter = NameValueHeaderValue.Find(_parameters, parameter); + NameValueHeaderValue? dateParameter = NameValueHeaderValue.Find(_parameters, parameter); DateTimeOffset date; if (dateParameter != null) { @@ -334,13 +333,13 @@ namespace System.Net.Http.Headers // Add the given parameter to the list. Remove if date is null. private void SetDate(string parameter, DateTimeOffset? date) { - NameValueHeaderValue dateParameter = NameValueHeaderValue.Find(_parameters, parameter); + NameValueHeaderValue? dateParameter = NameValueHeaderValue.Find(_parameters, parameter); if (date == null) { // Remove parameter. if (dateParameter != null) { - _parameters.Remove(dateParameter); + _parameters!.Remove(dateParameter); } } else @@ -360,15 +359,16 @@ namespace System.Net.Http.Headers // Gets a parameter of the given name and attempts to decode it if necessary. // Returns null if the parameter is not present or the raw value if the encoding is incorrect. - private string GetName(string parameter) + private string? GetName(string parameter) { - NameValueHeaderValue nameParameter = NameValueHeaderValue.Find(_parameters, parameter); + NameValueHeaderValue? nameParameter = NameValueHeaderValue.Find(_parameters, parameter); if (nameParameter != null) { - string result; + string? result; // filename*=utf-8'lang'%7FMyString if (parameter.EndsWith('*')) { + Debug.Assert(nameParameter.Value != null); if (TryDecode5987(nameParameter.Value, out result)) { return result; @@ -389,15 +389,15 @@ namespace System.Net.Http.Headers // Add/update the given parameter in the list, encoding if necessary. // Remove if value is null/Empty - private void SetName(string parameter, string value) + private void SetName(string parameter, string? value) { - NameValueHeaderValue nameParameter = NameValueHeaderValue.Find(_parameters, parameter); + NameValueHeaderValue? nameParameter = NameValueHeaderValue.Find(_parameters, parameter); if (string.IsNullOrEmpty(value)) { // Remove parameter. if (nameParameter != null) { - _parameters.Remove(nameParameter); + _parameters!.Remove(nameParameter); } } else @@ -476,12 +476,12 @@ namespace System.Net.Http.Headers } // Attempt to decode MIME encoded strings. - private static bool TryDecodeMime(string input, out string output) + private static bool TryDecodeMime(string? input, [NotNullWhen(true)] out string? output) { Debug.Assert(input != null); output = null; - string processedInput = input; + string? processedInput = input; // Require quotes, min of "=?e?b??=" if (!IsQuoted(processedInput) || processedInput.Length < 10) { @@ -519,7 +519,7 @@ namespace System.Net.Http.Headers // Attempt to decode using RFC 5987 encoding. // encoding'language'my%20string - private static bool TryDecode5987(string input, out string output) + private static bool TryDecode5987(string input, out string? output) { output = null; diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/ContentRangeHeaderValue.cs b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/ContentRangeHeaderValue.cs index 05362b0..6fa9a53 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/ContentRangeHeaderValue.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/ContentRangeHeaderValue.cs @@ -3,6 +3,7 @@ // See the LICENSE file in the project root for more information. using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.IO; using System.Text; @@ -11,7 +12,7 @@ namespace System.Net.Http.Headers { public class ContentRangeHeaderValue : ICloneable { - private string _unit; + private string _unit = null!; private long? _from; private long? _to; private long? _length; @@ -119,9 +120,9 @@ namespace System.Net.Http.Headers _unit = source._unit; } - public override bool Equals(object obj) + public override bool Equals(object? obj) { - ContentRangeHeaderValue other = obj as ContentRangeHeaderValue; + ContentRangeHeaderValue? other = obj as ContentRangeHeaderValue; if (other == null) { @@ -157,8 +158,9 @@ namespace System.Net.Http.Headers if (HasRange) { - sb.Append(_from.Value); + sb.Append(_from!.Value); sb.Append('-'); + Debug.Assert(_to.HasValue); sb.Append(_to.Value); } else @@ -169,7 +171,7 @@ namespace System.Net.Http.Headers sb.Append('/'); if (HasLength) { - sb.Append(_length.Value); + sb.Append(_length!.Value); } else { @@ -179,19 +181,18 @@ namespace System.Net.Http.Headers return StringBuilderCache.GetStringAndRelease(sb); } - public static ContentRangeHeaderValue Parse(string input) + public static ContentRangeHeaderValue Parse(string? input) { int index = 0; return (ContentRangeHeaderValue)GenericHeaderParser.ContentRangeParser.ParseValue(input, null, ref index); } - public static bool TryParse(string input, out ContentRangeHeaderValue parsedValue) + public static bool TryParse(string? input, [NotNullWhen(true)] out ContentRangeHeaderValue? parsedValue) { int index = 0; - object output; parsedValue = null; - if (GenericHeaderParser.ContentRangeParser.TryParseValue(input, null, ref index, out output)) + if (GenericHeaderParser.ContentRangeParser.TryParseValue(input, null, ref index, out object? output)) { parsedValue = (ContentRangeHeaderValue)output; return true; @@ -199,7 +200,7 @@ namespace System.Net.Http.Headers return false; } - internal static int GetContentRangeLength(string input, int startIndex, out object parsedValue) + internal static int GetContentRangeLength(string? input, int startIndex, out object? parsedValue) { Debug.Assert(startIndex >= 0); @@ -358,7 +359,7 @@ namespace System.Net.Http.Headers } private static bool TryCreateContentRange(string input, string unit, int fromStartIndex, int fromLength, - int toStartIndex, int toLength, int lengthStartIndex, int lengthLength, out object parsedValue) + int toStartIndex, int toLength, int lengthStartIndex, int lengthLength, [NotNullWhen(true)] out object? parsedValue) { parsedValue = null; diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/DateHeaderParser.cs b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/DateHeaderParser.cs index 9fc560a..cb3e5ad 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/DateHeaderParser.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/DateHeaderParser.cs @@ -3,6 +3,7 @@ // See the LICENSE file in the project root for more information. using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; namespace System.Net.Http.Headers { @@ -24,7 +25,7 @@ namespace System.Net.Http.Headers return HttpDateParser.DateToString((DateTimeOffset)value); } - public override bool TryParseValue(string value, object storeValue, ref int index, out object parsedValue) + public override bool TryParseValue(string? value, object? storeValue, ref int index, [NotNullWhen(true)] out object? parsedValue) { parsedValue = null; diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/EntityTagHeaderValue.cs b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/EntityTagHeaderValue.cs index 57f893e..dcf1837 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/EntityTagHeaderValue.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/EntityTagHeaderValue.cs @@ -3,14 +3,15 @@ // See the LICENSE file in the project root for more information. using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; namespace System.Net.Http.Headers { public class EntityTagHeaderValue : ICloneable { - private static EntityTagHeaderValue s_any; + private static EntityTagHeaderValue? s_any; - private string _tag; + private string _tag = null!; private bool _isWeak; public string Tag @@ -82,9 +83,9 @@ namespace System.Net.Http.Headers return _tag; } - public override bool Equals(object obj) + public override bool Equals(object? obj) { - EntityTagHeaderValue other = obj as EntityTagHeaderValue; + EntityTagHeaderValue? other = obj as EntityTagHeaderValue; if (other == null) { @@ -101,20 +102,19 @@ namespace System.Net.Http.Headers return _tag.GetHashCode() ^ _isWeak.GetHashCode(); } - public static EntityTagHeaderValue Parse(string input) + public static EntityTagHeaderValue Parse(string? input) { int index = 0; return (EntityTagHeaderValue)GenericHeaderParser.SingleValueEntityTagParser.ParseValue( input, null, ref index); } - public static bool TryParse(string input, out EntityTagHeaderValue parsedValue) + public static bool TryParse(string? input, [NotNullWhen(true)] out EntityTagHeaderValue? parsedValue) { int index = 0; - object output; parsedValue = null; - if (GenericHeaderParser.SingleValueEntityTagParser.TryParseValue(input, null, ref index, out output)) + if (GenericHeaderParser.SingleValueEntityTagParser.TryParseValue(input, null, ref index, out object? output)) { parsedValue = (EntityTagHeaderValue)output; return true; @@ -122,7 +122,7 @@ namespace System.Net.Http.Headers return false; } - internal static int GetEntityTagLength(string input, int startIndex, out EntityTagHeaderValue parsedValue) + internal static int GetEntityTagLength(string? input, int startIndex, out EntityTagHeaderValue? parsedValue) { Debug.Assert(startIndex >= 0); diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/GenericHeaderParser.cs b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/GenericHeaderParser.cs index bf89184..c8cbe35 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/GenericHeaderParser.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/GenericHeaderParser.cs @@ -9,7 +9,7 @@ namespace System.Net.Http.Headers { internal sealed class GenericHeaderParser : BaseHeaderParser { - private delegate int GetParsedValueLengthDelegate(string value, int startIndex, out object parsedValue); + private delegate int GetParsedValueLengthDelegate(string value, int startIndex, out object? parsedValue); #region Parser instances @@ -41,9 +41,9 @@ namespace System.Net.Http.Headers #endregion private readonly GetParsedValueLengthDelegate _getParsedValueLength; - private readonly IEqualityComparer _comparer; + private readonly IEqualityComparer? _comparer; - public override IEqualityComparer Comparer + public override IEqualityComparer? Comparer { get { return _comparer; } } @@ -54,7 +54,7 @@ namespace System.Net.Http.Headers } private GenericHeaderParser(bool supportsMultipleValues, GetParsedValueLengthDelegate getParsedValueLength, - IEqualityComparer comparer) + IEqualityComparer? comparer) : base(supportsMultipleValues) { Debug.Assert(getParsedValueLength != null); @@ -63,38 +63,35 @@ namespace System.Net.Http.Headers _comparer = comparer; } - protected override int GetParsedValueLength(string value, int startIndex, object storeValue, - out object parsedValue) + protected override int GetParsedValueLength(string value, int startIndex, object? storeValue, + out object? parsedValue) { return _getParsedValueLength(value, startIndex, out parsedValue); } #region Parse methods - private static int ParseNameValue(string value, int startIndex, out object parsedValue) + private static int ParseNameValue(string value, int startIndex, out object? parsedValue) { - NameValueHeaderValue temp = null; - int resultLength = NameValueHeaderValue.GetNameValueLength(value, startIndex, out temp); + int resultLength = NameValueHeaderValue.GetNameValueLength(value, startIndex, out NameValueHeaderValue? temp); parsedValue = temp; return resultLength; } - private static int ParseProduct(string value, int startIndex, out object parsedValue) + private static int ParseProduct(string value, int startIndex, out object? parsedValue) { - ProductHeaderValue temp = null; - int resultLength = ProductHeaderValue.GetProductLength(value, startIndex, out temp); + int resultLength = ProductHeaderValue.GetProductLength(value, startIndex, out ProductHeaderValue? temp); parsedValue = temp; return resultLength; } - private static int ParseSingleEntityTag(string value, int startIndex, out object parsedValue) + private static int ParseSingleEntityTag(string value, int startIndex, out object? parsedValue) { - EntityTagHeaderValue temp = null; parsedValue = null; - int resultLength = EntityTagHeaderValue.GetEntityTagLength(value, startIndex, out temp); + int resultLength = EntityTagHeaderValue.GetEntityTagLength(value, startIndex, out EntityTagHeaderValue? temp); // If we don't allow '*' ("Any") as valid ETag value, return false (e.g. 'ETag' header) if (temp == EntityTagHeaderValue.Any) @@ -110,16 +107,15 @@ namespace System.Net.Http.Headers // the value must either be '*' or a list of ETag values. It's not allowed to have both '*' and a list of // ETag values. We're not that strict: We allow both '*' and ETag values in a list. If the server sends such // an invalid list, we want to be able to represent it using the corresponding header property. - private static int ParseMultipleEntityTags(string value, int startIndex, out object parsedValue) + private static int ParseMultipleEntityTags(string value, int startIndex, out object? parsedValue) { - EntityTagHeaderValue temp = null; - int resultLength = EntityTagHeaderValue.GetEntityTagLength(value, startIndex, out temp); + int resultLength = EntityTagHeaderValue.GetEntityTagLength(value, startIndex, out EntityTagHeaderValue? temp); parsedValue = temp; return resultLength; } - private static int ParseMailAddress(string value, int startIndex, out object parsedValue) + private static int ParseMailAddress(string value, int startIndex, out object? parsedValue) { parsedValue = null; @@ -139,10 +135,9 @@ namespace System.Net.Http.Headers return result.Length; } - private static int ParseHost(string value, int startIndex, out object parsedValue) + private static int ParseHost(string value, int startIndex, out object? parsedValue) { - string host = null; - int hostLength = HttpRuleParser.GetHostLength(value, startIndex, false, out host); + int hostLength = HttpRuleParser.GetHostLength(value, startIndex, false, out string? host); parsedValue = host; return hostLength; diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/HeaderDescriptor.cs b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/HeaderDescriptor.cs index e33a5d6..2b955db 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/HeaderDescriptor.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/HeaderDescriptor.cs @@ -4,6 +4,7 @@ using System.Buffers; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Text.Unicode; namespace System.Net.Http.Headers @@ -15,7 +16,7 @@ namespace System.Net.Http.Headers internal readonly struct HeaderDescriptor : IEquatable { private readonly string _headerName; - private readonly KnownHeader _knownHeader; + private readonly KnownHeader? _knownHeader; public HeaderDescriptor(KnownHeader knownHeader) { @@ -31,23 +32,23 @@ namespace System.Net.Http.Headers } public string Name => _headerName; - public HttpHeaderParser Parser => _knownHeader?.Parser; + public HttpHeaderParser? Parser => _knownHeader?.Parser; public HttpHeaderType HeaderType => _knownHeader == null ? HttpHeaderType.Custom : _knownHeader.HeaderType; - public KnownHeader KnownHeader => _knownHeader; + public KnownHeader? KnownHeader => _knownHeader; public bool Equals(HeaderDescriptor other) => _knownHeader == null ? string.Equals(_headerName, other._headerName, StringComparison.OrdinalIgnoreCase) : _knownHeader == other._knownHeader; public override int GetHashCode() => _knownHeader?.GetHashCode() ?? StringComparer.OrdinalIgnoreCase.GetHashCode(_headerName); - public override bool Equals(object obj) => throw new InvalidOperationException(); // Ensure this is never called, to avoid boxing + public override bool Equals(object? obj) => throw new InvalidOperationException(); // Ensure this is never called, to avoid boxing // Returns false for invalid header name. public static bool TryGet(string headerName, out HeaderDescriptor descriptor) { Debug.Assert(!string.IsNullOrEmpty(headerName)); - KnownHeader knownHeader = KnownHeaders.TryGetKnownHeader(headerName); + KnownHeader? knownHeader = KnownHeaders.TryGetKnownHeader(headerName); if (knownHeader != null) { descriptor = new HeaderDescriptor(knownHeader); @@ -69,7 +70,7 @@ namespace System.Net.Http.Headers { Debug.Assert(headerName.Length > 0); - KnownHeader knownHeader = KnownHeaders.TryGetKnownHeader(headerName); + KnownHeader? knownHeader = KnownHeaders.TryGetKnownHeader(headerName); if (knownHeader != null) { descriptor = new HeaderDescriptor(knownHeader); @@ -86,7 +87,7 @@ namespace System.Net.Http.Headers return true; } - internal static bool TryGetStaticQPackHeader(int index, out HeaderDescriptor descriptor, out string knownValue) + internal static bool TryGetStaticQPackHeader(int index, out HeaderDescriptor descriptor, [NotNullWhen(true)] out string? knownValue) { Debug.Assert(index >= 0); Debug.Assert(s_qpackHeaderLookup.Length == 99); @@ -140,7 +141,7 @@ namespace System.Net.Http.Headers if (_knownHeader == KnownHeaders.Location) { // Normally Location should be in ISO-8859-1 but occasionally some servers respond with UTF-8. - if (TryDecodeUtf8(headerValue, out string decoded)) + if (TryDecodeUtf8(headerValue, out string? decoded)) { return decoded; } @@ -150,7 +151,7 @@ namespace System.Net.Http.Headers return HttpRuleParser.DefaultHttpEncoding.GetString(headerValue); } - private static bool TryDecodeUtf8(ReadOnlySpan input, out string decoded) + private static bool TryDecodeUtf8(ReadOnlySpan input, [NotNullWhen(true)] out string? decoded) { char[] rented = ArrayPool.Shared.Rent(input.Length); diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/HeaderUtilities.cs b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/HeaderUtilities.cs index a8183f1..6e6c782 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/HeaderUtilities.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/HeaderUtilities.cs @@ -31,7 +31,7 @@ namespace System.Net.Http.Headers { Debug.Assert(parameters != null); - NameValueHeaderValue qualityParameter = NameValueHeaderValue.Find(parameters, qualityName); + NameValueHeaderValue? qualityParameter = NameValueHeaderValue.Find(parameters, qualityName); if (value.HasValue) { // Note that even if we check the value here, we can't prevent a user from adding an invalid quality @@ -131,7 +131,7 @@ namespace System.Net.Http.Headers { Debug.Assert(parameters != null); - NameValueHeaderValue qualityParameter = NameValueHeaderValue.Find(parameters, qualityName); + NameValueHeaderValue? qualityParameter = NameValueHeaderValue.Find(parameters, qualityName); if (qualityParameter != null) { // Note that the RFC requires decimal '.' regardless of the culture. I.e. using ',' as decimal @@ -191,12 +191,12 @@ namespace System.Net.Http.Headers } } - internal static bool AreEqualCollections(ObjectCollection x, ObjectCollection y) where T : class + internal static bool AreEqualCollections(ObjectCollection? x, ObjectCollection? y) where T : class { return AreEqualCollections(x, y, null); } - internal static bool AreEqualCollections(ObjectCollection x, ObjectCollection y, IEqualityComparer comparer) where T : class + internal static bool AreEqualCollections(ObjectCollection? x, ObjectCollection? y, IEqualityComparer? comparer) where T : class { if (x == null) { @@ -293,7 +293,7 @@ namespace System.Net.Http.Headers { Debug.Assert(store != null); - object storedValue = store.GetParsedValues(descriptor); + object? storedValue = store.GetParsedValues(descriptor); if (storedValue != null) { return (DateTimeOffset)storedValue; @@ -310,7 +310,7 @@ namespace System.Net.Http.Headers { Debug.Assert(store != null); - object storedValue = store.GetParsedValues(descriptor); + object? storedValue = store.GetParsedValues(descriptor); if (storedValue != null) { return (TimeSpan)storedValue; @@ -343,7 +343,7 @@ namespace System.Net.Http.Headers return long.TryParse(value.AsSpan(offset, length), NumberStyles.None, provider: null, out result); } - internal static void DumpHeaders(StringBuilder sb, params HttpHeaders[] headers) + internal static void DumpHeaders(StringBuilder sb, params HttpHeaders?[] headers) { // Appends all headers as string similar to: // { @@ -358,7 +358,7 @@ namespace System.Net.Http.Headers { if (headers[i] != null) { - foreach (var header in headers[i]) + foreach (var header in headers[i]!) // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/34644 { foreach (var headerValue in header.Value) { diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/HttpContentHeaders.cs b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/HttpContentHeaders.cs index 6bb0541..428632a 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/HttpContentHeaders.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/HttpContentHeaders.cs @@ -13,9 +13,9 @@ namespace System.Net.Http.Headers private readonly HttpContent _parent; private bool _contentLengthSet; - private HttpHeaderValueCollection _allow; - private HttpHeaderValueCollection _contentEncoding; - private HttpHeaderValueCollection _contentLanguage; + private HttpHeaderValueCollection? _allow; + private HttpHeaderValueCollection? _contentEncoding; + private HttpHeaderValueCollection? _contentLanguage; public ICollection Allow { @@ -30,9 +30,9 @@ namespace System.Net.Http.Headers } } - public ContentDispositionHeaderValue ContentDisposition + public ContentDispositionHeaderValue? ContentDisposition { - get { return (ContentDispositionHeaderValue)GetParsedValues(KnownHeaders.ContentDisposition.Descriptor); } + get { return (ContentDispositionHeaderValue?)GetParsedValues(KnownHeaders.ContentDisposition.Descriptor); } set { SetOrRemoveParsedValue(KnownHeaders.ContentDisposition.Descriptor, value); } } @@ -69,7 +69,7 @@ namespace System.Net.Http.Headers get { // 'Content-Length' can only hold one value. So either we get 'null' back or a boxed long value. - object storedValue = GetParsedValues(KnownHeaders.ContentLength.Descriptor); + object? storedValue = GetParsedValues(KnownHeaders.ContentLength.Descriptor); // Only try to calculate the length if the user didn't set the value explicitly using the setter. if (!_contentLengthSet && (storedValue == null)) @@ -103,27 +103,27 @@ namespace System.Net.Http.Headers } } - public Uri ContentLocation + public Uri? ContentLocation { - get { return (Uri)GetParsedValues(KnownHeaders.ContentLocation.Descriptor); } + get { return (Uri?)GetParsedValues(KnownHeaders.ContentLocation.Descriptor); } set { SetOrRemoveParsedValue(KnownHeaders.ContentLocation.Descriptor, value); } } - public byte[] ContentMD5 + public byte[]? ContentMD5 { - get { return (byte[])GetParsedValues(KnownHeaders.ContentMD5.Descriptor); } + get { return (byte[]?)GetParsedValues(KnownHeaders.ContentMD5.Descriptor); } set { SetOrRemoveParsedValue(KnownHeaders.ContentMD5.Descriptor, value); } } - public ContentRangeHeaderValue ContentRange + public ContentRangeHeaderValue? ContentRange { - get { return (ContentRangeHeaderValue)GetParsedValues(KnownHeaders.ContentRange.Descriptor); } + get { return (ContentRangeHeaderValue?)GetParsedValues(KnownHeaders.ContentRange.Descriptor); } set { SetOrRemoveParsedValue(KnownHeaders.ContentRange.Descriptor, value); } } - public MediaTypeHeaderValue ContentType + public MediaTypeHeaderValue? ContentType { - get { return (MediaTypeHeaderValue)GetParsedValues(KnownHeaders.ContentType.Descriptor); } + get { return (MediaTypeHeaderValue?)GetParsedValues(KnownHeaders.ContentType.Descriptor); } set { SetOrRemoveParsedValue(KnownHeaders.ContentType.Descriptor, value); } } diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/HttpGeneralHeaders.cs b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/HttpGeneralHeaders.cs index 550b111..9656a0c 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/HttpGeneralHeaders.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/HttpGeneralHeaders.cs @@ -11,20 +11,20 @@ namespace System.Net.Http.Headers // functionality in both HttpRequestHeaders and HttpResponseHeaders. internal sealed class HttpGeneralHeaders { - private HttpHeaderValueCollection _connection; - private HttpHeaderValueCollection _trailer; - private HttpHeaderValueCollection _transferEncoding; - private HttpHeaderValueCollection _upgrade; - private HttpHeaderValueCollection _via; - private HttpHeaderValueCollection _warning; - private HttpHeaderValueCollection _pragma; + private HttpHeaderValueCollection? _connection; + private HttpHeaderValueCollection? _trailer; + private HttpHeaderValueCollection? _transferEncoding; + private HttpHeaderValueCollection? _upgrade; + private HttpHeaderValueCollection? _via; + private HttpHeaderValueCollection? _warning; + private HttpHeaderValueCollection? _pragma; private readonly HttpHeaders _parent; private bool _transferEncodingChunkedSet; private bool _connectionCloseSet; - public CacheControlHeaderValue CacheControl + public CacheControlHeaderValue? CacheControl { - get { return (CacheControlHeaderValue)_parent.GetParsedValues(KnownHeaders.CacheControl.Descriptor); } + get { return (CacheControlHeaderValue?)_parent.GetParsedValues(KnownHeaders.CacheControl.Descriptor); } set { _parent.SetOrRemoveParsedValue(KnownHeaders.CacheControl.Descriptor, value); } } @@ -57,7 +57,7 @@ namespace System.Net.Http.Headers } } - internal static bool? GetConnectionClose(HttpHeaders parent, HttpGeneralHeaders headers) + internal static bool? GetConnectionClose(HttpHeaders parent, HttpGeneralHeaders? headers) { // If we've already initialized the connection header value collection // and it contains the special value, or if we haven't and the headers contain @@ -117,7 +117,7 @@ namespace System.Net.Http.Headers get { return TransferEncodingCore; } } - internal static bool? GetTransferEncodingChunked(HttpHeaders parent, HttpGeneralHeaders headers) + internal static bool? GetTransferEncodingChunked(HttpHeaders parent, HttpGeneralHeaders? headers) { // If we've already initialized the transfer encoding header value collection // and it contains the special value, or if we haven't and the headers contain diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/HttpHeaderParser.cs b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/HttpHeaderParser.cs index 94b64f8..97402f9 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/HttpHeaderParser.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/HttpHeaderParser.cs @@ -4,6 +4,7 @@ using System.Collections; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; namespace System.Net.Http.Headers { @@ -12,14 +13,14 @@ namespace System.Net.Http.Headers internal const string DefaultSeparator = ", "; private readonly bool _supportsMultipleValues; - private readonly string _separator; + private readonly string? _separator; public bool SupportsMultipleValues { get { return _supportsMultipleValues; } } - public string Separator + public string? Separator { get { @@ -30,7 +31,7 @@ namespace System.Net.Http.Headers // If ValueType implements Equals() as required, there is no need to provide a comparer. A comparer is needed // e.g. if we want to compare strings using case-insensitive comparison. - public virtual IEqualityComparer Comparer + public virtual IEqualityComparer? Comparer { get { return null; } } @@ -57,9 +58,9 @@ namespace System.Net.Http.Headers // pointing to the next non-whitespace character after a delimiter. E.g. if called with a start index of 0 // for string "value , second_value", then after the call completes, 'index' must point to 's', i.e. the first // non-whitespace after the separator ','. - public abstract bool TryParseValue(string value, object storeValue, ref int index, out object parsedValue); + public abstract bool TryParseValue(string? value, object? storeValue, ref int index, [NotNullWhen(true)] out object? parsedValue); - public object ParseValue(string value, object storeValue, ref int index) + public object ParseValue(string? value, object? storeValue, ref int index) { // Index may be value.Length (e.g. both 0). This may be allowed for some headers (e.g. Accept but not // allowed by others (e.g. Content-Length). The parser has to decide if this is valid or not. @@ -67,8 +68,7 @@ namespace System.Net.Http.Headers // If a parser returns 'null', it means there was no value, but that's valid (e.g. "Accept: "). The caller // can ignore the value. - object result = null; - if (!TryParseValue(value, storeValue, ref index, out result)) + if (!TryParseValue(value, storeValue, ref index, out object? result)) { throw new FormatException(SR.Format(System.Globalization.CultureInfo.InvariantCulture, SR.net_http_headers_invalid_value, value == null ? "" : value.Substring(index))); @@ -80,7 +80,7 @@ namespace System.Net.Http.Headers // However for existing types like int, byte[], DateTimeOffset we can't override ToString(). Therefore the // parser provides a ToString() virtual method that can be overridden by derived types to correctly serialize // values (e.g. byte[] to Base64 encoded string). - public virtual string ToString(object value) + public virtual string? ToString(object value) { Debug.Assert(value != null); diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/HttpHeaderValueCollection.cs b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/HttpHeaderValueCollection.cs index 02e26a5..19534ae 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/HttpHeaderValueCollection.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/HttpHeaderValueCollection.cs @@ -36,8 +36,8 @@ namespace System.Net.Http.Headers { private readonly HeaderDescriptor _descriptor; private readonly HttpHeaders _store; - private readonly T _specialValue; - private readonly Action, T> _validator; + private readonly T? _specialValue; + private readonly Action, T>? _validator; public int Count { @@ -78,8 +78,8 @@ namespace System.Net.Http.Headers { } - internal HttpHeaderValueCollection(HeaderDescriptor descriptor, HttpHeaders store, T specialValue, - Action, T> validator) + internal HttpHeaderValueCollection(HeaderDescriptor descriptor, HttpHeaders store, T? specialValue, + Action, T>? validator) { Debug.Assert(descriptor.Name != null); Debug.Assert(store != null); @@ -96,12 +96,12 @@ namespace System.Net.Http.Headers _store.AddParsedValue(_descriptor, item); } - public void ParseAdd(string input) + public void ParseAdd(string? input) { _store.Add(_descriptor, input); } - public bool TryParseAdd(string input) + public bool TryParseAdd(string? input) { return _store.TryParseAndAddValue(_descriptor, input); } @@ -129,14 +129,14 @@ namespace System.Net.Http.Headers throw new ArgumentOutOfRangeException(nameof(arrayIndex)); } - object storeValue = _store.GetParsedValues(_descriptor); + object? storeValue = _store.GetParsedValues(_descriptor); if (storeValue == null) { return; } - List storeValues = storeValue as List; + List? storeValues = storeValue as List; if (storeValues == null) { @@ -147,7 +147,7 @@ namespace System.Net.Http.Headers { throw new ArgumentException(SR.net_http_copyto_array_too_small); } - array[arrayIndex] = storeValue as T; + array[arrayIndex] = (T)storeValue; } else { @@ -165,19 +165,19 @@ namespace System.Net.Http.Headers public IEnumerator GetEnumerator() { - object storeValue = _store.GetParsedValues(_descriptor); + object? storeValue = _store.GetParsedValues(_descriptor); if (storeValue == null) { yield break; } - List storeValues = storeValue as List; + List? storeValues = storeValue as List; if (storeValues == null) { Debug.Assert(storeValue is T); - yield return storeValue as T; + yield return (T)storeValue; } else { @@ -185,7 +185,7 @@ namespace System.Net.Http.Headers foreach (object item in storeValues) { Debug.Assert(item is T); - yield return item as T; + yield return (T)item; } } } @@ -245,14 +245,14 @@ namespace System.Net.Http.Headers { // This is an O(n) operation. - object storeValue = _store.GetParsedValues(_descriptor); + object? storeValue = _store.GetParsedValues(_descriptor); if (storeValue == null) { return 0; } - List storeValues = storeValue as List; + List? storeValues = storeValue as List; if (storeValues == null) { diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/HttpHeaders.cs b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/HttpHeaders.cs index 686b0cb..dfe61fa 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/HttpHeaders.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/HttpHeaders.cs @@ -31,7 +31,7 @@ namespace System.Net.Http.Headers // - HttpResponseHeaders.Via collection will only contain one ViaHeaderValue object with value "1.1 proxy" public abstract class HttpHeaders : IEnumerable>> { - private Dictionary _headerStore; + private Dictionary? _headerStore; private readonly HttpHeaderType _allowedHeaderTypes; private readonly HttpHeaderType _treatAsCustomHeaderTypes; @@ -56,14 +56,14 @@ namespace System.Net.Http.Headers _treatAsCustomHeaderTypes = treatAsCustomHeaderTypes & ~HttpHeaderType.NonTrailing; } - internal Dictionary HeaderStore => _headerStore; + internal Dictionary? HeaderStore => _headerStore; - public void Add(string name, string value) + public void Add(string name, string? value) { Add(GetHeaderDescriptor(name), value); } - internal void Add(HeaderDescriptor descriptor, string value) + internal void Add(HeaderDescriptor descriptor, string? value) { // We don't use GetOrCreateHeaderInfo() here, since this would create a new header in the store. If parsing // the value then throws, we would have to remove the header from the store again. So just get a @@ -82,27 +82,25 @@ namespace System.Net.Http.Headers } } - public void Add(string name, IEnumerable values) + public void Add(string name, IEnumerable values) { Add(GetHeaderDescriptor(name), values); } - internal void Add(HeaderDescriptor descriptor, IEnumerable values) + internal void Add(HeaderDescriptor descriptor, IEnumerable values) { if (values == null) { throw new ArgumentNullException(nameof(values)); } - HeaderStoreItemInfo info; - bool addToStore; - PrepareHeaderInfoForAdd(descriptor, out info, out addToStore); + PrepareHeaderInfoForAdd(descriptor, out HeaderStoreItemInfo info, out bool addToStore); try { // Note that if the first couple of values are valid followed by an invalid value, the valid values // will be added to the store before the exception for the invalid value is thrown. - foreach (string value in values) + foreach (string? value in values) { ParseAndAddValue(descriptor, info, value); } @@ -121,11 +119,11 @@ namespace System.Net.Http.Headers } } - public bool TryAddWithoutValidation(string name, string value) => + public bool TryAddWithoutValidation(string name, string? value) => TryGetHeaderDescriptor(name, out HeaderDescriptor descriptor) && TryAddWithoutValidation(descriptor, value); - internal bool TryAddWithoutValidation(HeaderDescriptor descriptor, string value) + internal bool TryAddWithoutValidation(HeaderDescriptor descriptor, string? value) { if (value == null) { @@ -141,11 +139,11 @@ namespace System.Net.Http.Headers return true; } - public bool TryAddWithoutValidation(string name, IEnumerable values) => + public bool TryAddWithoutValidation(string name, IEnumerable values) => TryGetHeaderDescriptor(name, out HeaderDescriptor descriptor) && TryAddWithoutValidation(descriptor, values); - internal bool TryAddWithoutValidation(HeaderDescriptor descriptor, IEnumerable values) + internal bool TryAddWithoutValidation(HeaderDescriptor descriptor, IEnumerable values) { if (values == null) { @@ -153,7 +151,7 @@ namespace System.Net.Http.Headers } HeaderStoreItemInfo info = GetOrCreateHeaderInfo(descriptor, false); - foreach (string value in values) + foreach (string? value in values) { // We allow empty header values. (e.g. "My-Header: "). If the user adds multiple null/empty // values, we'll just add them to the collection. This will result in delimiter-only values: @@ -184,8 +182,7 @@ namespace System.Net.Http.Headers internal IEnumerable GetValues(HeaderDescriptor descriptor) { - IEnumerable values; - if (!TryGetValues(descriptor, out values)) + if (!TryGetValues(descriptor, out IEnumerable? values)) { throw new InvalidOperationException(SR.net_http_headers_not_found); } @@ -193,7 +190,7 @@ namespace System.Net.Http.Headers return values; } - public bool TryGetValues(string name, out IEnumerable values) + public bool TryGetValues(string name, [NotNullWhen(true)] out IEnumerable? values) { HeaderDescriptor descriptor; if (!TryGetHeaderDescriptor(name, out descriptor)) @@ -205,7 +202,7 @@ namespace System.Net.Http.Headers return TryGetValues(descriptor, out values); } - internal bool TryGetValues(HeaderDescriptor descriptor, out IEnumerable values) + internal bool TryGetValues(HeaderDescriptor descriptor, [NotNullWhen(true)] out IEnumerable? values) { if (_headerStore == null) { @@ -213,8 +210,7 @@ namespace System.Net.Http.Headers return false; } - HeaderStoreItemInfo info = null; - if (TryGetAndParseHeaderInfo(descriptor, out info)) + if (TryGetAndParseHeaderInfo(descriptor, out HeaderStoreItemInfo? info)) { values = GetValuesAsStrings(descriptor, info); return true; @@ -239,8 +235,7 @@ namespace System.Net.Http.Headers // We can't just call headerStore.ContainsKey() since after parsing the value the header may not exist // anymore (if the value contains invalid newline chars, we remove the header). So try to parse the // header value. - HeaderStoreItemInfo info = null; - return TryGetAndParseHeaderInfo(descriptor, out info); + return TryGetAndParseHeaderInfo(descriptor, out HeaderStoreItemInfo? _); } public override string ToString() @@ -288,10 +283,9 @@ namespace System.Net.Http.Headers return GetHeaderString(descriptor); } - internal string GetHeaderString(HeaderDescriptor descriptor, object exclude = null) + internal string GetHeaderString(HeaderDescriptor descriptor, object? exclude = null) { - HeaderStoreItemInfo info; - if (!TryGetHeaderInfo(descriptor, out info)) + if (!TryGetHeaderInfo(descriptor, out HeaderStoreItemInfo? info)) { return string.Empty; } @@ -299,7 +293,7 @@ namespace System.Net.Http.Headers return GetHeaderString(descriptor, info, exclude); } - private string GetHeaderString(HeaderDescriptor descriptor, HeaderStoreItemInfo info, object exclude = null) + private string GetHeaderString(HeaderDescriptor descriptor, HeaderStoreItemInfo info, object? exclude = null) { string stringValue; @@ -313,7 +307,7 @@ namespace System.Net.Http.Headers { // Note that if we get multiple values for a header that doesn't support multiple values, we'll // just separate the values using a comma (default separator). - string separator = HttpHeaderParser.DefaultSeparator; + string? separator = HttpHeaderParser.DefaultSeparator; if ((descriptor.Parser != null) && (descriptor.Parser.SupportsMultipleValues)) { separator = descriptor.Parser.Separator; @@ -335,7 +329,7 @@ namespace System.Net.Http.Headers private IEnumerator>> GetEnumeratorCore() { - foreach (KeyValuePair header in _headerStore) + foreach (KeyValuePair header in _headerStore!) { HeaderDescriptor descriptor = header.Key; HeaderStoreItemInfo info = header.Value; @@ -397,7 +391,7 @@ namespace System.Net.Http.Headers AddValue(info, value, StoreLocation.Parsed); } - internal void SetOrRemoveParsedValue(HeaderDescriptor descriptor, object value) + internal void SetOrRemoveParsedValue(HeaderDescriptor descriptor, object? value) { if (value == null) { @@ -430,8 +424,7 @@ namespace System.Net.Http.Headers // If we have a value for this header, then verify if we have a single value. If so, compare that // value with 'item'. If we have a list of values, then remove 'item' from the list. - HeaderStoreItemInfo info = null; - if (TryGetAndParseHeaderInfo(descriptor, out info)) + if (TryGetAndParseHeaderInfo(descriptor, out HeaderStoreItemInfo? info)) { Debug.Assert(descriptor.Parser != null, "Can't add parsed value if there is no parser available."); Debug.Assert(descriptor.Parser.SupportsMultipleValues, @@ -445,9 +438,9 @@ namespace System.Net.Http.Headers return false; } - IEqualityComparer comparer = descriptor.Parser.Comparer; + IEqualityComparer? comparer = descriptor.Parser.Comparer; - List parsedValues = info.ParsedValue as List; + List? parsedValues = info.ParsedValue as List; if (parsedValues == null) { Debug.Assert(info.ParsedValue.GetType() == value.GetType(), @@ -506,8 +499,7 @@ namespace System.Net.Http.Headers // If we have a value for this header, then verify if we have a single value. If so, compare that // value with 'item'. If we have a list of values, then compare each item in the list with 'item'. - HeaderStoreItemInfo info = null; - if (TryGetAndParseHeaderInfo(descriptor, out info)) + if (TryGetAndParseHeaderInfo(descriptor, out HeaderStoreItemInfo? info)) { Debug.Assert(descriptor.Parser != null, "Can't add parsed value if there is no parser available."); Debug.Assert(descriptor.Parser.SupportsMultipleValues, @@ -519,9 +511,9 @@ namespace System.Net.Http.Headers return false; } - List parsedValues = info.ParsedValue as List; + List? parsedValues = info.ParsedValue as List; - IEqualityComparer comparer = descriptor.Parser.Comparer; + IEqualityComparer? comparer = descriptor.Parser.Comparer; if (parsedValues == null) { @@ -609,7 +601,7 @@ namespace System.Net.Http.Headers // Now clone and add parsed values (if any). if (sourceInfo.ParsedValue != null) { - List sourceValues = sourceInfo.ParsedValue as List; + List? sourceValues = sourceInfo.ParsedValue as List; if (sourceValues == null) { CloneAndAddValue(destinationInfo, sourceInfo.ParsedValue); @@ -628,9 +620,7 @@ namespace System.Net.Http.Headers private static void CloneAndAddValue(HeaderStoreItemInfo destinationInfo, object source) { // We only have one value. Clone it and assign it to the store. - ICloneable cloneableValue = source as ICloneable; - - if (cloneableValue != null) + if (source is ICloneable cloneableValue) { AddValue(destinationInfo, cloneableValue.Clone(), StoreLocation.Parsed); } @@ -641,14 +631,15 @@ namespace System.Net.Http.Headers } } - private static object CloneStringHeaderInfoValues(object source) + [return: NotNullIfNotNull("source")] + private static object? CloneStringHeaderInfoValues(object? source) { if (source == null) { return null; } - List sourceValues = source as List; + List? sourceValues = source as List; if (sourceValues == null) { // If we just have one value, return the reference to the string (strings are immutable so it's OK @@ -664,7 +655,7 @@ namespace System.Net.Http.Headers private HeaderStoreItemInfo GetOrCreateHeaderInfo(HeaderDescriptor descriptor, bool parseRawValues) { - HeaderStoreItemInfo result = null; + HeaderStoreItemInfo? result; bool found = false; if (parseRawValues) { @@ -706,7 +697,7 @@ namespace System.Net.Http.Headers _headerStore.Add(descriptor, info); } - private bool TryGetHeaderInfo(HeaderDescriptor descriptor, out HeaderStoreItemInfo info) + private bool TryGetHeaderInfo(HeaderDescriptor descriptor, [NotNullWhen(true)] out HeaderStoreItemInfo? info) { if (_headerStore == null) { @@ -717,7 +708,7 @@ namespace System.Net.Http.Headers return _headerStore.TryGetValue(descriptor, out info); } - private bool TryGetAndParseHeaderInfo(HeaderDescriptor key, out HeaderStoreItemInfo info) + private bool TryGetAndParseHeaderInfo(HeaderDescriptor key, [NotNullWhen(true)] out HeaderStoreItemInfo? info) { if (TryGetHeaderInfo(key, out info)) { @@ -737,7 +728,7 @@ namespace System.Net.Http.Headers // before returning to the caller. if (info.RawValue != null) { - List rawValues = info.RawValue as List; + List? rawValues = info.RawValue as List; if (rawValues == null) { @@ -798,7 +789,7 @@ namespace System.Net.Http.Headers private static void ParseSingleRawHeaderValue(HeaderDescriptor descriptor, HeaderStoreItemInfo info) { - string rawValue = info.RawValue as string; + string? rawValue = info.RawValue as string; Debug.Assert(rawValue != null, "RawValue must either be List or string."); if (descriptor.Parser == null) @@ -818,7 +809,7 @@ namespace System.Net.Http.Headers } // See Add(name, string) - internal bool TryParseAndAddValue(HeaderDescriptor descriptor, string value) + internal bool TryParseAndAddValue(HeaderDescriptor descriptor, string? value) { // We don't use GetOrCreateHeaderInfo() here, since this would create a new header in the store. If parsing // the value then throws, we would have to remove the header from the store again. So just get a @@ -840,7 +831,7 @@ namespace System.Net.Http.Headers } // See ParseAndAddValue - private static bool TryParseAndAddRawHeaderValue(HeaderDescriptor descriptor, HeaderStoreItemInfo info, string value, bool addWhenInvalid) + private static bool TryParseAndAddRawHeaderValue(HeaderDescriptor descriptor, HeaderStoreItemInfo info, string? value, bool addWhenInvalid) { Debug.Assert(info != null); Debug.Assert(descriptor.Parser != null); @@ -859,9 +850,8 @@ namespace System.Net.Http.Headers } int index = 0; - object parsedValue = null; - if (descriptor.Parser.TryParseValue(value, info.ParsedValue, ref index, out parsedValue)) + if (descriptor.Parser.TryParseValue(value, info.ParsedValue, ref index, out object? parsedValue)) { // The raw string only represented one value (which was successfully parsed). Add the value and return. if ((value == null) || (index == value.Length)) @@ -909,6 +899,7 @@ namespace System.Net.Http.Headers return true; } + Debug.Assert(value != null); if (!ContainsInvalidNewLine(value, descriptor.Name) && addWhenInvalid) { AddValue(info, value ?? string.Empty, StoreLocation.Invalid); @@ -916,7 +907,7 @@ namespace System.Net.Http.Headers return false; } - private static void AddValue(HeaderStoreItemInfo info, object value, StoreLocation location) + private static void AddValue(HeaderStoreItemInfo info, object? value, StoreLocation location) { // Since we have the same pattern for all three store locations (raw, invalid, parsed), we use // this helper method to deal with adding values: @@ -925,7 +916,7 @@ namespace System.Net.Http.Headers // - if 'T', i.e. we have already a value stored (but no list), create a list, add the stored value // to the list and append 'value' at the end of the newly created list. - object currentStoreValue = null; + object? currentStoreValue = null; switch (location) { case StoreLocation.Raw: @@ -955,7 +946,7 @@ namespace System.Net.Http.Headers } } - private static void AddValueToStoreValue(object value, ref object currentStoreValue) where T : class + private static void AddValueToStoreValue(object? value, ref object? currentStoreValue) where T : class { // If there is no value set yet, then add current item as value (we don't create a list // if not required). If 'info.Value' is already assigned then make sure 'info.Value' is a @@ -966,28 +957,26 @@ namespace System.Net.Http.Headers } else { - List storeValues = currentStoreValue as List; + List? storeValues = currentStoreValue as List; if (storeValues == null) { storeValues = new List(2); Debug.Assert(currentStoreValue is T); - storeValues.Add(currentStoreValue as T); + storeValues.Add((T)currentStoreValue); currentStoreValue = storeValues; } Debug.Assert(value is T); - storeValues.Add(value as T); + storeValues.Add((T)value); } } // Since most of the time we just have 1 value, we don't create a List for one value, but we change // the return type to 'object'. The caller has to deal with the return type (object vs. List). This // is to optimize the most common scenario where a header has only one value. - internal object GetParsedValues(HeaderDescriptor descriptor) + internal object? GetParsedValues(HeaderDescriptor descriptor) { - HeaderStoreItemInfo info = null; - - if (!TryGetAndParseHeaderInfo(descriptor, out info)) + if (!TryGetAndParseHeaderInfo(descriptor, out HeaderStoreItemInfo? info)) { return null; } @@ -1004,16 +993,15 @@ namespace System.Net.Http.Headers throw new InvalidOperationException(string.Format(SR.net_http_headers_not_allowed_header_name, descriptor.Name)); } - info = null; addToStore = false; - if (!TryGetAndParseHeaderInfo(descriptor, out info)) + if (!TryGetAndParseHeaderInfo(descriptor, out info!)) { info = new HeaderStoreItemInfo(); addToStore = true; } } - private void ParseAndAddValue(HeaderDescriptor descriptor, HeaderStoreItemInfo info, string value) + private void ParseAndAddValue(HeaderDescriptor descriptor, HeaderStoreItemInfo info, string? value) { Debug.Assert(info != null); @@ -1125,7 +1113,7 @@ namespace System.Net.Http.Headers return false; } - private static void CheckInvalidNewLine(string value) + private static void CheckInvalidNewLine(string? value) { if (value == null) { @@ -1148,7 +1136,7 @@ namespace System.Net.Http.Headers return false; } - private static string[] GetValuesAsStrings(HeaderDescriptor descriptor, HeaderStoreItemInfo info, object exclude = null) + private static string[] GetValuesAsStrings(HeaderDescriptor descriptor, HeaderStoreItemInfo info, object? exclude = null) { int length = GetValueCount(info); string[] values; @@ -1158,12 +1146,12 @@ namespace System.Net.Http.Headers values = new string[length]; int currentIndex = 0; - ReadStoreValues(values, info.RawValue, null, null, ref currentIndex); - ReadStoreValues(values, info.ParsedValue, descriptor.Parser, exclude, ref currentIndex); + ReadStoreValues(values, info.RawValue, null, null, ref currentIndex); + ReadStoreValues(values, info.ParsedValue, descriptor.Parser, exclude, ref currentIndex); // Set parser parameter to 'null' for invalid values: The invalid values is always a string so we // don't need the parser to "serialize" the value to a string. - ReadStoreValues(values, info.InvalidValue, null, null, ref currentIndex); + ReadStoreValues(values, info.InvalidValue, null, null, ref currentIndex); // The values array may not be full because some values were excluded if (currentIndex < length) @@ -1193,9 +1181,9 @@ namespace System.Net.Http.Headers } int currentIndex = 0; - ReadStoreValues(values, info.RawValue, null, null, ref currentIndex); - ReadStoreValues(values, info.ParsedValue, descriptor.Parser, null, ref currentIndex); - ReadStoreValues(values, info.InvalidValue, null, null, ref currentIndex); + ReadStoreValues(values, info.RawValue, null, null, ref currentIndex); + ReadStoreValues(values, info.ParsedValue, descriptor.Parser, null, ref currentIndex); + ReadStoreValues(values, info.InvalidValue, null, null, ref currentIndex); Debug.Assert(currentIndex == length); } @@ -1211,20 +1199,20 @@ namespace System.Net.Http.Headers valueCount += Count(info.ParsedValue); return valueCount; - static int Count(object valueStore) => + static int Count(object? valueStore) => valueStore is null ? 0 : valueStore is List list ? list.Count : 1; } - private static void ReadStoreValues(string[] values, object storeValue, HttpHeaderParser parser, + private static void ReadStoreValues(string?[] values, object? storeValue, HttpHeaderParser? parser, T exclude, ref int currentIndex) { Debug.Assert(values != null); if (storeValue != null) { - List storeValues = storeValue as List; + List? storeValues = storeValue as List; if (storeValues == null) { @@ -1236,10 +1224,11 @@ namespace System.Net.Http.Headers } else { - foreach (object item in storeValues) + foreach (object? item in storeValues) { if (ShouldAdd(item, parser, exclude)) { + Debug.Assert(item != null); values[currentIndex] = parser == null ? item.ToString() : parser.ToString(item); currentIndex++; } @@ -1248,7 +1237,7 @@ namespace System.Net.Http.Headers } } - private static bool ShouldAdd(object storeValue, HttpHeaderParser parser, T exclude) + private static bool ShouldAdd(object? storeValue, HttpHeaderParser? parser, T exclude) { bool add = true; if (parser != null && exclude != null) @@ -1265,7 +1254,7 @@ namespace System.Net.Http.Headers return add; } - private bool AreEqual(object value, object storeValue, IEqualityComparer comparer) + private bool AreEqual(object value, object? storeValue, IEqualityComparer? comparer) { Debug.Assert(value != null); @@ -1284,9 +1273,9 @@ namespace System.Net.Http.Headers { internal HeaderStoreItemInfo() { } - internal object RawValue { get; set; } - internal object InvalidValue { get; set; } - internal object ParsedValue { get; set; } + internal object? RawValue { get; set; } + internal object? InvalidValue { get; set; } + internal object? ParsedValue { get; set; } internal bool CanAddValue(HttpHeaderParser parser) { diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/HttpRequestHeaders.cs b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/HttpRequestHeaders.cs index df0ec9d..f62345a 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/HttpRequestHeaders.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/HttpRequestHeaders.cs @@ -19,9 +19,9 @@ namespace System.Net.Http.Headers private const int UserAgentSlot = 7; private const int NumCollectionsSlots = 8; - private object[] _specialCollectionsSlots; - private HttpGeneralHeaders _generalHeaders; - private HttpHeaderValueCollection _expect; + private object[]? _specialCollectionsSlots; + private HttpGeneralHeaders? _generalHeaders; + private HttpHeaderValueCollection? _expect; private bool _expectContinueSet; #region Request Headers @@ -32,7 +32,7 @@ namespace System.Net.Http.Headers // Rather than having a field for each of these, store them untyped in an array that's lazily // allocated. Then we only pay for the 64 bytes for those fields when any is actually accessed. _specialCollectionsSlots ??= new object[NumCollectionsSlots]; - return (T)(_specialCollectionsSlots[slot] ??= creationFunc(this)); + return (T)(_specialCollectionsSlots[slot] ??= creationFunc(this)!); } public HttpHeaderValueCollection Accept => @@ -47,9 +47,9 @@ namespace System.Net.Http.Headers public HttpHeaderValueCollection AcceptLanguage => GetSpecializedCollection(AcceptLanguageSlot, thisRef => new HttpHeaderValueCollection(KnownHeaders.AcceptLanguage.Descriptor, thisRef)); - public AuthenticationHeaderValue Authorization + public AuthenticationHeaderValue? Authorization { - get { return (AuthenticationHeaderValue)GetParsedValues(KnownHeaders.Authorization.Descriptor); } + get { return (AuthenticationHeaderValue?)GetParsedValues(KnownHeaders.Authorization.Descriptor); } set { SetOrRemoveParsedValue(KnownHeaders.Authorization.Descriptor, value); } } @@ -92,9 +92,9 @@ namespace System.Net.Http.Headers } } - public string From + public string? From { - get { return (string)GetParsedValues(KnownHeaders.From.Descriptor); } + get { return (string?)GetParsedValues(KnownHeaders.From.Descriptor); } set { // Null and empty string are equivalent. In this case it means, remove the From header value (if any). @@ -111,9 +111,9 @@ namespace System.Net.Http.Headers } } - public string Host + public string? Host { - get { return (string)GetParsedValues(KnownHeaders.Host.Descriptor); } + get { return (string?)GetParsedValues(KnownHeaders.Host.Descriptor); } set { // Null and empty string are equivalent. In this case it means, remove the Host header value (if any). @@ -122,8 +122,7 @@ namespace System.Net.Http.Headers value = null; } - string host = null; - if ((value != null) && (HttpRuleParser.GetHostLength(value, 0, false, out host) != value.Length)) + if ((value != null) && (HttpRuleParser.GetHostLength(value, 0, false, out string? _) != value.Length)) { throw new FormatException(SR.net_http_headers_invalid_host_header); } @@ -143,9 +142,9 @@ namespace System.Net.Http.Headers public HttpHeaderValueCollection IfNoneMatch => GetSpecializedCollection(IfNoneMatchSlot, thisRef => new HttpHeaderValueCollection(KnownHeaders.IfNoneMatch.Descriptor, thisRef)); - public RangeConditionHeaderValue IfRange + public RangeConditionHeaderValue? IfRange { - get { return (RangeConditionHeaderValue)GetParsedValues(KnownHeaders.IfRange.Descriptor); } + get { return (RangeConditionHeaderValue?)GetParsedValues(KnownHeaders.IfRange.Descriptor); } set { SetOrRemoveParsedValue(KnownHeaders.IfRange.Descriptor, value); } } @@ -159,7 +158,7 @@ namespace System.Net.Http.Headers { get { - object storedValue = GetParsedValues(KnownHeaders.MaxForwards.Descriptor); + object? storedValue = GetParsedValues(KnownHeaders.MaxForwards.Descriptor); if (storedValue != null) { return (int)storedValue; @@ -170,21 +169,21 @@ namespace System.Net.Http.Headers } - public AuthenticationHeaderValue ProxyAuthorization + public AuthenticationHeaderValue? ProxyAuthorization { - get { return (AuthenticationHeaderValue)GetParsedValues(KnownHeaders.ProxyAuthorization.Descriptor); } + get { return (AuthenticationHeaderValue?)GetParsedValues(KnownHeaders.ProxyAuthorization.Descriptor); } set { SetOrRemoveParsedValue(KnownHeaders.ProxyAuthorization.Descriptor, value); } } - public RangeHeaderValue Range + public RangeHeaderValue? Range { - get { return (RangeHeaderValue)GetParsedValues(KnownHeaders.Range.Descriptor); } + get { return (RangeHeaderValue?)GetParsedValues(KnownHeaders.Range.Descriptor); } set { SetOrRemoveParsedValue(KnownHeaders.Range.Descriptor, value); } } - public Uri Referrer + public Uri? Referrer { - get { return (Uri)GetParsedValues(KnownHeaders.Referer.Descriptor); } + get { return (Uri?)GetParsedValues(KnownHeaders.Referer.Descriptor); } set { SetOrRemoveParsedValue(KnownHeaders.Referer.Descriptor, value); } } @@ -201,7 +200,7 @@ namespace System.Net.Http.Headers #region General Headers - public CacheControlHeaderValue CacheControl + public CacheControlHeaderValue? CacheControl { get { return GeneralHeaders.CacheControl; } set { GeneralHeaders.CacheControl = value; } @@ -270,7 +269,7 @@ namespace System.Net.Http.Headers internal override void AddHeaders(HttpHeaders sourceHeaders) { base.AddHeaders(sourceHeaders); - HttpRequestHeaders sourceRequestHeaders = sourceHeaders as HttpRequestHeaders; + HttpRequestHeaders? sourceRequestHeaders = sourceHeaders as HttpRequestHeaders; Debug.Assert(sourceRequestHeaders != null); // Copy special values but do not overwrite. diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/HttpResponseHeaders.cs b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/HttpResponseHeaders.cs index c08b745..8da6741 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/HttpResponseHeaders.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/HttpResponseHeaders.cs @@ -16,8 +16,8 @@ namespace System.Net.Http.Headers private const int WwwAuthenticateSlot = 4; private const int NumCollectionsSlots = 5; - private object[] _specialCollectionsSlots; - private HttpGeneralHeaders _generalHeaders; + private object[]? _specialCollectionsSlots; + private HttpGeneralHeaders? _generalHeaders; private bool _containsTrailingHeaders; #region Response Headers @@ -31,7 +31,7 @@ namespace System.Net.Http.Headers object result = collections[slot]; if (result == null) { - collections[slot] = result = creationFunc(this); + collections[slot] = result = creationFunc(this)!; } return (T)result; } @@ -45,24 +45,24 @@ namespace System.Net.Http.Headers set { SetOrRemoveParsedValue(KnownHeaders.Age.Descriptor, value); } } - public EntityTagHeaderValue ETag + public EntityTagHeaderValue? ETag { - get { return (EntityTagHeaderValue)GetParsedValues(KnownHeaders.ETag.Descriptor); } + get { return (EntityTagHeaderValue?)GetParsedValues(KnownHeaders.ETag.Descriptor); } set { SetOrRemoveParsedValue(KnownHeaders.ETag.Descriptor, value); } } - public Uri Location + public Uri? Location { - get { return (Uri)GetParsedValues(KnownHeaders.Location.Descriptor); } + get { return (Uri?)GetParsedValues(KnownHeaders.Location.Descriptor); } set { SetOrRemoveParsedValue(KnownHeaders.Location.Descriptor, value); } } public HttpHeaderValueCollection ProxyAuthenticate => GetSpecializedCollection(ProxyAuthenticateSlot, thisRef => new HttpHeaderValueCollection(KnownHeaders.ProxyAuthenticate.Descriptor, thisRef)); - public RetryConditionHeaderValue RetryAfter + public RetryConditionHeaderValue? RetryAfter { - get { return (RetryConditionHeaderValue)GetParsedValues(KnownHeaders.RetryAfter.Descriptor); } + get { return (RetryConditionHeaderValue?)GetParsedValues(KnownHeaders.RetryAfter.Descriptor); } set { SetOrRemoveParsedValue(KnownHeaders.RetryAfter.Descriptor, value); } } @@ -79,7 +79,7 @@ namespace System.Net.Http.Headers #region General Headers - public CacheControlHeaderValue CacheControl + public CacheControlHeaderValue? CacheControl { get { return GeneralHeaders.CacheControl; } set { GeneralHeaders.CacheControl = value; } @@ -150,7 +150,7 @@ namespace System.Net.Http.Headers internal override void AddHeaders(HttpHeaders sourceHeaders) { base.AddHeaders(sourceHeaders); - HttpResponseHeaders sourceResponseHeaders = sourceHeaders as HttpResponseHeaders; + HttpResponseHeaders? sourceResponseHeaders = sourceHeaders as HttpResponseHeaders; Debug.Assert(sourceResponseHeaders != null); // Copy special values, but do not overwrite @@ -165,7 +165,7 @@ namespace System.Net.Http.Headers if (!_containsTrailingHeaders) return true; - KnownHeader knownHeader = KnownHeaders.TryGetKnownHeader(descriptor.Name); + KnownHeader? knownHeader = KnownHeaders.TryGetKnownHeader(descriptor.Name); if (knownHeader == null) return true; diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/Int32NumberHeaderParser.cs b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/Int32NumberHeaderParser.cs index d7d812f..e02d56c 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/Int32NumberHeaderParser.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/Int32NumberHeaderParser.cs @@ -29,8 +29,8 @@ namespace System.Net.Http.Headers return ((int)value).ToString(NumberFormatInfo.InvariantInfo); } - protected override int GetParsedValueLength(string value, int startIndex, object storeValue, - out object parsedValue) + protected override int GetParsedValueLength(string value, int startIndex, object? storeValue, + out object? parsedValue) { parsedValue = null; diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/Int64NumberHeaderParser.cs b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/Int64NumberHeaderParser.cs index 539781c5..8f582d0 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/Int64NumberHeaderParser.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/Int64NumberHeaderParser.cs @@ -29,8 +29,8 @@ namespace System.Net.Http.Headers return ((long)value).ToString(NumberFormatInfo.InvariantInfo); } - protected override int GetParsedValueLength(string value, int startIndex, object storeValue, - out object parsedValue) + protected override int GetParsedValueLength(string value, int startIndex, object? storeValue, + out object? parsedValue) { parsedValue = null; diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/KnownHeader.cs b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/KnownHeader.cs index d24739e..ce0705b 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/KnownHeader.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/KnownHeader.cs @@ -17,7 +17,7 @@ namespace System.Net.Http.Headers Debug.Assert(name[0] == ':' || HttpRuleParser.GetTokenLength(name, 0) == name.Length); } - public KnownHeader(string name, HttpHeaderType headerType, HttpHeaderParser parser, string[] knownValues = null, int? http2StaticTableIndex = null, int? http3StaticTableIndex = null) + public KnownHeader(string name, HttpHeaderType headerType, HttpHeaderParser? parser, string[]? knownValues = null, int? http2StaticTableIndex = null, int? http3StaticTableIndex = null) { Debug.Assert(!string.IsNullOrEmpty(name)); Debug.Assert(name[0] == ':' || HttpRuleParser.GetTokenLength(name, 0) == name.Length); @@ -45,13 +45,13 @@ namespace System.Net.Http.Headers } public string Name { get; } - public HttpHeaderParser Parser { get; } + public HttpHeaderParser? Parser { get; } public HttpHeaderType HeaderType { get; } /// /// If a raw string is a known value, this instance will be returned rather than allocating a new string. /// - public string[] KnownValues { get; } + public string[]? KnownValues { get; } public byte[] AsciiBytesWithColonSpace { get; } public HeaderDescriptor Descriptor => new HeaderDescriptor(this); public byte[] Http2EncodedName { get; } diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/KnownHeaders.cs b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/KnownHeaders.cs index c65483d..d07b879 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/KnownHeaders.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/KnownHeaders.cs @@ -141,7 +141,7 @@ namespace System.Net.Http.Headers // Matching is case-insenstive. // NOTE: Because of this, we do not preserve the case of the original header, // whether from the wire or from the user explicitly setting a known header using a header name string. - private static KnownHeader GetCandidate(T key) + private static KnownHeader? GetCandidate(T key) where T : struct, IHeaderNameAccessor // Enforce struct for performance { int length = key.Length; @@ -373,9 +373,9 @@ namespace System.Net.Http.Headers return null; } - internal static KnownHeader TryGetKnownHeader(string name) + internal static KnownHeader? TryGetKnownHeader(string name) { - KnownHeader candidate = GetCandidate(new StringAccessor(name)); + KnownHeader? candidate = GetCandidate(new StringAccessor(name)); if (candidate != null && StringComparer.OrdinalIgnoreCase.Equals(name, candidate.Name)) { return candidate; @@ -384,11 +384,11 @@ namespace System.Net.Http.Headers return null; } - internal static unsafe KnownHeader TryGetKnownHeader(ReadOnlySpan name) + internal static unsafe KnownHeader? TryGetKnownHeader(ReadOnlySpan name) { fixed (byte* p = &MemoryMarshal.GetReference(name)) { - KnownHeader candidate = GetCandidate(new BytePtrAccessor(p, name.Length)); + KnownHeader? candidate = GetCandidate(new BytePtrAccessor(p, name.Length)); if (candidate != null && ByteArrayHelpers.EqualsOrdinalAsciiIgnoreCase(candidate.Name, name)) { return candidate; diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/MediaTypeHeaderParser.cs b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/MediaTypeHeaderParser.cs index f70cc01..a353bed 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/MediaTypeHeaderParser.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/MediaTypeHeaderParser.cs @@ -27,11 +27,10 @@ namespace System.Net.Http.Headers _mediaTypeCreator = mediaTypeCreator; } - protected override int GetParsedValueLength(string value, int startIndex, object storeValue, - out object parsedValue) + protected override int GetParsedValueLength(string? value, int startIndex, object? storeValue, + out object? parsedValue) { - MediaTypeHeaderValue temp = null; - int resultLength = MediaTypeHeaderValue.GetMediaTypeLength(value, startIndex, _mediaTypeCreator, out temp); + int resultLength = MediaTypeHeaderValue.GetMediaTypeLength(value, startIndex, _mediaTypeCreator, out MediaTypeHeaderValue? temp); parsedValue = temp; return resultLength; diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/MediaTypeHeaderValue.cs b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/MediaTypeHeaderValue.cs index e433ded..fbb73ec 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/MediaTypeHeaderValue.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/MediaTypeHeaderValue.cs @@ -4,6 +4,7 @@ using System.Collections.Generic; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.IO; using System.Text; @@ -13,14 +14,14 @@ namespace System.Net.Http.Headers { private const string charSet = "charset"; - private ObjectCollection _parameters; - private string _mediaType; + private ObjectCollection? _parameters; + private string? _mediaType; - public string CharSet + public string? CharSet { get { - NameValueHeaderValue charSetParameter = NameValueHeaderValue.Find(_parameters, charSet); + NameValueHeaderValue? charSetParameter = NameValueHeaderValue.Find(_parameters, charSet); if (charSetParameter != null) { return charSetParameter.Value; @@ -31,13 +32,13 @@ namespace System.Net.Http.Headers { // We don't prevent a user from setting whitespace-only charsets. Like we can't prevent a user from // setting a non-existing charset. - NameValueHeaderValue charSetParameter = NameValueHeaderValue.Find(_parameters, charSet); + NameValueHeaderValue? charSetParameter = NameValueHeaderValue.Find(_parameters, charSet); if (string.IsNullOrEmpty(value)) { // Remove charset parameter if (charSetParameter != null) { - _parameters.Remove(charSetParameter); + _parameters!.Remove(charSetParameter); } } else @@ -66,7 +67,8 @@ namespace System.Net.Http.Headers } } - public string MediaType + [DisallowNull] + public string? MediaType { get { return _mediaType; } set @@ -110,9 +112,9 @@ namespace System.Net.Http.Headers return StringBuilderCache.GetStringAndRelease(sb); } - public override bool Equals(object obj) + public override bool Equals(object? obj) { - MediaTypeHeaderValue other = obj as MediaTypeHeaderValue; + MediaTypeHeaderValue? other = obj as MediaTypeHeaderValue; if (other == null) { @@ -126,22 +128,21 @@ namespace System.Net.Http.Headers public override int GetHashCode() { // The media-type string is case-insensitive. - return StringComparer.OrdinalIgnoreCase.GetHashCode(_mediaType) ^ NameValueHeaderValue.GetHashCode(_parameters); + return StringComparer.OrdinalIgnoreCase.GetHashCode(_mediaType!) ^ NameValueHeaderValue.GetHashCode(_parameters); } - public static MediaTypeHeaderValue Parse(string input) + public static MediaTypeHeaderValue Parse(string? input) { int index = 0; return (MediaTypeHeaderValue)MediaTypeHeaderParser.SingleValueParser.ParseValue(input, null, ref index); } - public static bool TryParse(string input, out MediaTypeHeaderValue parsedValue) + public static bool TryParse(string? input, [NotNullWhen(true)] out MediaTypeHeaderValue? parsedValue) { int index = 0; - object output; parsedValue = null; - if (MediaTypeHeaderParser.SingleValueParser.TryParseValue(input, null, ref index, out output)) + if (MediaTypeHeaderParser.SingleValueParser.TryParseValue(input, null, ref index, out object? output)) { parsedValue = (MediaTypeHeaderValue)output; return true; @@ -149,8 +150,8 @@ namespace System.Net.Http.Headers return false; } - internal static int GetMediaTypeLength(string input, int startIndex, - Func mediaTypeCreator, out MediaTypeHeaderValue parsedValue) + internal static int GetMediaTypeLength(string? input, int startIndex, + Func mediaTypeCreator, out MediaTypeHeaderValue? parsedValue) { Debug.Assert(mediaTypeCreator != null); Debug.Assert(startIndex >= 0); @@ -163,8 +164,7 @@ namespace System.Net.Http.Headers } // Caller must remove leading whitespace. If not, we'll return 0. - string mediaType = null; - int mediaTypeLength = MediaTypeHeaderValue.GetMediaTypeExpressionLength(input, startIndex, out mediaType); + int mediaTypeLength = MediaTypeHeaderValue.GetMediaTypeExpressionLength(input, startIndex, out string? mediaType); if (mediaTypeLength == 0) { @@ -173,7 +173,7 @@ namespace System.Net.Http.Headers int current = startIndex + mediaTypeLength; current = current + HttpRuleParser.GetWhitespaceLength(input, current); - MediaTypeHeaderValue mediaTypeHeader = null; + MediaTypeHeaderValue mediaTypeHeader; // If we're not done and we have a parameter delimiter, then we have a list of parameters. if ((current < input.Length) && (input[current] == ';')) @@ -201,7 +201,7 @@ namespace System.Net.Http.Headers return current - startIndex; } - private static int GetMediaTypeExpressionLength(string input, int startIndex, out string mediaType) + private static int GetMediaTypeExpressionLength(string input, int startIndex, out string? mediaType) { Debug.Assert((input != null) && (input.Length > 0) && (startIndex < input.Length)); @@ -259,9 +259,8 @@ namespace System.Net.Http.Headers // When adding values using strongly typed objects, no leading/trailing LWS (whitespace) are allowed. // Also no LWS between type and subtype are allowed. - string tempMediaType; - int mediaTypeLength = GetMediaTypeExpressionLength(mediaType, 0, out tempMediaType); - if ((mediaTypeLength == 0) || (tempMediaType.Length != mediaType.Length)) + int mediaTypeLength = GetMediaTypeExpressionLength(mediaType, 0, out string? tempMediaType); + if ((mediaTypeLength == 0) || (tempMediaType!.Length != mediaType.Length)) { throw new FormatException(SR.Format(System.Globalization.CultureInfo.InvariantCulture, SR.net_http_headers_invalid_value, mediaType)); } diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/MediaTypeWithQualityHeaderValue.cs b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/MediaTypeWithQualityHeaderValue.cs index ddeeda2..ad8c6c2 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/MediaTypeWithQualityHeaderValue.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/MediaTypeWithQualityHeaderValue.cs @@ -3,6 +3,7 @@ // See the LICENSE file in the project root for more information. using System; +using System.Diagnostics.CodeAnalysis; namespace System.Net.Http.Headers { @@ -42,20 +43,19 @@ namespace System.Net.Http.Headers return new MediaTypeWithQualityHeaderValue(this); } - public static new MediaTypeWithQualityHeaderValue Parse(string input) + public static new MediaTypeWithQualityHeaderValue Parse(string? input) { int index = 0; return (MediaTypeWithQualityHeaderValue)MediaTypeHeaderParser.SingleValueWithQualityParser.ParseValue( input, null, ref index); } - public static bool TryParse(string input, out MediaTypeWithQualityHeaderValue parsedValue) + public static bool TryParse(string? input, [NotNullWhen(true)] out MediaTypeWithQualityHeaderValue? parsedValue) { int index = 0; - object output; parsedValue = null; - if (MediaTypeHeaderParser.SingleValueWithQualityParser.TryParseValue(input, null, ref index, out output)) + if (MediaTypeHeaderParser.SingleValueWithQualityParser.TryParseValue(input, null, ref index, out object? output)) { parsedValue = (MediaTypeWithQualityHeaderValue)output; return true; diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/NameValueHeaderValue.cs b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/NameValueHeaderValue.cs index ed83707..12aa888 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/NameValueHeaderValue.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/NameValueHeaderValue.cs @@ -4,6 +4,7 @@ using System.Collections.Generic; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.IO; using System.Text; @@ -16,15 +17,15 @@ namespace System.Net.Http.Headers { private static readonly Func s_defaultNameValueCreator = CreateNameValue; - private string _name; - private string _value; + private string _name = null!; // Name always set after default constructor used + private string? _value; public string Name { get { return _name; } } - public string Value + public string? Value { get { return _value; } set @@ -43,7 +44,7 @@ namespace System.Net.Http.Headers { } - public NameValueHeaderValue(string name, string value) + public NameValueHeaderValue(string name, string? value) { CheckNameValueFormat(name, value); @@ -80,9 +81,9 @@ namespace System.Net.Http.Headers return nameHashCode; } - public override bool Equals(object obj) + public override bool Equals(object? obj) { - NameValueHeaderValue other = obj as NameValueHeaderValue; + NameValueHeaderValue? other = obj as NameValueHeaderValue; if (other == null) { @@ -114,20 +115,19 @@ namespace System.Net.Http.Headers } } - public static NameValueHeaderValue Parse(string input) + public static NameValueHeaderValue Parse(string? input) { int index = 0; return (NameValueHeaderValue)GenericHeaderParser.SingleValueNameValueParser.ParseValue( input, null, ref index); } - public static bool TryParse(string input, out NameValueHeaderValue parsedValue) + public static bool TryParse(string? input, [NotNullWhen(true)] out NameValueHeaderValue? parsedValue) { int index = 0; - object output; parsedValue = null; - if (GenericHeaderParser.SingleValueNameValueParser.TryParseValue(input, null, ref index, out output)) + if (GenericHeaderParser.SingleValueNameValueParser.TryParseValue(input, null, ref index, out object? output)) { parsedValue = (NameValueHeaderValue)output; return true; @@ -165,7 +165,7 @@ namespace System.Net.Http.Headers } } - internal static void ToString(ObjectCollection values, char separator, bool leadingSeparator, + internal static void ToString(ObjectCollection? values, char separator, bool leadingSeparator, StringBuilder destination) { Debug.Assert(destination != null); @@ -186,7 +186,7 @@ namespace System.Net.Http.Headers } } - internal static int GetHashCode(ObjectCollection values) + internal static int GetHashCode(ObjectCollection? values) { if ((values == null) || (values.Count == 0)) { @@ -201,13 +201,13 @@ namespace System.Net.Http.Headers return result; } - internal static int GetNameValueLength(string input, int startIndex, out NameValueHeaderValue parsedValue) + internal static int GetNameValueLength(string input, int startIndex, out NameValueHeaderValue? parsedValue) { return GetNameValueLength(input, startIndex, s_defaultNameValueCreator, out parsedValue); } internal static int GetNameValueLength(string input, int startIndex, - Func nameValueCreator, out NameValueHeaderValue parsedValue) + Func nameValueCreator, out NameValueHeaderValue? parsedValue) { Debug.Assert(input != null); Debug.Assert(startIndex >= 0); @@ -265,7 +265,7 @@ namespace System.Net.Http.Headers // Returns the length of a name/value list, separated by 'delimiter'. E.g. "a=b, c=d, e=f" adds 3 // name/value pairs to 'nameValueCollection' if 'delimiter' equals ','. - internal static int GetNameValueListLength(string input, int startIndex, char delimiter, + internal static int GetNameValueListLength(string? input, int startIndex, char delimiter, ObjectCollection nameValueCollection) { Debug.Assert(nameValueCollection != null); @@ -279,7 +279,7 @@ namespace System.Net.Http.Headers int current = startIndex + HttpRuleParser.GetWhitespaceLength(input, startIndex); while (true) { - NameValueHeaderValue parameter = null; + NameValueHeaderValue? parameter; int nameValueLength = NameValueHeaderValue.GetNameValueLength(input, current, s_defaultNameValueCreator, out parameter); @@ -288,7 +288,7 @@ namespace System.Net.Http.Headers return 0; } - nameValueCollection.Add(parameter); + nameValueCollection.Add(parameter!); current = current + nameValueLength; current = current + HttpRuleParser.GetWhitespaceLength(input, current); @@ -304,7 +304,7 @@ namespace System.Net.Http.Headers } } - internal static NameValueHeaderValue Find(ObjectCollection values, string name) + internal static NameValueHeaderValue? Find(ObjectCollection? values, string name) { Debug.Assert((name != null) && (name.Length > 0)); @@ -346,13 +346,13 @@ namespace System.Net.Http.Headers return valueLength; } - private static void CheckNameValueFormat(string name, string value) + private static void CheckNameValueFormat(string name, string? value) { HeaderUtilities.CheckValidToken(name, nameof(name)); CheckValueFormat(value); } - private static void CheckValueFormat(string value) + private static void CheckValueFormat(string? value) { // Either value is null/empty or a valid token/quoted string if (!(string.IsNullOrEmpty(value) || (GetValueLength(value, 0) == value.Length))) diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/NameValueWithParametersHeaderValue.cs b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/NameValueWithParametersHeaderValue.cs index f2a54c1..b4116e6 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/NameValueWithParametersHeaderValue.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/NameValueWithParametersHeaderValue.cs @@ -4,6 +4,7 @@ using System.Collections.Generic; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.IO; using System.Text; @@ -15,7 +16,7 @@ namespace System.Net.Http.Headers { private static readonly Func s_nameValueCreator = CreateNameValue; - private ObjectCollection _parameters; + private ObjectCollection? _parameters; public ICollection Parameters { @@ -34,7 +35,7 @@ namespace System.Net.Http.Headers { } - public NameValueWithParametersHeaderValue(string name, string value) + public NameValueWithParametersHeaderValue(string name, string? value) : base(name, value) { } @@ -55,13 +56,13 @@ namespace System.Net.Http.Headers } } - public override bool Equals(object obj) + public override bool Equals(object? obj) { bool result = base.Equals(obj); if (result) { - NameValueWithParametersHeaderValue other = obj as NameValueWithParametersHeaderValue; + NameValueWithParametersHeaderValue? other = obj as NameValueWithParametersHeaderValue; if (other == null) { @@ -87,21 +88,20 @@ namespace System.Net.Http.Headers return StringBuilderCache.GetStringAndRelease(sb); } - public static new NameValueWithParametersHeaderValue Parse(string input) + public static new NameValueWithParametersHeaderValue Parse(string? input) { int index = 0; return (NameValueWithParametersHeaderValue)GenericHeaderParser.SingleValueNameValueWithParametersParser .ParseValue(input, null, ref index); } - public static bool TryParse(string input, out NameValueWithParametersHeaderValue parsedValue) + public static bool TryParse(string? input, [NotNullWhen(true)] out NameValueWithParametersHeaderValue? parsedValue) { int index = 0; - object output; parsedValue = null; if (GenericHeaderParser.SingleValueNameValueWithParametersParser.TryParseValue(input, - null, ref index, out output)) + null, ref index, out object? output)) { parsedValue = (NameValueWithParametersHeaderValue)output; return true; @@ -109,7 +109,7 @@ namespace System.Net.Http.Headers return false; } - internal static int GetNameValueWithParametersLength(string input, int startIndex, out object parsedValue) + internal static int GetNameValueWithParametersLength(string? input, int startIndex, out object? parsedValue) { Debug.Assert(input != null); Debug.Assert(startIndex >= 0); @@ -121,9 +121,8 @@ namespace System.Net.Http.Headers return 0; } - NameValueHeaderValue nameValue = null; int nameValueLength = NameValueHeaderValue.GetNameValueLength(input, startIndex, - s_nameValueCreator, out nameValue); + s_nameValueCreator, out NameValueHeaderValue? nameValue); if (nameValueLength == 0) { @@ -132,7 +131,7 @@ namespace System.Net.Http.Headers int current = startIndex + nameValueLength; current = current + HttpRuleParser.GetWhitespaceLength(input, current); - NameValueWithParametersHeaderValue nameValueWithParameters = + NameValueWithParametersHeaderValue? nameValueWithParameters = nameValue as NameValueWithParametersHeaderValue; Debug.Assert(nameValueWithParameters != null); diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/ProductHeaderValue.cs b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/ProductHeaderValue.cs index 677600d..3f59898 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/ProductHeaderValue.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/ProductHeaderValue.cs @@ -8,8 +8,8 @@ namespace System.Net.Http.Headers { public class ProductHeaderValue : ICloneable { - private string _name; - private string _version; + private string _name = null!; + private string? _version; public string Name { @@ -17,7 +17,7 @@ namespace System.Net.Http.Headers } // We can't use the System.Version type, since a version can be e.g. "x11". - public string Version + public string? Version { get { return _version; } } @@ -27,7 +27,7 @@ namespace System.Net.Http.Headers { } - public ProductHeaderValue(string name, string version) + public ProductHeaderValue(string name, string? version) { HeaderUtilities.CheckValidToken(name, nameof(name)); @@ -61,9 +61,9 @@ namespace System.Net.Http.Headers return _name + "/" + _version; } - public override bool Equals(object obj) + public override bool Equals(object? obj) { - ProductHeaderValue other = obj as ProductHeaderValue; + ProductHeaderValue? other = obj as ProductHeaderValue; if (other == null) { @@ -86,19 +86,18 @@ namespace System.Net.Http.Headers return result; } - public static ProductHeaderValue Parse(string input) + public static ProductHeaderValue Parse(string? input) { int index = 0; return (ProductHeaderValue)GenericHeaderParser.SingleValueProductParser.ParseValue(input, null, ref index); } - public static bool TryParse(string input, out ProductHeaderValue parsedValue) + public static bool TryParse(string? input, out ProductHeaderValue? parsedValue) { int index = 0; - object output; parsedValue = null; - if (GenericHeaderParser.SingleValueProductParser.TryParseValue(input, null, ref index, out output)) + if (GenericHeaderParser.SingleValueProductParser.TryParseValue(input, null, ref index, out object? output)) { parsedValue = (ProductHeaderValue)output; return true; @@ -106,7 +105,7 @@ namespace System.Net.Http.Headers return false; } - internal static int GetProductLength(string input, int startIndex, out ProductHeaderValue parsedValue) + internal static int GetProductLength(string input, int startIndex, out ProductHeaderValue? parsedValue) { Debug.Assert(startIndex >= 0); diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/ProductInfoHeaderParser.cs b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/ProductInfoHeaderParser.cs index 97744c2..b3e4b6d 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/ProductInfoHeaderParser.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/ProductInfoHeaderParser.cs @@ -3,6 +3,7 @@ // See the LICENSE file in the project root for more information. using System; +using System.Diagnostics.CodeAnalysis; namespace System.Net.Http.Headers { @@ -21,7 +22,7 @@ namespace System.Net.Http.Headers { } - public override bool TryParseValue(string value, object storeValue, ref int index, out object parsedValue) + public override bool TryParseValue(string? value, object? storeValue, ref int index, [NotNullWhen(true)] out object? parsedValue) { parsedValue = null; @@ -38,8 +39,7 @@ namespace System.Net.Http.Headers return false; // whitespace-only values are not valid } - ProductInfoHeaderValue result = null; - int length = ProductInfoHeaderValue.GetProductInfoLength(value, current, out result); + int length = ProductInfoHeaderValue.GetProductInfoLength(value, current, out ProductInfoHeaderValue? result); if (length == 0) { @@ -65,7 +65,7 @@ namespace System.Net.Http.Headers // Separators for "User-Agent" and "Server" headers are whitespace. This is different from most other headers // where comma/semicolon is used as separator. index = current; - parsedValue = result; + parsedValue = result!; return true; } } diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/ProductInfoHeaderValue.cs b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/ProductInfoHeaderValue.cs index 1a8f3c6..85d02c1 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/ProductInfoHeaderValue.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/ProductInfoHeaderValue.cs @@ -3,25 +3,26 @@ // See the LICENSE file in the project root for more information. using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; namespace System.Net.Http.Headers { public class ProductInfoHeaderValue : ICloneable { - private ProductHeaderValue _product; - private string _comment; + private ProductHeaderValue? _product; + private string? _comment; - public ProductHeaderValue Product + public ProductHeaderValue? Product { get { return _product; } } - public string Comment + public string? Comment { get { return _comment; } } - public ProductInfoHeaderValue(string productName, string productVersion) + public ProductInfoHeaderValue(string productName, string? productVersion) : this(new ProductHeaderValue(productName, productVersion)) { } @@ -58,14 +59,15 @@ namespace System.Net.Http.Headers { if (_product == null) { + Debug.Assert(_comment != null); return _comment; } return _product.ToString(); } - public override bool Equals(object obj) + public override bool Equals(object? obj) { - ProductInfoHeaderValue other = obj as ProductInfoHeaderValue; + ProductInfoHeaderValue? other = obj as ProductInfoHeaderValue; if (other == null) { @@ -85,6 +87,7 @@ namespace System.Net.Http.Headers { if (_product == null) { + Debug.Assert(_comment != null); return _comment.GetHashCode(); } return _product.GetHashCode(); @@ -104,13 +107,12 @@ namespace System.Net.Http.Headers return (ProductInfoHeaderValue)result; } - public static bool TryParse(string input, out ProductInfoHeaderValue parsedValue) + public static bool TryParse(string input, [NotNullWhen(true)] out ProductInfoHeaderValue? parsedValue) { int index = 0; - object output; parsedValue = null; - if (ProductInfoHeaderParser.SingleValueParser.TryParseValue(input, null, ref index, out output)) + if (ProductInfoHeaderParser.SingleValueParser.TryParseValue(input, null, ref index, out object? output)) { if (index < input.Length) { @@ -124,7 +126,7 @@ namespace System.Net.Http.Headers return false; } - internal static int GetProductInfoLength(string input, int startIndex, out ProductInfoHeaderValue parsedValue) + internal static int GetProductInfoLength(string? input, int startIndex, out ProductInfoHeaderValue? parsedValue) { Debug.Assert(startIndex >= 0); @@ -138,8 +140,8 @@ namespace System.Net.Http.Headers int current = startIndex; // Caller must remove leading whitespace. - string comment = null; - ProductHeaderValue product = null; + string? comment = null; + ProductHeaderValue? product = null; if (input[current] == '(') { int commentLength = 0; diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/RangeConditionHeaderValue.cs b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/RangeConditionHeaderValue.cs index 51399c7..21c8768 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/RangeConditionHeaderValue.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/RangeConditionHeaderValue.cs @@ -3,20 +3,21 @@ // See the LICENSE file in the project root for more information. using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; namespace System.Net.Http.Headers { public class RangeConditionHeaderValue : ICloneable { private DateTimeOffset? _date; - private EntityTagHeaderValue _entityTag; + private EntityTagHeaderValue? _entityTag; public DateTimeOffset? Date { get { return _date; } } - public EntityTagHeaderValue EntityTag + public EntityTagHeaderValue? EntityTag { get { return _entityTag; } } @@ -57,14 +58,15 @@ namespace System.Net.Http.Headers { if (_entityTag == null) { + Debug.Assert(_date != null); return HttpDateParser.DateToString(_date.Value); } return _entityTag.ToString(); } - public override bool Equals(object obj) + public override bool Equals(object? obj) { - RangeConditionHeaderValue other = obj as RangeConditionHeaderValue; + RangeConditionHeaderValue? other = obj as RangeConditionHeaderValue; if (other == null) { @@ -73,6 +75,7 @@ namespace System.Net.Http.Headers if (_entityTag == null) { + Debug.Assert(_date != null); return (other._date != null) && (_date.Value == other._date.Value); } @@ -83,26 +86,26 @@ namespace System.Net.Http.Headers { if (_entityTag == null) { + Debug.Assert(_date != null); return _date.Value.GetHashCode(); } return _entityTag.GetHashCode(); } - public static RangeConditionHeaderValue Parse(string input) + public static RangeConditionHeaderValue Parse(string? input) { int index = 0; return (RangeConditionHeaderValue)GenericHeaderParser.RangeConditionParser.ParseValue( input, null, ref index); } - public static bool TryParse(string input, out RangeConditionHeaderValue parsedValue) + public static bool TryParse(string? input, [NotNullWhen(true)] out RangeConditionHeaderValue? parsedValue) { int index = 0; - object output; parsedValue = null; - if (GenericHeaderParser.RangeConditionParser.TryParseValue(input, null, ref index, out output)) + if (GenericHeaderParser.RangeConditionParser.TryParseValue(input, null, ref index, out object? output)) { parsedValue = (RangeConditionHeaderValue)output; return true; @@ -110,7 +113,7 @@ namespace System.Net.Http.Headers return false; } - internal static int GetRangeConditionLength(string input, int startIndex, out object parsedValue) + internal static int GetRangeConditionLength(string? input, int startIndex, out object? parsedValue) { Debug.Assert(startIndex >= 0); @@ -126,7 +129,7 @@ namespace System.Net.Http.Headers // Caller must remove leading whitespace. DateTimeOffset date = DateTimeOffset.MinValue; - EntityTagHeaderValue entityTag = null; + EntityTagHeaderValue? entityTag = null; // Entity tags are quoted strings optionally preceded by "W/". By looking at the first two character we // can determine whether the string is en entity tag or a date. diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/RangeHeaderValue.cs b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/RangeHeaderValue.cs index 554f65c..1e3a44e 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/RangeHeaderValue.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/RangeHeaderValue.cs @@ -4,6 +4,7 @@ using System.Collections.Generic; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.IO; using System.Text; @@ -12,7 +13,7 @@ namespace System.Net.Http.Headers public class RangeHeaderValue : ICloneable { private string _unit; - private ObjectCollection _ranges; + private ObjectCollection? _ranges; public string Unit { @@ -91,9 +92,9 @@ namespace System.Net.Http.Headers return StringBuilderCache.GetStringAndRelease(sb); } - public override bool Equals(object obj) + public override bool Equals(object? obj) { - RangeHeaderValue other = obj as RangeHeaderValue; + RangeHeaderValue? other = obj as RangeHeaderValue; if (other == null) { @@ -119,19 +120,18 @@ namespace System.Net.Http.Headers return result; } - public static RangeHeaderValue Parse(string input) + public static RangeHeaderValue Parse(string? input) { int index = 0; return (RangeHeaderValue)GenericHeaderParser.RangeParser.ParseValue(input, null, ref index); } - public static bool TryParse(string input, out RangeHeaderValue parsedValue) + public static bool TryParse(string? input, [NotNullWhen(true)] out RangeHeaderValue? parsedValue) { int index = 0; - object output; - parsedValue = null; + parsedValue = null; - if (GenericHeaderParser.RangeParser.TryParseValue(input, null, ref index, out output)) + if (GenericHeaderParser.RangeParser.TryParseValue(input, null, ref index, out object? output)) { parsedValue = (RangeHeaderValue)output; return true; @@ -139,7 +139,7 @@ namespace System.Net.Http.Headers return false; } - internal static int GetRangeLength(string input, int startIndex, out object parsedValue) + internal static int GetRangeLength(string? input, int startIndex, out object? parsedValue) { Debug.Assert(startIndex >= 0); diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/RangeItemHeaderValue.cs b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/RangeItemHeaderValue.cs index 4576470..b848edd 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/RangeItemHeaderValue.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/RangeItemHeaderValue.cs @@ -58,6 +58,7 @@ namespace System.Net.Http.Headers { if (!_from.HasValue) { + Debug.Assert(_to != null); return "-" + _to.Value.ToString(NumberFormatInfo.InvariantInfo); } else if (!_to.HasValue) @@ -68,9 +69,9 @@ namespace System.Net.Http.Headers _to.Value.ToString(NumberFormatInfo.InvariantInfo); } - public override bool Equals(object obj) + public override bool Equals(object? obj) { - RangeItemHeaderValue other = obj as RangeItemHeaderValue; + RangeItemHeaderValue? other = obj as RangeItemHeaderValue; if (other == null) { @@ -94,7 +95,7 @@ namespace System.Net.Http.Headers // Returns the length of a range list. E.g. "1-2, 3-4, 5-6" adds 3 ranges to 'rangeCollection'. Note that empty // list segments are allowed, e.g. ",1-2, , 3-4,,". - internal static int GetRangeItemListLength(string input, int startIndex, + internal static int GetRangeItemListLength(string? input, int startIndex, ICollection rangeCollection) { Debug.Assert(rangeCollection != null); @@ -115,7 +116,7 @@ namespace System.Net.Http.Headers return 0; } - RangeItemHeaderValue range = null; + RangeItemHeaderValue? range; while (true) { int rangeLength = GetRangeItemLength(input, current, out range); @@ -125,7 +126,7 @@ namespace System.Net.Http.Headers return 0; } - rangeCollection.Add(range); + rangeCollection.Add(range!); current = current + rangeLength; current = HeaderUtilities.GetNextNonEmptyOrWhitespaceIndex(input, current, true, out separatorFound); @@ -144,7 +145,7 @@ namespace System.Net.Http.Headers } } - internal static int GetRangeItemLength(string input, int startIndex, out RangeItemHeaderValue parsedValue) + internal static int GetRangeItemLength(string? input, int startIndex, out RangeItemHeaderValue? parsedValue) { Debug.Assert(startIndex >= 0); diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/RetryConditionHeaderValue.cs b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/RetryConditionHeaderValue.cs index 81822d9..26152f3 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/RetryConditionHeaderValue.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/RetryConditionHeaderValue.cs @@ -4,6 +4,7 @@ using System.Diagnostics; using System.Globalization; +using System.Diagnostics.CodeAnalysis; namespace System.Net.Http.Headers { @@ -56,12 +57,13 @@ namespace System.Net.Http.Headers { return ((int)_delta.Value.TotalSeconds).ToString(NumberFormatInfo.InvariantInfo); } + Debug.Assert(_date != null); return HttpDateParser.DateToString(_date.Value); } - public override bool Equals(object obj) + public override bool Equals(object? obj) { - RetryConditionHeaderValue other = obj as RetryConditionHeaderValue; + RetryConditionHeaderValue? other = obj as RetryConditionHeaderValue; if (other == null) { @@ -73,6 +75,7 @@ namespace System.Net.Http.Headers return (other._delta != null) && (_delta.Value == other._delta.Value); } + Debug.Assert(_date != null); return (other._date != null) && (_date.Value == other._date.Value); } @@ -80,26 +83,26 @@ namespace System.Net.Http.Headers { if (_delta == null) { + Debug.Assert(_date != null); return _date.Value.GetHashCode(); } return _delta.Value.GetHashCode(); } - public static RetryConditionHeaderValue Parse(string input) + public static RetryConditionHeaderValue Parse(string? input) { int index = 0; return (RetryConditionHeaderValue)GenericHeaderParser.RetryConditionParser.ParseValue( input, null, ref index); } - public static bool TryParse(string input, out RetryConditionHeaderValue parsedValue) + public static bool TryParse(string? input, [NotNullWhen(true)] out RetryConditionHeaderValue? parsedValue) { int index = 0; - object output; parsedValue = null; - if (GenericHeaderParser.RetryConditionParser.TryParseValue(input, null, ref index, out output)) + if (GenericHeaderParser.RetryConditionParser.TryParseValue(input, null, ref index, out object? output)) { parsedValue = (RetryConditionHeaderValue)output; return true; @@ -107,7 +110,7 @@ namespace System.Net.Http.Headers return false; } - internal static int GetRetryConditionLength(string input, int startIndex, out object parsedValue) + internal static int GetRetryConditionLength(string? input, int startIndex, out object? parsedValue) { Debug.Assert(startIndex >= 0); diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/StringWithQualityHeaderValue.cs b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/StringWithQualityHeaderValue.cs index 98e0fcd..fc516ee 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/StringWithQualityHeaderValue.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/StringWithQualityHeaderValue.cs @@ -3,13 +3,14 @@ // See the LICENSE file in the project root for more information. using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Globalization; namespace System.Net.Http.Headers { public class StringWithQualityHeaderValue : ICloneable { - private string _value; + private string _value = null!; private double? _quality; public string Value @@ -64,9 +65,9 @@ namespace System.Net.Http.Headers return _value; } - public override bool Equals(object obj) + public override bool Equals(object? obj) { - StringWithQualityHeaderValue other = obj as StringWithQualityHeaderValue; + StringWithQualityHeaderValue? other = obj as StringWithQualityHeaderValue; if (other == null) { @@ -103,21 +104,20 @@ namespace System.Net.Http.Headers return result; } - public static StringWithQualityHeaderValue Parse(string input) + public static StringWithQualityHeaderValue Parse(string? input) { int index = 0; return (StringWithQualityHeaderValue)GenericHeaderParser.SingleValueStringWithQualityParser.ParseValue( input, null, ref index); } - public static bool TryParse(string input, out StringWithQualityHeaderValue parsedValue) + public static bool TryParse(string? input, [NotNullWhen(true)] out StringWithQualityHeaderValue? parsedValue) { int index = 0; - object output; parsedValue = null; if (GenericHeaderParser.SingleValueStringWithQualityParser.TryParseValue( - input, null, ref index, out output)) + input, null, ref index, out object? output)) { parsedValue = (StringWithQualityHeaderValue)output; return true; @@ -125,7 +125,7 @@ namespace System.Net.Http.Headers return false; } - internal static int GetStringWithQualityLength(string input, int startIndex, out object parsedValue) + internal static int GetStringWithQualityLength(string? input, int startIndex, out object? parsedValue) { Debug.Assert(startIndex >= 0); diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/TimeSpanHeaderParser.cs b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/TimeSpanHeaderParser.cs index 99cd0d1..f8db68c 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/TimeSpanHeaderParser.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/TimeSpanHeaderParser.cs @@ -23,8 +23,8 @@ namespace System.Net.Http.Headers return ((int)((TimeSpan)value).TotalSeconds).ToString(NumberFormatInfo.InvariantInfo); } - protected override int GetParsedValueLength(string value, int startIndex, object storeValue, - out object parsedValue) + protected override int GetParsedValueLength(string value, int startIndex, object? storeValue, + out object? parsedValue) { parsedValue = null; diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/TransferCodingHeaderParser.cs b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/TransferCodingHeaderParser.cs index 8a904bf..9bd31fa 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/TransferCodingHeaderParser.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/TransferCodingHeaderParser.cs @@ -28,12 +28,11 @@ namespace System.Net.Http.Headers _transferCodingCreator = transferCodingCreator; } - protected override int GetParsedValueLength(string value, int startIndex, object storeValue, - out object parsedValue) + protected override int GetParsedValueLength(string value, int startIndex, object? storeValue, + out object? parsedValue) { - TransferCodingHeaderValue temp = null; int resultLength = TransferCodingHeaderValue.GetTransferCodingLength(value, startIndex, - _transferCodingCreator, out temp); + _transferCodingCreator, out TransferCodingHeaderValue? temp); parsedValue = temp; return resultLength; diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/TransferCodingHeaderValue.cs b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/TransferCodingHeaderValue.cs index 177623e..a11cb4a 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/TransferCodingHeaderValue.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/TransferCodingHeaderValue.cs @@ -4,6 +4,7 @@ using System.Collections.Generic; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.IO; using System.Text; @@ -12,8 +13,8 @@ namespace System.Net.Http.Headers public class TransferCodingHeaderValue : ICloneable { // Use ObjectCollection since we may have multiple parameters with the same name. - private ObjectCollection _parameters; - private string _value; + private ObjectCollection? _parameters; + private string _value = null!; // empty constructor only used internally and value set with non null public string Value { @@ -57,20 +58,19 @@ namespace System.Net.Http.Headers _value = value; } - public static TransferCodingHeaderValue Parse(string input) + public static TransferCodingHeaderValue Parse(string? input) { int index = 0; return (TransferCodingHeaderValue)TransferCodingHeaderParser.SingleValueParser.ParseValue( input, null, ref index); } - public static bool TryParse(string input, out TransferCodingHeaderValue parsedValue) + public static bool TryParse(string? input, [NotNullWhen(true)] out TransferCodingHeaderValue? parsedValue) { int index = 0; - object output; parsedValue = null; - if (TransferCodingHeaderParser.SingleValueParser.TryParseValue(input, null, ref index, out output)) + if (TransferCodingHeaderParser.SingleValueParser.TryParseValue(input, null, ref index, out object? output)) { parsedValue = (TransferCodingHeaderValue)output; return true; @@ -79,7 +79,7 @@ namespace System.Net.Http.Headers } internal static int GetTransferCodingLength(string input, int startIndex, - Func transferCodingCreator, out TransferCodingHeaderValue parsedValue) + Func transferCodingCreator, out TransferCodingHeaderValue? parsedValue) { Debug.Assert(transferCodingCreator != null); Debug.Assert(startIndex >= 0); @@ -102,7 +102,7 @@ namespace System.Net.Http.Headers string value = input.Substring(startIndex, valueLength); int current = startIndex + valueLength; current = current + HttpRuleParser.GetWhitespaceLength(input, current); - TransferCodingHeaderValue transferCodingHeader = null; + TransferCodingHeaderValue transferCodingHeader; // If we're not done and we have a parameter delimiter, then we have a list of parameters. if ((current < input.Length) && (input[current] == ';')) @@ -138,9 +138,9 @@ namespace System.Net.Http.Headers return StringBuilderCache.GetStringAndRelease(sb); } - public override bool Equals(object obj) + public override bool Equals(object? obj) { - TransferCodingHeaderValue other = obj as TransferCodingHeaderValue; + TransferCodingHeaderValue? other = obj as TransferCodingHeaderValue; if (other == null) { diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/TransferCodingWithQualityHeaderValue.cs b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/TransferCodingWithQualityHeaderValue.cs index 5eef034..f4fd075 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/TransferCodingWithQualityHeaderValue.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/TransferCodingWithQualityHeaderValue.cs @@ -3,6 +3,7 @@ // See the LICENSE file in the project root for more information. using System; +using System.Diagnostics.CodeAnalysis; namespace System.Net.Http.Headers { @@ -41,21 +42,20 @@ namespace System.Net.Http.Headers return new TransferCodingWithQualityHeaderValue(this); } - public static new TransferCodingWithQualityHeaderValue Parse(string input) + public static new TransferCodingWithQualityHeaderValue Parse(string? input) { int index = 0; return (TransferCodingWithQualityHeaderValue)TransferCodingHeaderParser.SingleValueWithQualityParser .ParseValue(input, null, ref index); } - public static bool TryParse(string input, out TransferCodingWithQualityHeaderValue parsedValue) + public static bool TryParse(string? input, [NotNullWhen(true)] out TransferCodingWithQualityHeaderValue? parsedValue) { int index = 0; - object output; parsedValue = null; if (TransferCodingHeaderParser.SingleValueWithQualityParser.TryParseValue( - input, null, ref index, out output)) + input, null, ref index, out object? output)) { parsedValue = (TransferCodingWithQualityHeaderValue)output; return true; diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/UriHeaderParser.cs b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/UriHeaderParser.cs index 3e0a6f5..4d75e84 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/UriHeaderParser.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/UriHeaderParser.cs @@ -4,6 +4,7 @@ using System; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; namespace System.Net.Http.Headers { @@ -22,7 +23,7 @@ namespace System.Net.Http.Headers _uriKind = uriKind; } - public override bool TryParseValue(string value, object storeValue, ref int index, out object parsedValue) + public override bool TryParseValue(string? value, object? storeValue, ref int index, [NotNullWhen(true)] out object? parsedValue) { parsedValue = null; @@ -38,8 +39,7 @@ namespace System.Net.Http.Headers uriString = value.Substring(index); } - Uri uri; - if (!Uri.TryCreate(uriString, _uriKind, out uri)) + if (!Uri.TryCreate(uriString, _uriKind, out Uri? uri)) { // Some servers send the host names in Utf-8. uriString = DecodeUtf8FromString(uriString); diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/ViaHeaderValue.cs b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/ViaHeaderValue.cs index 2e8ecd7..24cbbb9 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/ViaHeaderValue.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/ViaHeaderValue.cs @@ -3,6 +3,7 @@ // See the LICENSE file in the project root for more information. using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.IO; using System.Text; @@ -10,12 +11,12 @@ namespace System.Net.Http.Headers { public class ViaHeaderValue : ICloneable { - private string _protocolName; - private string _protocolVersion; - private string _receivedBy; - private string _comment; + private string? _protocolName; + private string _protocolVersion = null!; + private string _receivedBy = null!; + private string? _comment; - public string ProtocolName + public string? ProtocolName { get { return _protocolName; } } @@ -30,7 +31,7 @@ namespace System.Net.Http.Headers get { return _receivedBy; } } - public string Comment + public string? Comment { get { return _comment; } } @@ -40,12 +41,12 @@ namespace System.Net.Http.Headers { } - public ViaHeaderValue(string protocolVersion, string receivedBy, string protocolName) + public ViaHeaderValue(string protocolVersion, string receivedBy, string? protocolName) : this(protocolVersion, receivedBy, protocolName, null) { } - public ViaHeaderValue(string protocolVersion, string receivedBy, string protocolName, string comment) + public ViaHeaderValue(string protocolVersion, string receivedBy, string? protocolName, string? comment) { HeaderUtilities.CheckValidToken(protocolVersion, nameof(protocolVersion)); CheckReceivedBy(receivedBy); @@ -103,9 +104,9 @@ namespace System.Net.Http.Headers return StringBuilderCache.GetStringAndRelease(sb); } - public override bool Equals(object obj) + public override bool Equals(object? obj) { - ViaHeaderValue other = obj as ViaHeaderValue; + ViaHeaderValue? other = obj as ViaHeaderValue; if (other == null) { @@ -138,19 +139,18 @@ namespace System.Net.Http.Headers return result; } - public static ViaHeaderValue Parse(string input) + public static ViaHeaderValue Parse(string? input) { int index = 0; return (ViaHeaderValue)GenericHeaderParser.SingleValueViaParser.ParseValue(input, null, ref index); } - public static bool TryParse(string input, out ViaHeaderValue parsedValue) + public static bool TryParse(string? input, [NotNullWhen(true)] out ViaHeaderValue? parsedValue) { int index = 0; - object output; parsedValue = null; - if (GenericHeaderParser.SingleValueViaParser.TryParseValue(input, null, ref index, out output)) + if (GenericHeaderParser.SingleValueViaParser.TryParseValue(input, null, ref index, out object? output)) { parsedValue = (ViaHeaderValue)output; return true; @@ -158,7 +158,7 @@ namespace System.Net.Http.Headers return false; } - internal static int GetViaLength(string input, int startIndex, out object parsedValue) + internal static int GetViaLength(string? input, int startIndex, out object? parsedValue) { Debug.Assert(startIndex >= 0); @@ -170,9 +170,7 @@ namespace System.Net.Http.Headers } // Read and in '[/] []' - string protocolName = null; - string protocolVersion = null; - int current = GetProtocolEndIndex(input, startIndex, out protocolName, out protocolVersion); + int current = GetProtocolEndIndex(input, startIndex, out string? protocolName, out string? protocolVersion); // If we reached the end of the string after reading protocolName/Version we return (we expect at least // to follow). If reading protocolName/Version read 0 bytes, we return. @@ -183,8 +181,7 @@ namespace System.Net.Http.Headers Debug.Assert(protocolVersion != null); // Read in '[/] []' - string receivedBy = null; - int receivedByLength = HttpRuleParser.GetHostLength(input, current, true, out receivedBy); + int receivedByLength = HttpRuleParser.GetHostLength(input, current, true, out string? receivedBy); if (receivedByLength == 0) { @@ -194,7 +191,7 @@ namespace System.Net.Http.Headers current = current + receivedByLength; current = current + HttpRuleParser.GetWhitespaceLength(input, current); - string comment = null; + string? comment = null; if ((current < input.Length) && (input[current] == '(')) { // We have a in '[/] []' @@ -213,15 +210,15 @@ namespace System.Net.Http.Headers ViaHeaderValue result = new ViaHeaderValue(); result._protocolVersion = protocolVersion; result._protocolName = protocolName; - result._receivedBy = receivedBy; + result._receivedBy = receivedBy!; result._comment = comment; parsedValue = result; return current - startIndex; } - private static int GetProtocolEndIndex(string input, int startIndex, out string protocolName, - out string protocolVersion) + private static int GetProtocolEndIndex(string input, int startIndex, out string? protocolName, + out string? protocolVersion) { // We have a string of the form '[/] []'. The first // token may either be the protocol name or protocol version. We'll only find out after reading the token @@ -294,9 +291,8 @@ namespace System.Net.Http.Headers } // 'receivedBy' can either be a host or a token. Since a token is a valid host, we only verify if the value - // is a valid host. - string host = null; - if (HttpRuleParser.GetHostLength(receivedBy, 0, true, out host) != receivedBy.Length) + // is a valid host.; + if (HttpRuleParser.GetHostLength(receivedBy, 0, true, out string? host) != receivedBy.Length) { throw new FormatException(SR.Format(System.Globalization.CultureInfo.InvariantCulture, SR.net_http_headers_invalid_value, receivedBy)); } diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/WarningHeaderValue.cs b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/WarningHeaderValue.cs index bf18913..0b4439f 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/WarningHeaderValue.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/WarningHeaderValue.cs @@ -3,6 +3,7 @@ // See the LICENSE file in the project root for more information. using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.IO; using System.Text; @@ -12,8 +13,8 @@ namespace System.Net.Http.Headers public class WarningHeaderValue : ICloneable { private int _code; - private string _agent; - private string _text; + private string _agent = null!; + private string _text = null!; private DateTimeOffset? _date; public int Code @@ -95,9 +96,9 @@ namespace System.Net.Http.Headers return StringBuilderCache.GetStringAndRelease(sb); } - public override bool Equals(object obj) + public override bool Equals(object? obj) { - WarningHeaderValue other = obj as WarningHeaderValue; + WarningHeaderValue? other = obj as WarningHeaderValue; if (other == null) { @@ -136,19 +137,18 @@ namespace System.Net.Http.Headers return result; } - public static WarningHeaderValue Parse(string input) + public static WarningHeaderValue Parse(string? input) { int index = 0; return (WarningHeaderValue)GenericHeaderParser.SingleValueWarningParser.ParseValue(input, null, ref index); } - public static bool TryParse(string input, out WarningHeaderValue parsedValue) + public static bool TryParse(string? input, [NotNullWhen(true)] out WarningHeaderValue? parsedValue) { int index = 0; - object output; parsedValue = null; - if (GenericHeaderParser.SingleValueWarningParser.TryParseValue(input, null, ref index, out output)) + if (GenericHeaderParser.SingleValueWarningParser.TryParseValue(input, null, ref index, out object? output)) { parsedValue = (WarningHeaderValue)output; return true; @@ -156,7 +156,7 @@ namespace System.Net.Http.Headers return false; } - internal static int GetWarningLength(string input, int startIndex, out object parsedValue) + internal static int GetWarningLength(string? input, int startIndex, out object? parsedValue) { Debug.Assert(startIndex >= 0); @@ -177,8 +177,7 @@ namespace System.Net.Http.Headers } // Read in ' [""]' - string agent; - if (!TryReadAgent(input, current, ref current, out agent)) + if (!TryReadAgent(input, current, ref current, out string? agent)) { return 0; } @@ -210,11 +209,9 @@ namespace System.Net.Http.Headers return current - startIndex; } - private static bool TryReadAgent(string input, int startIndex, ref int current, out string agent) + private static bool TryReadAgent(string input, int startIndex, ref int current, [NotNullWhen(true)] out string? agent) { - agent = null; - - int agentLength = HttpRuleParser.GetHostLength(input, startIndex, true, out agent); + int agentLength = HttpRuleParser.GetHostLength(input, startIndex, true, out agent!); if (agentLength == 0) { @@ -337,8 +334,7 @@ namespace System.Net.Http.Headers // 'receivedBy' can either be a host or a token. Since a token is a valid host, we only verify if the value // is a valid host. - string host = null; - if (HttpRuleParser.GetHostLength(agent, 0, true, out host) != agent.Length) + if (HttpRuleParser.GetHostLength(agent, 0, true, out string? host) != agent.Length) { throw new FormatException(SR.Format(System.Globalization.CultureInfo.InvariantCulture, SR.net_http_headers_invalid_value, agent)); } diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/HttpClient.cs b/src/libraries/System.Net.Http/src/System/Net/Http/HttpClient.cs index ba716da..91d955b 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/HttpClient.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/HttpClient.cs @@ -15,7 +15,7 @@ namespace System.Net.Http { #region Fields - private static IWebProxy s_defaultProxy; + private static IWebProxy? s_defaultProxy; private static readonly TimeSpan s_defaultTimeout = TimeSpan.FromSeconds(100); private static readonly TimeSpan s_maxTimeout = TimeSpan.FromMilliseconds(int.MaxValue); private static readonly TimeSpan s_infiniteTimeout = Threading.Timeout.InfiniteTimeSpan; @@ -25,10 +25,10 @@ namespace System.Net.Http private volatile bool _disposed; private CancellationTokenSource _pendingRequestsCts; - private HttpRequestHeaders _defaultRequestHeaders; + private HttpRequestHeaders? _defaultRequestHeaders; private Version _defaultRequestVersion = HttpUtilities.DefaultRequestVersion; - private Uri _baseAddress; + private Uri? _baseAddress; private TimeSpan _timeout; private int _maxResponseContentBufferSize; @@ -67,7 +67,7 @@ namespace System.Net.Http } } - public Uri BaseAddress + public Uri? BaseAddress { get { return _baseAddress; } set @@ -145,16 +145,16 @@ namespace System.Net.Http #region Simple Get Overloads - public Task GetStringAsync(string requestUri) => + public Task GetStringAsync(string? requestUri) => GetStringAsync(CreateUri(requestUri)); - public Task GetStringAsync(Uri requestUri) => + public Task GetStringAsync(Uri? requestUri) => GetStringAsync(requestUri, CancellationToken.None); - public Task GetStringAsync(string requestUri, CancellationToken cancellationToken) => + public Task GetStringAsync(string? requestUri, CancellationToken cancellationToken) => GetStringAsync(CreateUri(requestUri), cancellationToken); - public Task GetStringAsync(Uri requestUri, CancellationToken cancellationToken) => + public Task GetStringAsync(Uri? requestUri, CancellationToken cancellationToken) => GetStringAsyncCore(GetAsync(requestUri, HttpCompletionOption.ResponseHeadersRead, cancellationToken), cancellationToken); private async Task GetStringAsyncCore(Task getTask, CancellationToken cancellationToken) @@ -166,7 +166,7 @@ namespace System.Net.Http responseMessage.EnsureSuccessStatusCode(); // Get the response content. - HttpContent c = responseMessage.Content; + HttpContent? c = responseMessage.Content; if (c != null) { #if NET46 @@ -202,16 +202,16 @@ namespace System.Net.Http } } - public Task GetByteArrayAsync(string requestUri) => + public Task GetByteArrayAsync(string? requestUri) => GetByteArrayAsync(CreateUri(requestUri)); - public Task GetByteArrayAsync(Uri requestUri) => + public Task GetByteArrayAsync(Uri? requestUri) => GetByteArrayAsync(requestUri, CancellationToken.None); - public Task GetByteArrayAsync(string requestUri, CancellationToken cancellationToken) => + public Task GetByteArrayAsync(string? requestUri, CancellationToken cancellationToken) => GetByteArrayAsync(CreateUri(requestUri), cancellationToken); - public Task GetByteArrayAsync(Uri requestUri, CancellationToken cancellationToken) => + public Task GetByteArrayAsync(Uri? requestUri, CancellationToken cancellationToken) => GetByteArrayAsyncCore(GetAsync(requestUri, HttpCompletionOption.ResponseHeadersRead, cancellationToken), cancellationToken); private async Task GetByteArrayAsyncCore(Task getTask, CancellationToken cancellationToken) @@ -223,7 +223,7 @@ namespace System.Net.Http responseMessage.EnsureSuccessStatusCode(); // Get the response content. - HttpContent c = responseMessage.Content; + HttpContent? c = responseMessage.Content; if (c != null) { #if NET46 @@ -290,23 +290,23 @@ namespace System.Net.Http } } - public Task GetStreamAsync(string requestUri) => + public Task GetStreamAsync(string? requestUri) => GetStreamAsync(CreateUri(requestUri)); - public Task GetStreamAsync(string requestUri, CancellationToken cancellationToken) => + public Task GetStreamAsync(string? requestUri, CancellationToken cancellationToken) => GetStreamAsync(CreateUri(requestUri), cancellationToken); - public Task GetStreamAsync(Uri requestUri) => + public Task GetStreamAsync(Uri? requestUri) => GetStreamAsync(requestUri, CancellationToken.None); - public Task GetStreamAsync(Uri requestUri, CancellationToken cancellationToken) => + public Task GetStreamAsync(Uri? requestUri, CancellationToken cancellationToken) => FinishGetStreamAsync(GetAsync(requestUri, HttpCompletionOption.ResponseHeadersRead, cancellationToken), cancellationToken); private async Task FinishGetStreamAsync(Task getTask, CancellationToken cancellationToken) { HttpResponseMessage response = await getTask.ConfigureAwait(false); response.EnsureSuccessStatusCode(); - HttpContent c = response.Content; + HttpContent? c = response.Content; return c != null ? (c.TryReadAsStream() ?? await c.ReadAsStreamAsync(cancellationToken).ConfigureAwait(false)) : Stream.Null; @@ -316,65 +316,65 @@ namespace System.Net.Http #region REST Send Overloads - public Task GetAsync(string requestUri) + public Task GetAsync(string? requestUri) { return GetAsync(CreateUri(requestUri)); } - public Task GetAsync(Uri requestUri) + public Task GetAsync(Uri? requestUri) { return GetAsync(requestUri, defaultCompletionOption); } - public Task GetAsync(string requestUri, HttpCompletionOption completionOption) + public Task GetAsync(string? requestUri, HttpCompletionOption completionOption) { return GetAsync(CreateUri(requestUri), completionOption); } - public Task GetAsync(Uri requestUri, HttpCompletionOption completionOption) + public Task GetAsync(Uri? requestUri, HttpCompletionOption completionOption) { return GetAsync(requestUri, completionOption, CancellationToken.None); } - public Task GetAsync(string requestUri, CancellationToken cancellationToken) + public Task GetAsync(string? requestUri, CancellationToken cancellationToken) { return GetAsync(CreateUri(requestUri), cancellationToken); } - public Task GetAsync(Uri requestUri, CancellationToken cancellationToken) + public Task GetAsync(Uri? requestUri, CancellationToken cancellationToken) { return GetAsync(requestUri, defaultCompletionOption, cancellationToken); } - public Task GetAsync(string requestUri, HttpCompletionOption completionOption, + public Task GetAsync(string? requestUri, HttpCompletionOption completionOption, CancellationToken cancellationToken) { return GetAsync(CreateUri(requestUri), completionOption, cancellationToken); } - public Task GetAsync(Uri requestUri, HttpCompletionOption completionOption, + public Task GetAsync(Uri? requestUri, HttpCompletionOption completionOption, CancellationToken cancellationToken) { return SendAsync(CreateRequestMessage(HttpMethod.Get, requestUri), completionOption, cancellationToken); } - public Task PostAsync(string requestUri, HttpContent content) + public Task PostAsync(string? requestUri, HttpContent content) { return PostAsync(CreateUri(requestUri), content); } - public Task PostAsync(Uri requestUri, HttpContent content) + public Task PostAsync(Uri? requestUri, HttpContent content) { return PostAsync(requestUri, content, CancellationToken.None); } - public Task PostAsync(string requestUri, HttpContent content, + public Task PostAsync(string? requestUri, HttpContent content, CancellationToken cancellationToken) { return PostAsync(CreateUri(requestUri), content, cancellationToken); } - public Task PostAsync(Uri requestUri, HttpContent content, + public Task PostAsync(Uri? requestUri, HttpContent content, CancellationToken cancellationToken) { HttpRequestMessage request = CreateRequestMessage(HttpMethod.Post, requestUri); @@ -382,23 +382,23 @@ namespace System.Net.Http return SendAsync(request, cancellationToken); } - public Task PutAsync(string requestUri, HttpContent content) + public Task PutAsync(string? requestUri, HttpContent content) { return PutAsync(CreateUri(requestUri), content); } - public Task PutAsync(Uri requestUri, HttpContent content) + public Task PutAsync(Uri? requestUri, HttpContent content) { return PutAsync(requestUri, content, CancellationToken.None); } - public Task PutAsync(string requestUri, HttpContent content, + public Task PutAsync(string? requestUri, HttpContent content, CancellationToken cancellationToken) { return PutAsync(CreateUri(requestUri), content, cancellationToken); } - public Task PutAsync(Uri requestUri, HttpContent content, + public Task PutAsync(Uri? requestUri, HttpContent content, CancellationToken cancellationToken) { HttpRequestMessage request = CreateRequestMessage(HttpMethod.Put, requestUri); @@ -406,23 +406,23 @@ namespace System.Net.Http return SendAsync(request, cancellationToken); } - public Task PatchAsync(string requestUri, HttpContent content) + public Task PatchAsync(string? requestUri, HttpContent content) { return PatchAsync(CreateUri(requestUri), content); } - public Task PatchAsync(Uri requestUri, HttpContent content) + public Task PatchAsync(Uri? requestUri, HttpContent content) { return PatchAsync(requestUri, content, CancellationToken.None); } - public Task PatchAsync(string requestUri, HttpContent content, + public Task PatchAsync(string? requestUri, HttpContent content, CancellationToken cancellationToken) { return PatchAsync(CreateUri(requestUri), content, cancellationToken); } - public Task PatchAsync(Uri requestUri, HttpContent content, + public Task PatchAsync(Uri? requestUri, HttpContent content, CancellationToken cancellationToken) { HttpRequestMessage request = CreateRequestMessage(HttpMethod.Patch, requestUri); @@ -430,22 +430,22 @@ namespace System.Net.Http return SendAsync(request, cancellationToken); } - public Task DeleteAsync(string requestUri) + public Task DeleteAsync(string? requestUri) { return DeleteAsync(CreateUri(requestUri)); } - public Task DeleteAsync(Uri requestUri) + public Task DeleteAsync(Uri? requestUri) { return DeleteAsync(requestUri, CancellationToken.None); } - public Task DeleteAsync(string requestUri, CancellationToken cancellationToken) + public Task DeleteAsync(string? requestUri, CancellationToken cancellationToken) { return DeleteAsync(CreateUri(requestUri), cancellationToken); } - public Task DeleteAsync(Uri requestUri, CancellationToken cancellationToken) + public Task DeleteAsync(Uri? requestUri, CancellationToken cancellationToken) { return SendAsync(CreateRequestMessage(HttpMethod.Delete, requestUri), cancellationToken); } @@ -535,7 +535,7 @@ namespace System.Net.Http private async Task FinishSendAsyncBuffered( Task sendTask, HttpRequestMessage request, CancellationTokenSource cts, bool disposeCts, CancellationToken callerToken, long timeoutTime) { - HttpResponseMessage response = null; + HttpResponseMessage? response = null; try { // Wait for the send request to complete, getting back the response. @@ -740,7 +740,7 @@ namespace System.Net.Http private void PrepareRequestMessage(HttpRequestMessage request) { - Uri requestUri = null; + Uri? requestUri = null; if ((request.RequestUri == null) && (_baseAddress == null)) { throw new InvalidOperationException(SR.net_http_client_invalid_requesturi); @@ -778,7 +778,7 @@ namespace System.Net.Http } } - private static void CheckBaseAddress(Uri baseAddress, string parameterName) + private static void CheckBaseAddress(Uri? baseAddress, string parameterName) { if (baseAddress == null) { @@ -796,10 +796,10 @@ namespace System.Net.Http } } - private Uri CreateUri(string uri) => + private Uri? CreateUri(string? uri) => string.IsNullOrEmpty(uri) ? null : new Uri(uri, UriKind.RelativeOrAbsolute); - private HttpRequestMessage CreateRequestMessage(HttpMethod method, Uri uri) => + private HttpRequestMessage CreateRequestMessage(HttpMethod method, Uri? uri) => new HttpRequestMessage(method, uri) { Version = _defaultRequestVersion }; #endregion Private Helpers } diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/HttpClientHandler.cs b/src/libraries/System.Net.Http/src/System/Net/Http/HttpClientHandler.cs index 280b506..1851c5a 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/HttpClientHandler.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/HttpClientHandler.cs @@ -71,13 +71,13 @@ namespace System.Net.Http set => _socketsHttpHandler.UseProxy = value; } - public IWebProxy Proxy + public IWebProxy? Proxy { get => _socketsHttpHandler.Proxy; set => _socketsHttpHandler.Proxy = value; } - public ICredentials DefaultProxyCredentials + public ICredentials? DefaultProxyCredentials { get => _socketsHttpHandler.DefaultProxyCredentials; set => _socketsHttpHandler.DefaultProxyCredentials = value; @@ -111,7 +111,7 @@ namespace System.Net.Http } } - public ICredentials Credentials + public ICredentials? Credentials { get => _socketsHttpHandler.Credentials; set => _socketsHttpHandler.Credentials = value; @@ -151,13 +151,13 @@ namespace System.Net.Http case ClientCertificateOption.Manual: ThrowForModifiedManagedSslOptionsIfStarted(); _clientCertificateOptions = value; - _socketsHttpHandler.SslOptions.LocalCertificateSelectionCallback = (sender, targetHost, localCertificates, remoteCertificate, acceptableIssuers) => CertificateHelper.GetEligibleClientCertificate(ClientCertificates); + _socketsHttpHandler.SslOptions.LocalCertificateSelectionCallback = (sender, targetHost, localCertificates, remoteCertificate, acceptableIssuers) => CertificateHelper.GetEligibleClientCertificate(ClientCertificates)!; break; case ClientCertificateOption.Automatic: ThrowForModifiedManagedSslOptionsIfStarted(); _clientCertificateOptions = value; - _socketsHttpHandler.SslOptions.LocalCertificateSelectionCallback = (sender, targetHost, localCertificates, remoteCertificate, acceptableIssuers) => CertificateHelper.GetEligibleClientCertificate(); + _socketsHttpHandler.SslOptions.LocalCertificateSelectionCallback = (sender, targetHost, localCertificates, remoteCertificate, acceptableIssuers) => CertificateHelper.GetEligibleClientCertificate()!; break; default: @@ -180,7 +180,7 @@ namespace System.Net.Http } } - public Func ServerCertificateCustomValidationCallback + public Func? ServerCertificateCustomValidationCallback { get => (_socketsHttpHandler.SslOptions.RemoteCertificateValidationCallback?.Target as ConnectHelper.CertificateCallbackMapper)?.FromHttpClientHandler; set @@ -212,7 +212,7 @@ namespace System.Net.Http } } - public IDictionary Properties => _socketsHttpHandler.Properties; + public IDictionary Properties => _socketsHttpHandler.Properties; protected internal override Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/HttpContent.cs b/src/libraries/System.Net.Http/src/System/Net/Http/HttpContent.cs index aeb543e..2ba2272 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/HttpContent.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/HttpContent.cs @@ -4,6 +4,7 @@ using System.Buffers; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.IO; using System.Net.Http.Headers; using System.Text; @@ -14,9 +15,9 @@ namespace System.Net.Http { public abstract class HttpContent : IDisposable { - private HttpContentHeaders _headers; - private MemoryStream _bufferedContent; - private object _contentReadStream; // Stream or Task + private HttpContentHeaders? _headers; + private MemoryStream? _bufferedContent; + private object? _contentReadStream; // Stream or Task private bool _disposed; private bool _canCalculateLength; @@ -169,7 +170,7 @@ namespace System.Net.Http { Debug.Assert(IsBuffered); - if (_bufferedContent.Length == 0) + if (_bufferedContent!.Length == 0) { return string.Empty; } @@ -190,10 +191,10 @@ namespace System.Net.Http // Content-Encoding is 'gzip' the user should set HttpClientHandler.AutomaticDecompression to get a // decoded response stream. - Encoding encoding = null; + Encoding? encoding = null; int bomLength = -1; - string charset = headers.ContentType?.CharSet; + string? charset = headers.ContentType?.CharSet; // If we do have encoding information in the 'Content-Type' header, use that information to convert // the content to a string. @@ -238,7 +239,7 @@ namespace System.Net.Http } // Drop the BOM when decoding the data. - return encoding.GetString(buffer.Array, buffer.Offset + bomLength, buffer.Count - bomLength); + return encoding.GetString(buffer.Array!, buffer.Offset + bomLength, buffer.Count - bomLength); } public Task ReadAsByteArrayAsync() => @@ -252,6 +253,7 @@ namespace System.Net.Http internal byte[] ReadBufferedContentAsByteArray() { + Debug.Assert(_bufferedContent != null); // The returned array is exposed out of the library, so use ToArray rather // than TryGetBuffer in order to make a copy. return _bufferedContent.ToArray(); @@ -271,7 +273,7 @@ namespace System.Net.Http if (_contentReadStream == null) // don't yet have a Stream { Task t = TryGetBuffer(out ArraySegment buffer) ? - Task.FromResult(new MemoryStream(buffer.Array, buffer.Offset, buffer.Count, writable: false)) : + Task.FromResult(new MemoryStream(buffer.Array!, buffer.Offset, buffer.Count, writable: false)) : CreateContentReadStreamAsync(cancellationToken); _contentReadStream = t; return t; @@ -289,7 +291,7 @@ namespace System.Net.Http } } - internal Stream TryReadAsStream() + internal Stream? TryReadAsStream() { CheckDisposed(); @@ -299,8 +301,8 @@ namespace System.Net.Http if (_contentReadStream == null) // don't yet have a Stream { - Stream s = TryGetBuffer(out ArraySegment buffer) ? - new MemoryStream(buffer.Array, buffer.Offset, buffer.Count, writable: false) : + Stream? s = TryGetBuffer(out ArraySegment buffer) ? + new MemoryStream(buffer.Array!, buffer.Offset, buffer.Count, writable: false) : TryCreateContentReadStream(); _contentReadStream = s; return s; @@ -317,9 +319,9 @@ namespace System.Net.Http } } - protected abstract Task SerializeToStreamAsync(Stream stream, TransportContext context); + protected abstract Task SerializeToStreamAsync(Stream stream, TransportContext? context); - protected virtual Task SerializeToStreamAsync(Stream stream, TransportContext context, CancellationToken cancellationToken) => + protected virtual Task SerializeToStreamAsync(Stream stream, TransportContext? context, CancellationToken cancellationToken) => SerializeToStreamAsync(stream, context); // TODO https://github.com/dotnet/runtime/issues/31316: Expose something to enable this publicly. For very specific @@ -336,10 +338,10 @@ namespace System.Net.Http public Task CopyToAsync(Stream stream, CancellationToken cancellationToken) => CopyToAsync(stream, null, cancellationToken); - public Task CopyToAsync(Stream stream, TransportContext context) => + public Task CopyToAsync(Stream stream, TransportContext? context) => CopyToAsync(stream, context, CancellationToken.None); - public Task CopyToAsync(Stream stream, TransportContext context, CancellationToken cancellationToken) + public Task CopyToAsync(Stream stream, TransportContext? context, CancellationToken cancellationToken) { CheckDisposed(); if (stream == null) @@ -411,12 +413,11 @@ namespace System.Net.Http return Task.CompletedTask; } - Exception error = null; - MemoryStream tempBuffer = CreateMemoryStream(maxBufferSize, out error); + MemoryStream? tempBuffer = CreateMemoryStream(maxBufferSize, out Exception? error); if (tempBuffer == null) { // We don't throw in LoadIntoBufferAsync(): return a faulted task. - return Task.FromException(error); + return Task.FromException(error!); } try @@ -463,7 +464,7 @@ namespace System.Net.Http // By default just buffer the content to a memory stream. Derived classes can override this behavior // if there is a better way to retrieve the content as stream (e.g. byte array/string use a more efficient // way, like wrapping a read-only MemoryStream around the bytes/string) - return WaitAndReturnAsync(LoadIntoBufferAsync(), this, s => (Stream)s._bufferedContent); + return WaitAndReturnAsync(LoadIntoBufferAsync(), this, s => (Stream)s._bufferedContent!); } protected virtual Task CreateContentReadStreamAsync(CancellationToken cancellationToken) @@ -476,7 +477,7 @@ namespace System.Net.Http // HttpContent-derived implementations that override CreateContentReadStreamAsync in a way that always // or frequently returns synchronously-completed tasks, we can avoid the task allocation by enabling // callers to try to get the Stream first synchronously. - internal virtual Stream TryCreateContentReadStream() => null; + internal virtual Stream? TryCreateContentReadStream() => null; // Derived types return true if they're able to compute the length. It's OK if derived types return false to // indicate that they're not able to compute the length. The transport channel needs to decide what to do in @@ -489,7 +490,7 @@ namespace System.Net.Http if (IsBuffered) { - return _bufferedContent.Length; + return _bufferedContent!.Length; } // If we already tried to calculate the length, but the derived class returned 'false', then don't try @@ -509,7 +510,7 @@ namespace System.Net.Http return null; } - private MemoryStream CreateMemoryStream(long maxBufferSize, out Exception error) + private MemoryStream? CreateMemoryStream(long maxBufferSize, out Exception? error) { error = null; @@ -545,7 +546,7 @@ namespace System.Net.Http if (_contentReadStream != null) { - Stream s = _contentReadStream as Stream ?? + Stream? s = _contentReadStream as Stream ?? (_contentReadStream is Task t && t.Status == TaskStatus.RanToCompletion ? t.Result : null); s?.Dispose(); _contentReadStream = null; @@ -553,7 +554,7 @@ namespace System.Net.Http if (IsBuffered) { - _bufferedContent.Dispose(); + _bufferedContent!.Dispose(); } } } @@ -612,7 +613,7 @@ namespace System.Net.Http private static int GetPreambleLength(ArraySegment buffer, Encoding encoding) { - byte[] data = buffer.Array; + byte[]? data = buffer.Array; int offset = buffer.Offset; int dataLength = buffer.Count; @@ -648,9 +649,9 @@ namespace System.Net.Http } } - private static bool TryDetectEncoding(ArraySegment buffer, out Encoding encoding, out int preambleLength) + private static bool TryDetectEncoding(ArraySegment buffer, [NotNullWhen(true)] out Encoding? encoding, out int preambleLength) { - byte[] data = buffer.Array; + byte[]? data = buffer.Array; int offset = buffer.Offset; int dataLength = buffer.Count; @@ -699,7 +700,7 @@ namespace System.Net.Http private static bool BufferHasPrefix(ArraySegment buffer, byte[] prefix) { - byte[] byteArray = buffer.Array; + byte[]? byteArray = buffer.Array; if (prefix == null || byteArray == null || prefix.Length > buffer.Count || prefix.Length == 0) return false; @@ -739,7 +740,7 @@ namespace System.Net.Http public byte[] GetSizedBuffer() { ArraySegment buffer; - return TryGetBuffer(out buffer) && buffer.Offset == 0 && buffer.Count == buffer.Array.Length ? + return TryGetBuffer(out buffer) && buffer.Offset == 0 && buffer.Count == buffer.Array!.Length ? buffer.Array : ToArray(); } @@ -768,7 +769,7 @@ namespace System.Net.Http return base.WriteAsync(buffer, cancellationToken); } - public override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback callback, object state) + public override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback? callback, object? state) { CheckSize(count); return base.BeginWrite(buffer, offset, count, callback, state); @@ -791,7 +792,7 @@ namespace System.Net.Http Position = length; long bytesToWrite = length - pos; - return destination.WriteAsync(buffer.Array, (int)(buffer.Offset + pos), (int)bytesToWrite, cancellationToken); + return destination.WriteAsync(buffer.Array!, (int)(buffer.Offset + pos), (int)bytesToWrite, cancellationToken); } return base.CopyToAsync(destination, bufferSize, cancellationToken); @@ -837,7 +838,7 @@ namespace System.Net.Http Debug.Assert(_buffer != null); ArrayPool.Shared.Return(_buffer); - _buffer = null; + _buffer = null!; base.Dispose(disposing); } @@ -869,7 +870,7 @@ namespace System.Net.Http // Extract the current buffer to be replaced. byte[] currentBuffer = _buffer; - _buffer = null; + _buffer = null!; // Determine the capacity to request for the new buffer. It should be // at least twice as long as the current one, if not more if the requested @@ -919,7 +920,7 @@ namespace System.Net.Http return default; } - public override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback asyncCallback, object asyncState) => + public override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback? asyncCallback, object? asyncState) => TaskToApm.Begin(WriteAsync(buffer, offset, count, CancellationToken.None), asyncCallback, asyncState); public override void EndWrite(IAsyncResult asyncResult) => diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/HttpMethod.cs b/src/libraries/System.Net.Http/src/System/Net/Http/HttpMethod.cs index 75460af..fef238f 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/HttpMethod.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/HttpMethod.cs @@ -11,7 +11,7 @@ namespace System.Net.Http public class HttpMethod : IEquatable { private readonly string _method; - private readonly byte[] _http3EncodedBytes; + private readonly byte[]? _http3EncodedBytes; private int _hashcode; private static readonly HttpMethod s_getMethod = new HttpMethod("GET", http3StaticTableIndex: H3StaticTable.MethodGet); @@ -90,7 +90,7 @@ namespace System.Net.Http get { return _method; } } - internal byte[] Http3EncodedBytes + internal byte[]? Http3EncodedBytes { get { return _http3EncodedBytes; } } @@ -119,9 +119,9 @@ namespace System.Net.Http #region IEquatable Members - public bool Equals(HttpMethod other) + public bool Equals(HttpMethod? other) { - if ((object)other == null) + if ((object?)other == null) { return false; } @@ -138,7 +138,7 @@ namespace System.Net.Http #endregion - public override bool Equals(object obj) + public override bool Equals(object? obj) { return Equals(obj as HttpMethod); } @@ -158,14 +158,14 @@ namespace System.Net.Http return _method; } - public static bool operator ==(HttpMethod left, HttpMethod right) + public static bool operator ==(HttpMethod? left, HttpMethod? right) { - return (object)left == null || (object)right == null ? + return (object?)left == null || (object?)right == null ? ReferenceEquals(left, right) : left.Equals(right); } - public static bool operator !=(HttpMethod left, HttpMethod right) + public static bool operator !=(HttpMethod? left, HttpMethod? right) { return !(left == right); } @@ -177,7 +177,7 @@ namespace System.Net.Http internal static HttpMethod Normalize(HttpMethod method) { Debug.Assert(method != null); - return s_knownMethods.TryGetValue(method, out HttpMethod normalized) ? + return s_knownMethods.TryGetValue(method, out HttpMethod? normalized) ? normalized : method; } diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/HttpRequestException.cs b/src/libraries/System.Net.Http/src/System/Net/Http/HttpRequestException.cs index da0bdf6..cba9fe2 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/HttpRequestException.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/HttpRequestException.cs @@ -15,11 +15,11 @@ namespace System.Net.Http : this(null, null) { } - public HttpRequestException(string message) + public HttpRequestException(string? message) : this(message, null) { } - public HttpRequestException(string message, Exception inner) + public HttpRequestException(string? message, Exception? inner) : base(message, inner) { if (inner != null) @@ -34,7 +34,7 @@ namespace System.Net.Http /// A message that describes the current exception. /// The inner exception. /// The HTTP status code. - public HttpRequestException(string message, Exception inner, HttpStatusCode? statusCode) + public HttpRequestException(string? message, Exception? inner, HttpStatusCode? statusCode) : this(message, inner) { StatusCode = statusCode; @@ -50,7 +50,7 @@ namespace System.Net.Http // This constructor is used internally to indicate that a request was not successfully sent due to an IOException, // and the exception occurred early enough so that the request may be retried on another connection. - internal HttpRequestException(string message, Exception inner, RequestRetryType allowRetry) + internal HttpRequestException(string? message, Exception? inner, RequestRetryType allowRetry) : this(message, inner) { AllowRetry = allowRetry; diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/HttpRequestMessage.cs b/src/libraries/System.Net.Http/src/System/Net/Http/HttpRequestMessage.cs index ed2293a..a76798f 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/HttpRequestMessage.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/HttpRequestMessage.cs @@ -19,13 +19,13 @@ namespace System.Net.Http // The message shouldn't be sent again if this field is equal to MessageAlreadySent. private int _sendStatus = MessageNotYetSent; - private HttpMethod _method; - private Uri _requestUri; - private HttpRequestHeaders _headers; - private Version _version; - private HttpContent _content; + private HttpMethod _method = null!; + private Uri? _requestUri; + private HttpRequestHeaders? _headers; + private Version _version = null!; + private HttpContent? _content; private bool _disposed; - private IDictionary _properties; + private IDictionary? _properties; public Version Version { @@ -42,7 +42,7 @@ namespace System.Net.Http } } - public HttpContent Content + public HttpContent? Content { get { return _content; } set @@ -81,7 +81,7 @@ namespace System.Net.Http } } - public Uri RequestUri + public Uri? RequestUri { get { return _requestUri; } set @@ -112,31 +112,31 @@ namespace System.Net.Http internal bool HasHeaders => _headers != null; - public IDictionary Properties + public IDictionary Properties { get { if (_properties == null) { - _properties = new Dictionary(); + _properties = new Dictionary(); } return _properties; } } public HttpRequestMessage() - : this(HttpMethod.Get, (Uri)null) + : this(HttpMethod.Get, (Uri?)null) { } - public HttpRequestMessage(HttpMethod method, Uri requestUri) + public HttpRequestMessage(HttpMethod method, Uri? requestUri) { if (NetEventSource.IsEnabled) NetEventSource.Enter(this, method, requestUri); InitializeValues(method, requestUri); if (NetEventSource.IsEnabled) NetEventSource.Exit(this); } - public HttpRequestMessage(HttpMethod method, string requestUri) + public HttpRequestMessage(HttpMethod method, string? requestUri) { if (NetEventSource.IsEnabled) NetEventSource.Enter(this, method, requestUri); @@ -177,7 +177,7 @@ namespace System.Net.Http return sb.ToString(); } - private void InitializeValues(HttpMethod method, Uri requestUri) + private void InitializeValues(HttpMethod method, Uri? requestUri) { if (method == null) { diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/HttpResponseMessage.cs b/src/libraries/System.Net.Http/src/System/Net/Http/HttpResponseMessage.cs index d52f14a..dbe85b5 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/HttpResponseMessage.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/HttpResponseMessage.cs @@ -12,12 +12,12 @@ namespace System.Net.Http private const HttpStatusCode defaultStatusCode = HttpStatusCode.OK; private HttpStatusCode _statusCode; - private HttpResponseHeaders _headers; - private HttpResponseHeaders _trailingHeaders; - private string _reasonPhrase; - private HttpRequestMessage _requestMessage; + private HttpResponseHeaders? _headers; + private HttpResponseHeaders? _trailingHeaders; + private string? _reasonPhrase; + private HttpRequestMessage? _requestMessage; private Version _version; - private HttpContent _content; + private HttpContent? _content; private bool _disposed; public Version Version @@ -39,7 +39,7 @@ namespace System.Net.Http internal void SetVersionWithoutValidation(Version value) => _version = value; - public HttpContent Content + public HttpContent? Content { get { return _content; } set @@ -79,7 +79,7 @@ namespace System.Net.Http internal void SetStatusCodeWithoutValidation(HttpStatusCode value) => _statusCode = value; - public string ReasonPhrase + public string? ReasonPhrase { get { @@ -129,7 +129,7 @@ namespace System.Net.Http } } - public HttpRequestMessage RequestMessage + public HttpRequestMessage? RequestMessage { get { return _requestMessage; } set diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/HttpRuleParser.cs b/src/libraries/System.Net.Http/src/System/Net/Http/HttpRuleParser.cs index b45d2db..c8e223a 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/HttpRuleParser.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/HttpRuleParser.cs @@ -246,7 +246,7 @@ namespace System.Net.Http return current - startIndex; } - internal static int GetHostLength(string input, int startIndex, bool allowToken, out string host) + internal static int GetHostLength(string input, int startIndex, bool allowToken, out string? host) { Debug.Assert(input != null); Debug.Assert(startIndex >= 0); @@ -425,8 +425,7 @@ namespace System.Net.Http private static bool IsValidHostName(string host) { // Also add user info (u@) to make sure 'host' doesn't include user info. - Uri hostUri; - return Uri.TryCreate("http://u@" + host + "/", UriKind.Absolute, out hostUri); + return Uri.TryCreate("http://u@" + host + "/", UriKind.Absolute, out Uri? hostUri); } } } diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/HttpUtilities.cs b/src/libraries/System.Net.Http/src/System/Net/Http/HttpUtilities.cs index bf8a98b..400ed5d 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/HttpUtilities.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/HttpUtilities.cs @@ -41,7 +41,7 @@ namespace System.Net.Http // Since we're not doing any CPU and/or I/O intensive operations, continue on the same thread. // This results in better performance since the continuation task doesn't get scheduled by the // scheduler and there are no context switches required. - internal static Task ContinueWithStandard(this Task task, object state, Action, object> continuation) + internal static Task ContinueWithStandard(this Task task, object state, Action, object?> continuation) { return task.ContinueWith(continuation, state, CancellationToken.None, TaskContinuationOptions.ExecuteSynchronously, TaskScheduler.Default); diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/MessageProcessingHandler.cs b/src/libraries/System.Net.Http/src/System/Net/Http/MessageProcessingHandler.cs index 55db3c6..78f9cc0 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/MessageProcessingHandler.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/MessageProcessingHandler.cs @@ -51,13 +51,13 @@ namespace System.Net.Http // processing method. ProcessResponse() is only called if the task wasn't canceled before. sendAsyncTask.ContinueWithStandard(tcs, (task, state) => { - var sendState = (SendState)state; + var sendState = (SendState)state!; MessageProcessingHandler self = sendState._handler; CancellationToken token = sendState._token; if (task.IsFaulted) { - sendState.TrySetException(task.Exception.GetBaseException()); + sendState.TrySetException(task.Exception!.GetBaseException()); return; } diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/MultipartContent.cs b/src/libraries/System.Net.Http/src/System/Net/Http/MultipartContent.cs index 0e25934..20aacaa 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/MultipartContent.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/MultipartContent.cs @@ -166,16 +166,16 @@ namespace System.Net.Http // write "--" + boundary + "--" // Can't be canceled directly by the user. If the overall request is canceled // then the stream will be closed an exception thrown. - protected override Task SerializeToStreamAsync(Stream stream, TransportContext context) => + protected override Task SerializeToStreamAsync(Stream stream, TransportContext? context) => SerializeToStreamAsyncCore(stream, context, default); - protected override Task SerializeToStreamAsync(Stream stream, TransportContext context, CancellationToken cancellationToken) => + protected override Task SerializeToStreamAsync(Stream stream, TransportContext? context, CancellationToken cancellationToken) => // Only skip the original protected virtual SerializeToStreamAsync if this // isn't a derived type that may have overridden the behavior. GetType() == typeof(MultipartContent) ? SerializeToStreamAsyncCore(stream, context, cancellationToken) : base.SerializeToStreamAsync(stream, context, cancellationToken); - private protected async Task SerializeToStreamAsyncCore(Stream stream, TransportContext context, CancellationToken cancellationToken) + private protected async Task SerializeToStreamAsyncCore(Stream stream, TransportContext? context, CancellationToken cancellationToken) { Debug.Assert(stream != null); try @@ -375,7 +375,7 @@ namespace System.Net.Http private readonly long _length; private int _next; - private Stream _current; + private Stream? _current; private long _position; internal ContentReadStream(Stream[] streams) @@ -481,7 +481,7 @@ namespace System.Net.Http public override ValueTask ReadAsync(Memory buffer, CancellationToken cancellationToken = default) => ReadAsyncPrivate(buffer, cancellationToken); - public override IAsyncResult BeginRead(byte[] array, int offset, int count, AsyncCallback asyncCallback, object asyncState) => + public override IAsyncResult BeginRead(byte[] array, int offset, int count, AsyncCallback? asyncCallback, object? asyncState) => TaskToApm.Begin(ReadAsync(array, offset, count, CancellationToken.None), asyncCallback, asyncState); public override int EndRead(IAsyncResult asyncResult) => diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/MultipartFormDataContent.cs b/src/libraries/System.Net.Http/src/System/Net/Http/MultipartFormDataContent.cs index dd88505..8b579c7 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/MultipartFormDataContent.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/MultipartFormDataContent.cs @@ -71,7 +71,7 @@ namespace System.Net.Http AddInternal(content, name, fileName); } - private void AddInternal(HttpContent content, string name, string fileName) + private void AddInternal(HttpContent content, string name, string? fileName) { if (content.Headers.ContentDisposition == null) { @@ -85,7 +85,7 @@ namespace System.Net.Http base.Add(content); } - protected override Task SerializeToStreamAsync(Stream stream, TransportContext context, CancellationToken cancellationToken) => + protected override Task SerializeToStreamAsync(Stream stream, TransportContext? context, CancellationToken cancellationToken) => // Only skip the original protected virtual SerializeToStreamAsync if this // isn't a derived type that may have overridden the behavior. GetType() == typeof(MultipartFormDataContent) ? SerializeToStreamAsyncCore(stream, context, cancellationToken) : diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/NetEventSource.Http.cs b/src/libraries/System.Net.Http/src/System/Net/Http/NetEventSource.Http.cs index 28dc086..0d9745d 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/NetEventSource.Http.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/NetEventSource.Http.cs @@ -21,14 +21,14 @@ namespace System.Net private const int HandlerErrorId = AuthenticationErrorId + 1; [NonEvent] - public static void UriBaseAddress(object obj, Uri baseAddress) + public static void UriBaseAddress(object obj, Uri? baseAddress) { Debug.Assert(IsEnabled); Log.UriBaseAddress(baseAddress?.ToString(), IdOf(obj), GetHashCode(obj)); } [Event(UriBaseAddressId, Keywords = Keywords.Debug, Level = EventLevel.Informational)] - private unsafe void UriBaseAddress(string uriBaseAddress, string objName, int objHash) => + private unsafe void UriBaseAddress(string? uriBaseAddress, string objName, int objHash) => WriteEvent(UriBaseAddressId, uriBaseAddress, objName, objHash); [NonEvent] @@ -50,7 +50,7 @@ namespace System.Net } [Event(ClientSendCompletedId, Keywords = Keywords.Debug, Level = EventLevel.Verbose)] - private void ClientSendCompleted(string responseString, int httpRequestMessageHash, int httpResponseMessageHash, int httpClientHash) => + private void ClientSendCompleted(string? responseString, int httpRequestMessageHash, int httpResponseMessageHash, int httpClientHash) => WriteEvent(ClientSendCompletedId, responseString, httpRequestMessageHash, httpResponseMessageHash, httpClientHash); [Event(HeadersInvalidValueId, Keywords = Keywords.Debug, Level = EventLevel.Error)] @@ -58,11 +58,11 @@ namespace System.Net WriteEvent(HeadersInvalidValueId, name, rawValue); [Event(HandlerMessageId, Keywords = Keywords.Debug, Level = EventLevel.Verbose)] - public void HandlerMessage(int poolId, int workerId, int requestId, string memberName, string message) => + public void HandlerMessage(int poolId, int workerId, int requestId, string? memberName, string? message) => WriteEvent(HandlerMessageId, poolId, workerId, requestId, memberName, message); [Event(HandlerErrorId, Keywords = Keywords.Debug, Level = EventLevel.Error)] - public void HandlerMessageError(int poolId, int workerId, int requestId, string memberName, string message) => + public void HandlerMessageError(int poolId, int workerId, int requestId, string? memberName, string message) => WriteEvent(HandlerErrorId, poolId, workerId, requestId, memberName, message); [NonEvent] @@ -73,22 +73,22 @@ namespace System.Net } [Event(AuthenticationInfoId, Keywords = Keywords.Debug, Level = EventLevel.Verbose)] - public void AuthenticationInfo(string uri, string message) => + public void AuthenticationInfo(string? uri, string message) => WriteEvent(AuthenticationInfoId, uri, message); [NonEvent] - public static void AuthenticationError(Uri uri, string message) + public static void AuthenticationError(Uri? uri, string message) { Debug.Assert(IsEnabled); Log.AuthenticationError(uri?.ToString(), message); } [Event(AuthenticationErrorId, Keywords = Keywords.Debug, Level = EventLevel.Error)] - public void AuthenticationError(string uri, string message) => + public void AuthenticationError(string? uri, string message) => WriteEvent(AuthenticationErrorId, uri, message); [NonEvent] - private unsafe void WriteEvent(int eventId, int arg1, int arg2, int arg3, string arg4, string arg5) + private unsafe void WriteEvent(int eventId, int arg1, int arg2, int arg3, string? arg4, string? arg5) { if (IsEnabled()) { diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/ReadOnlyMemoryContent.cs b/src/libraries/System.Net.Http/src/System/Net/Http/ReadOnlyMemoryContent.cs index e73e0d0..b2140a9 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/ReadOnlyMemoryContent.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/ReadOnlyMemoryContent.cs @@ -20,14 +20,14 @@ namespace System.Net.Http { // If we have an array, allow HttpClient to take optimized paths by just // giving it the array content to use as its already buffered data. - SetBuffer(array.Array, array.Offset, array.Count); + SetBuffer(array.Array!, array.Offset, array.Count); } } - protected override Task SerializeToStreamAsync(Stream stream, TransportContext context) => + protected override Task SerializeToStreamAsync(Stream stream, TransportContext? context) => stream.WriteAsync(_content).AsTask(); - protected override Task SerializeToStreamAsync(Stream stream, TransportContext context, CancellationToken cancellationToken) => + protected override Task SerializeToStreamAsync(Stream stream, TransportContext? context, CancellationToken cancellationToken) => stream.WriteAsync(_content, cancellationToken).AsTask(); protected internal override bool TryComputeLength(out long length) diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/AuthenticationHelper.Digest.cs b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/AuthenticationHelper.Digest.cs index 773537d..7f67877 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/AuthenticationHelper.Digest.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/AuthenticationHelper.Digest.cs @@ -40,17 +40,17 @@ namespace System.Net.Http // 48='0', 65='A', 97='a' private static readonly int[] s_alphaNumChooser = new int[] { 48, 65, 97 }; - public static async Task GetDigestTokenForCredential(NetworkCredential credential, HttpRequestMessage request, DigestResponse digestResponse) + public static async Task GetDigestTokenForCredential(NetworkCredential credential, HttpRequestMessage request, DigestResponse digestResponse) { StringBuilder sb = StringBuilderCache.Acquire(); // It is mandatory for servers to implement sha-256 per RFC 7616 // Keep MD5 for backward compatibility. - string algorithm; + string? algorithm; bool isAlgorithmSpecified = digestResponse.Parameters.TryGetValue(Algorithm, out algorithm); if (isAlgorithmSpecified) { - if (!algorithm.Equals(Sha256, StringComparison.OrdinalIgnoreCase) && + if (!algorithm!.Equals(Sha256, StringComparison.OrdinalIgnoreCase) && !algorithm.Equals(Md5, StringComparison.OrdinalIgnoreCase) && !algorithm.Equals(Sha256Sess, StringComparison.OrdinalIgnoreCase) && !algorithm.Equals(MD5Sess, StringComparison.OrdinalIgnoreCase)) @@ -65,7 +65,7 @@ namespace System.Net.Http } // Check if nonce is there in challenge - string nonce; + string? nonce; if (!digestResponse.Parameters.TryGetValue(Nonce, out nonce)) { if (NetEventSource.IsEnabled) NetEventSource.Error(digestResponse, "Nonce missing"); @@ -73,10 +73,10 @@ namespace System.Net.Http } // opaque token may or may not exist - string opaque; + string? opaque; digestResponse.Parameters.TryGetValue(Opaque, out opaque); - string realm; + string? realm; if (!digestResponse.Parameters.TryGetValue(Realm, out realm)) { if (NetEventSource.IsEnabled) NetEventSource.Error(digestResponse, "Realm missing"); @@ -84,7 +84,7 @@ namespace System.Net.Http } // Add username - string userhash; + string? userhash; if (digestResponse.Parameters.TryGetValue(UserHash, out userhash) && userhash == "true") { sb.AppendKeyValue(Username, ComputeHash(credential.UserName + ":" + realm, algorithm)); @@ -110,6 +110,7 @@ namespace System.Net.Http // Add nonce sb.AppendKeyValue(Nonce, nonce); + Debug.Assert(request.RequestUri != null); // Add uri sb.AppendKeyValue(Uri, request.RequestUri.PathAndQuery); @@ -204,8 +205,7 @@ namespace System.Net.Http public static bool IsServerNonceStale(DigestResponse digestResponse) { - string stale = null; - return digestResponse.Parameters.TryGetValue(Stale, out stale) && stale == "true"; + return digestResponse.Parameters.TryGetValue(Stale, out string? stale) && stale == "true"; } private static string GetRandomAlphaNumericString() @@ -256,7 +256,7 @@ namespace System.Net.Http internal readonly Dictionary Parameters = new Dictionary(StringComparer.OrdinalIgnoreCase); internal const string NonceCount = "00000001"; - internal DigestResponse(string challenge) + internal DigestResponse(string? challenge) { if (!string.IsNullOrEmpty(challenge)) Parse(challenge); @@ -274,7 +274,7 @@ namespace System.Net.Http key.Equals(Opaque, StringComparison.OrdinalIgnoreCase) || key.Equals(Qop, StringComparison.OrdinalIgnoreCase); } - private string GetNextKey(string data, int currentIndex, out int parsedIndex) + private string? GetNextKey(string data, int currentIndex, out int parsedIndex) { // Skip leading space or tab. while (currentIndex < data.Length && CharIsSpaceOrTab(data[currentIndex])) @@ -329,7 +329,7 @@ namespace System.Net.Http return data.Substring(start, length); } - private string GetNextValue(string data, int currentIndex, bool expectQuotes, out int parsedIndex) + private string? GetNextValue(string data, int currentIndex, bool expectQuotes, out int parsedIndex) { Debug.Assert(currentIndex < data.Length && !CharIsSpaceOrTab(data[currentIndex])); @@ -406,13 +406,13 @@ namespace System.Net.Http while (parsedIndex < challenge.Length) { // Get the key. - string key = GetNextKey(challenge, parsedIndex, out parsedIndex); + string? key = GetNextKey(challenge, parsedIndex, out parsedIndex); // Ensure key is not empty and parsedIndex is still in range. if (string.IsNullOrEmpty(key) || parsedIndex >= challenge.Length) break; // Get the value. - string value = GetNextValue(challenge, parsedIndex, MustValueBeQuoted(key), out parsedIndex); + string? value = GetNextValue(challenge, parsedIndex, MustValueBeQuoted(key), out parsedIndex); // Ensure value is valid. if (string.IsNullOrEmpty(value) && (value == null || !key.Equals(Opaque, StringComparison.OrdinalIgnoreCase))) diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/AuthenticationHelper.NtAuth.cs b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/AuthenticationHelper.NtAuth.cs index b1d6e8b..68f2c4a 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/AuthenticationHelper.NtAuth.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/AuthenticationHelper.NtAuth.cs @@ -23,7 +23,7 @@ namespace System.Net.Http private static bool ProxySupportsConnectionAuth(HttpResponseMessage response) { - if (!response.Headers.TryGetValues(KnownHeaders.ProxySupport.Descriptor, out IEnumerable values)) + if (!response.Headers.TryGetValues(KnownHeaders.ProxySupport.Descriptor, out IEnumerable? values)) { return false; } @@ -64,14 +64,16 @@ namespace System.Net.Http if (response.Headers.ConnectionClose.GetValueOrDefault()) { // Server is closing the connection and asking us to authenticate on a new connection. +#pragma warning disable CS8600 // expression returns null connection on error, was not able to use '!' for the expression (connection, response) = await connectionPool.CreateHttp11ConnectionAsync(request, cancellationToken).ConfigureAwait(false); +#pragma warning restore CS8600 if (response != null) { return response; } connectionPool.IncrementConnectionCount(); - connection.Acquire(); + connection!.Acquire(); isNewConnection = true; needDrain = false; } @@ -119,14 +121,14 @@ namespace System.Net.Http NetEventSource.Info(connection, $"Authentication: {challenge.AuthenticationType}, SPN: {spn}"); } - ChannelBinding channelBinding = connection.TransportContext?.GetChannelBinding(ChannelBindingKind.Endpoint); + ChannelBinding? channelBinding = connection.TransportContext?.GetChannelBinding(ChannelBindingKind.Endpoint); NTAuthentication authContext = new NTAuthentication(isServer: false, challenge.SchemeName, challenge.Credential, spn, ContextFlagsPal.Connection, channelBinding); - string challengeData = challenge.ChallengeData; + string? challengeData = challenge.ChallengeData; try { while (true) { - string challengeResponse = authContext.GetOutgoingBlob(challengeData); + string? challengeResponse = authContext.GetOutgoingBlob(challengeData); if (challengeResponse == null) { // Response indicated denial even after login, so stop processing and return current response. @@ -135,7 +137,7 @@ namespace System.Net.Http if (needDrain) { - await connection.DrainResponseAsync(response, cancellationToken).ConfigureAwait(false); + await connection.DrainResponseAsync(response!, cancellationToken).ConfigureAwait(false); } SetRequestAuthenticationHeaderValue(request, new AuthenticationHeaderValue(challenge.SchemeName, challengeResponse), isProxyAuth); @@ -158,13 +160,13 @@ namespace System.Net.Http { if (isNewConnection) { - connection.Release(); + connection!.Release(); } } } } - return response; + return response!; } public static Task SendWithNtProxyAuthAsync(HttpRequestMessage request, Uri proxyUri, ICredentials proxyCredentials, HttpConnection connection, HttpConnectionPool connectionPool, CancellationToken cancellationToken) @@ -174,6 +176,7 @@ namespace System.Net.Http public static Task SendWithNtConnectionAuthAsync(HttpRequestMessage request, ICredentials credentials, HttpConnection connection, HttpConnectionPool connectionPool, CancellationToken cancellationToken) { + Debug.Assert(request.RequestUri != null); return SendWithNtAuthAsync(request, request.RequestUri, credentials, isProxyAuth: false, connection, connectionPool, cancellationToken); } } diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/AuthenticationHelper.cs b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/AuthenticationHelper.cs index b6855e3..4f99031 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/AuthenticationHelper.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/AuthenticationHelper.cs @@ -3,6 +3,7 @@ // See the LICENSE file in the project root for more information. using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Net.Http.Headers; using System.Text; using System.Threading; @@ -30,9 +31,9 @@ namespace System.Net.Http public AuthenticationType AuthenticationType { get; } public string SchemeName { get; } public NetworkCredential Credential { get; } - public string ChallengeData { get; } + public string? ChallengeData { get; } - public AuthenticationChallenge(AuthenticationType authenticationType, string schemeName, NetworkCredential credential, string challenge) + public AuthenticationChallenge(AuthenticationType authenticationType, string schemeName, NetworkCredential credential, string? challenge) { AuthenticationType = authenticationType; SchemeName = schemeName; @@ -41,7 +42,7 @@ namespace System.Net.Http } } - private static bool TryGetChallengeDataForScheme(string scheme, HttpHeaderValueCollection authenticationHeaderValues, out string challengeData) + private static bool TryGetChallengeDataForScheme(string scheme, HttpHeaderValueCollection authenticationHeaderValues, out string? challengeData) { foreach (AuthenticationHeaderValue ahv in authenticationHeaderValues) { @@ -82,12 +83,12 @@ namespace System.Net.Http { challenge = default; - if (!TryGetChallengeDataForScheme(scheme, authenticationHeaderValues, out string challengeData)) + if (!TryGetChallengeDataForScheme(scheme, authenticationHeaderValues, out string? challengeData)) { return false; } - NetworkCredential credential = credentials.GetCredential(uri, scheme); + NetworkCredential? credential = credentials.GetCredential(uri, scheme); if (credential == null) { // We have no credential for this auth type, so we can't respond to the challenge. @@ -128,7 +129,7 @@ namespace System.Net.Http TryGetValidAuthenticationChallengeForScheme(BasicScheme, AuthenticationType.Basic, authUri, credentials, authenticationHeaderValues, out challenge); } - private static bool TryGetRepeatedChallenge(HttpResponseMessage response, string scheme, bool isProxyAuth, out string challengeData) + private static bool TryGetRepeatedChallenge(HttpResponseMessage response, string scheme, bool isProxyAuth, out string? challengeData) { challengeData = null; @@ -186,7 +187,7 @@ namespace System.Net.Http private static async ValueTask TrySetDigestAuthToken(HttpRequestMessage request, NetworkCredential credential, DigestResponse digestResponse, bool isProxyAuth) { - string parameter = await GetDigestTokenForCredential(credential, request, digestResponse).ConfigureAwait(false); + string? parameter = await GetDigestTokenForCredential(credential, request, digestResponse).ConfigureAwait(false); // Any errors in obtaining parameter return false and we don't proceed with auth if (string.IsNullOrEmpty(parameter)) @@ -219,7 +220,7 @@ namespace System.Net.Http if (preAuthenticate) { Debug.Assert(pool.PreAuthCredentials != null); - NetworkCredential credential; + NetworkCredential? credential; lock (pool.PreAuthCredentials) { // Just look for basic credentials. If in the future we support preauth @@ -251,7 +252,7 @@ namespace System.Net.Http response = await InnerSendAsync(request, isProxyAuth, doRequestAuth, pool, cancellationToken).ConfigureAwait(false); // Retry in case of nonce timeout in server. - if (TryGetRepeatedChallenge(response, challenge.SchemeName, isProxyAuth, out string challengeData)) + if (TryGetRepeatedChallenge(response, challenge.SchemeName, isProxyAuth, out string? challengeData)) { digestResponse = new DigestResponse(challengeData); if (IsServerNonceStale(digestResponse) && @@ -291,7 +292,7 @@ namespace System.Net.Http break; default: - lock (pool.PreAuthCredentials) + lock (pool.PreAuthCredentials!) { try { @@ -332,6 +333,7 @@ namespace System.Net.Http public static Task SendWithRequestAuthAsync(HttpRequestMessage request, ICredentials credentials, bool preAuthenticate, HttpConnectionPool pool, CancellationToken cancellationToken) { + Debug.Assert(request.RequestUri != null); return SendWithAuthAsync(request, request.RequestUri, credentials, preAuthenticate, isProxyAuth: false, doRequestAuth: true, pool, cancellationToken); } } diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/CancellationHelper.cs b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/CancellationHelper.cs index ad5a79a..d2c9572 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/CancellationHelper.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/CancellationHelper.cs @@ -24,13 +24,13 @@ namespace System.Net.Http /// The inner exception to wrap. May be null. /// The that triggered the cancellation. /// The cancellation exception. - internal static Exception CreateOperationCanceledException(Exception innerException, CancellationToken cancellationToken) => + internal static Exception CreateOperationCanceledException(Exception? innerException, CancellationToken cancellationToken) => new TaskCanceledException(s_cancellationMessage, innerException, cancellationToken); // TCE for compatibility with other handlers that use TaskCompletionSource.TrySetCanceled() /// Throws a cancellation exception. /// The inner exception to wrap. May be null. /// The that triggered the cancellation. - private static void ThrowOperationCanceledException(Exception innerException, CancellationToken cancellationToken) => + private static void ThrowOperationCanceledException(Exception? innerException, CancellationToken cancellationToken) => throw CreateOperationCanceledException(innerException, cancellationToken); /// Throws a cancellation exception if cancellation has been requested via . diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/ChunkedEncodingReadStream.cs b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/ChunkedEncodingReadStream.cs index 32cba80..72c5858 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/ChunkedEncodingReadStream.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/ChunkedEncodingReadStream.cs @@ -202,7 +202,7 @@ namespace System.Net.Http private async Task CopyToAsyncCore(Stream destination, CancellationToken cancellationToken) { - CancellationTokenRegistration ctr = _connection.RegisterCancellation(cancellationToken); + CancellationTokenRegistration ctr = _connection!.RegisterCancellation(cancellationToken); try { while (true) @@ -257,7 +257,7 @@ namespace System.Net.Http private ReadOnlyMemory ReadChunkFromConnectionBuffer(int maxBytesToRead, CancellationTokenRegistration cancellationRegistration) { - Debug.Assert(maxBytesToRead > 0); + Debug.Assert(maxBytesToRead > 0 && _connection != null); try { @@ -393,7 +393,7 @@ namespace System.Net.Http catch (Exception) { // Ensure we don't try to read from the connection again (in particular, for draining) - _connection.Dispose(); + _connection!.Dispose(); _connection = null; throw; } @@ -432,7 +432,7 @@ namespace System.Net.Http { Debug.Assert(_connection != null); - CancellationTokenSource cts = null; + CancellationTokenSource? cts = null; CancellationTokenRegistration ctr = default; try { @@ -467,7 +467,7 @@ namespace System.Net.Http if (drainTime != Timeout.InfiniteTimeSpan) { cts = new CancellationTokenSource((int)drainTime.TotalMilliseconds); - ctr = cts.Token.Register(s => ((HttpConnection)s).Dispose(), _connection); + ctr = cts.Token.Register(s => ((HttpConnection)s!).Dispose(), _connection); } } diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/ConnectHelper.cs b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/ConnectHelper.cs index a364b2e..7f88b00 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/ConnectHelper.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/ConnectHelper.cs @@ -23,14 +23,14 @@ namespace System.Net.Http /// internal sealed class CertificateCallbackMapper { - public readonly Func FromHttpClientHandler; + public readonly Func FromHttpClientHandler; public readonly RemoteCertificateValidationCallback ForSocketsHttpHandler; - public CertificateCallbackMapper(Func fromHttpClientHandler) + public CertificateCallbackMapper(Func fromHttpClientHandler) { FromHttpClientHandler = fromHttpClientHandler; - ForSocketsHttpHandler = (object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors) => - FromHttpClientHandler(sender as HttpRequestMessage, certificate as X509Certificate2, chain, sslPolicyErrors); + ForSocketsHttpHandler = (object sender, X509Certificate? certificate, X509Chain? chain, SslPolicyErrors sslPolicyErrors) => + FromHttpClientHandler((HttpRequestMessage)sender, certificate as X509Certificate2, chain, sslPolicyErrors); } } @@ -51,7 +51,7 @@ namespace System.Net.Http if (Socket.ConnectAsync(SocketType.Stream, ProtocolType.Tcp, saea)) { // Connect completing asynchronously. Enable it to be canceled and wait for it. - using (cancellationToken.UnsafeRegister(s => Socket.CancelConnectAsync((SocketAsyncEventArgs)s), saea)) + using (cancellationToken.UnsafeRegister(s => Socket.CancelConnectAsync((SocketAsyncEventArgs)s!), saea)) { await saea.Builder.Task.ConfigureAwait(false); } @@ -129,13 +129,13 @@ namespace System.Net.Http { // If there's a cert validation callback, and if it came from HttpClientHandler, // wrap the original delegate in order to change the sender to be the request message (expected by HttpClientHandler's delegate). - RemoteCertificateValidationCallback callback = sslOptions.RemoteCertificateValidationCallback; + RemoteCertificateValidationCallback? callback = sslOptions.RemoteCertificateValidationCallback; if (callback != null && callback.Target is CertificateCallbackMapper mapper) { sslOptions = sslOptions.ShallowClone(); // Clone as we're about to mutate it and don't want to affect the cached copy - Func localFromHttpClientHandler = mapper.FromHttpClientHandler; + Func localFromHttpClientHandler = mapper.FromHttpClientHandler; HttpRequestMessage localRequest = request; - sslOptions.RemoteCertificateValidationCallback = (object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors) => + sslOptions.RemoteCertificateValidationCallback = (object sender, X509Certificate? certificate, X509Chain? chain, SslPolicyErrors sslPolicyErrors) => localFromHttpClientHandler(localRequest, certificate as X509Certificate2, chain, sslPolicyErrors); } @@ -178,10 +178,10 @@ namespace System.Net.Http return sslStream; } - public static async ValueTask ConnectQuicAsync(string host, int port, SslClientAuthenticationOptions clientAuthenticationOptions, CancellationToken cancellationToken) + public static async ValueTask ConnectQuicAsync(string host, int port, SslClientAuthenticationOptions? clientAuthenticationOptions, CancellationToken cancellationToken) { IPAddress[] addresses = await Dns.GetHostAddressesAsync(host).ConfigureAwait(false); - Exception lastException = null; + Exception? lastException = null; foreach (IPAddress address in addresses) { diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/ConnectionCloseReadStream.cs b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/ConnectionCloseReadStream.cs index 262ab20..99f9c23 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/ConnectionCloseReadStream.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/ConnectionCloseReadStream.cs @@ -18,7 +18,7 @@ namespace System.Net.Http public override int Read(Span buffer) { - HttpConnection connection = _connection; + HttpConnection? connection = _connection; if (connection == null || buffer.Length == 0) { // Response body fully consumed or the caller didn't ask for any data @@ -40,7 +40,7 @@ namespace System.Net.Http { CancellationHelper.ThrowIfCancellationRequested(cancellationToken); - HttpConnection connection = _connection; + HttpConnection? connection = _connection; if (connection == null || buffer.Length == 0) { // Response body fully consumed or the caller didn't ask for any data @@ -97,7 +97,7 @@ namespace System.Net.Http return Task.FromCanceled(cancellationToken); } - HttpConnection connection = _connection; + HttpConnection? connection = _connection; if (connection == null) { // null if response body fully consumed diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/ContentLengthReadStream.cs b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/ContentLengthReadStream.cs index 7aba584..cae7197 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/ContentLengthReadStream.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/ContentLengthReadStream.cs @@ -144,6 +144,7 @@ namespace System.Net.Http private async Task CompleteCopyToAsync(Task copyTask, CancellationToken cancellationToken) { + Debug.Assert(_connection != null); CancellationTokenRegistration ctr = _connection.RegisterCancellation(cancellationToken); try { @@ -164,7 +165,7 @@ namespace System.Net.Http private void Finish() { _contentBytesRemaining = 0; - _connection.CompleteResponse(); + _connection!.CompleteResponse(); _connection = null; } @@ -173,6 +174,7 @@ namespace System.Net.Http { Debug.Assert(maxBytesToRead > 0); Debug.Assert(_contentBytesRemaining > 0); + Debug.Assert(_connection != null); ReadOnlyMemory connectionBuffer = _connection.RemainingBuffer; if (connectionBuffer.Length == 0) @@ -208,13 +210,13 @@ namespace System.Net.Http return false; } - CancellationTokenSource cts = null; + CancellationTokenSource? cts = null; CancellationTokenRegistration ctr = default; TimeSpan drainTime = _connection._pool.Settings._maxResponseDrainTime; if (drainTime != Timeout.InfiniteTimeSpan) { cts = new CancellationTokenSource((int)drainTime.TotalMilliseconds); - ctr = cts.Token.Register(s => ((HttpConnection)s).Dispose(), _connection); + ctr = cts.Token.Register(s => ((HttpConnection)s!).Dispose(), _connection); } try { diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/CookieHelper.cs b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/CookieHelper.cs index 024359e..64cff30 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/CookieHelper.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/CookieHelper.cs @@ -12,12 +12,12 @@ namespace System.Net.Http { public static void ProcessReceivedCookies(HttpResponseMessage response, CookieContainer cookieContainer) { - IEnumerable values; - if (response.Headers.TryGetValues(KnownHeaders.SetCookie.Descriptor, out values)) + if (response.Headers.TryGetValues(KnownHeaders.SetCookie.Descriptor, out IEnumerable? values)) { // The header values are always a string[] var valuesArray = (string[])values; Debug.Assert(valuesArray.Length > 0, "No values for header??"); + Debug.Assert(response.RequestMessage != null && response.RequestMessage.RequestUri != null); Uri requestUri = response.RequestMessage.RequestUri; for (int i = 0; i < valuesArray.Length; i++) diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/CreditManager.cs b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/CreditManager.cs index 2812241..f49d61b 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/CreditManager.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/CreditManager.cs @@ -16,7 +16,7 @@ namespace System.Net.Http private bool _disposed; /// Circular singly-linked list of active waiters. /// If null, the list is empty. If non-null, this is the tail. If the list has one item, its Next is itself. - private CreditWaiter _waitersTail; + private CreditWaiter? _waitersTail; public CreditManager(IHttpTrace owner, string name, int initialCredit) { @@ -102,7 +102,8 @@ namespace System.Net.Http while (_current > 0 && _waitersTail != null) { // Get the waiter from the head of the queue. - CreditWaiter waiter = _waitersTail.Next; + CreditWaiter? waiter = _waitersTail.Next; + Debug.Assert(waiter != null); int granted = Math.Min(waiter.Amount, _current); // Remove the waiter from the list. @@ -139,12 +140,12 @@ namespace System.Net.Http _disposed = true; - CreditWaiter waiter = _waitersTail; + CreditWaiter? waiter = _waitersTail; if (waiter != null) { do { - CreditWaiter next = waiter.Next; + CreditWaiter? next = waiter!.Next; waiter.Next = null; waiter.Dispose(); waiter = next; diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/CreditWaiter.cs b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/CreditWaiter.cs index 9520eaf..9e04293 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/CreditWaiter.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/CreditWaiter.cs @@ -14,7 +14,7 @@ namespace System.Net.Http internal class CreditWaiter : IValueTaskSource { public int Amount; - public CreditWaiter Next; + public CreditWaiter? Next; protected ManualResetValueTaskSourceCore _source; public CreditWaiter() => _source.RunContinuationsAsynchronously = true; @@ -49,7 +49,7 @@ namespace System.Net.Http _source.GetResult(token); ValueTaskSourceStatus IValueTaskSource.GetStatus(short token) => _source.GetStatus(token); - void IValueTaskSource.OnCompleted(Action continuation, object state, short token, ValueTaskSourceOnCompletedFlags flags) => + void IValueTaskSource.OnCompleted(Action continuation, object? state, short token, ValueTaskSourceOnCompletedFlags flags) => _source.OnCompleted(continuation, state, token, flags); } diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/DecompressionHandler.cs b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/DecompressionHandler.cs index 1a4e8a6..5eb74ef 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/DecompressionHandler.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/DecompressionHandler.cs @@ -56,10 +56,11 @@ namespace System.Net.Http HttpResponseMessage response = await _innerHandler.SendAsync(request, cancellationToken).ConfigureAwait(false); + Debug.Assert(response.Content != null); ICollection contentEncodings = response.Content.Headers.ContentEncoding; if (contentEncodings.Count > 0) { - string last = null; + string? last = null; foreach (string encoding in contentEncodings) { last = encoding; @@ -108,7 +109,7 @@ namespace System.Net.Http Headers.AddHeaders(originalContent.Headers); Headers.ContentLength = null; Headers.ContentEncoding.Clear(); - string prevEncoding = null; + string? prevEncoding = null; foreach (string encoding in originalContent.Headers.ContentEncoding) { if (prevEncoding != null) @@ -121,10 +122,10 @@ namespace System.Net.Http protected abstract Stream GetDecompressedStream(Stream originalStream); - protected override Task SerializeToStreamAsync(Stream stream, TransportContext context) => + protected override Task SerializeToStreamAsync(Stream stream, TransportContext? context) => SerializeToStreamAsync(stream, context, CancellationToken.None); - protected override async Task SerializeToStreamAsync(Stream stream, TransportContext context, CancellationToken cancellationToken) + protected override async Task SerializeToStreamAsync(Stream stream, TransportContext? context, CancellationToken cancellationToken) { using (Stream decompressedStream = TryCreateContentReadStream() ?? await CreateContentReadStreamAsync(cancellationToken).ConfigureAwait(false)) { @@ -145,9 +146,9 @@ namespace System.Net.Http return GetDecompressedStream(originalStream); } - internal override Stream TryCreateContentReadStream() + internal override Stream? TryCreateContentReadStream() { - Stream originalStream = _originalContent.TryReadAsStream(); + Stream? originalStream = _originalContent.TryReadAsStream(); return originalStream is null ? null : GetDecompressedStream(originalStream); } diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http2Connection.cs b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http2Connection.cs index 1e9f209..b2fbfd3 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http2Connection.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http2Connection.cs @@ -61,13 +61,13 @@ namespace System.Net.Http private int _lastStreamId = -1; // This will be set when a connection IO error occurs - private Exception _abortException; + private Exception? _abortException; // If an in-progress write is canceled we need to be able to immediately // report a cancellation to the user, but also block the connection until // the write completes. We avoid actually canceling the write, as we would // then have to close the whole connection. - private Task _inProgressWrite = null; + private Task? _inProgressWrite = null; private const int MaxStreamId = int.MaxValue; @@ -338,7 +338,7 @@ namespace System.Net.Http // Callers must check for this and send a RST_STREAM or ignore as appropriate. // If the streamId is invalid or the stream is idle, calling this function // will result in a connection level error. - private Http2Stream GetStream(int streamId) + private Http2Stream? GetStream(int streamId) { if (streamId <= 0 || streamId >= _nextStream) { @@ -347,7 +347,7 @@ namespace System.Net.Http lock (SyncObject) { - if (!_httpStreams.TryGetValue(streamId, out Http2Stream http2Stream)) + if (!_httpStreams.TryGetValue(streamId, out Http2Stream? http2Stream)) { return null; } @@ -364,7 +364,7 @@ namespace System.Net.Http bool endStream = frameHeader.EndStreamFlag; int streamId = frameHeader.StreamId; - Http2Stream http2Stream = GetStream(streamId); + Http2Stream? http2Stream = GetStream(streamId); // Note, http2Stream will be null if this is a closed stream. // We will still process the headers, to ensure the header decoding state is up-to-date, @@ -475,7 +475,7 @@ namespace System.Net.Http { Debug.Assert(frameHeader.Type == FrameType.Data); - Http2Stream http2Stream = GetStream(frameHeader.StreamId); + Http2Stream? http2Stream = GetStream(frameHeader.StreamId); // Note, http2Stream will be null if this is a closed stream. // Just ignore the frame in this case. @@ -683,7 +683,7 @@ namespace System.Net.Http } else { - Http2Stream http2Stream = GetStream(frameHeader.StreamId); + Http2Stream? http2Stream = GetStream(frameHeader.StreamId); if (http2Stream == null) { // Ignore invalid stream ID, as per RFC @@ -708,7 +708,7 @@ namespace System.Net.Http throw new Http2ConnectionException(Http2ProtocolErrorCode.ProtocolError); } - Http2Stream http2Stream = GetStream(frameHeader.StreamId); + Http2Stream? http2Stream = GetStream(frameHeader.StreamId); if (http2Stream == null) { // Ignore invalid stream ID, as per RFC @@ -979,7 +979,7 @@ namespace System.Net.Http _headerBuffer.Commit(bytesWritten); } - private void WriteLiteralHeaderValues(ReadOnlySpan values, string separator) + private void WriteLiteralHeaderValues(ReadOnlySpan values, string? separator) { if (NetEventSource.IsEnabled) Trace($"{nameof(values)}={string.Join(separator, values.ToArray())}"); @@ -1033,7 +1033,7 @@ namespace System.Net.Http Debug.Assert(headerValuesCount > 0, "No values for header??"); ReadOnlySpan headerValues = _headerValues.AsSpan(0, headerValuesCount); - KnownHeader knownHeader = header.Key.KnownHeader; + KnownHeader? knownHeader = header.Key.KnownHeader; if (knownHeader != null) { // The Host header is not sent for HTTP2 because we send the ":authority" pseudo-header instead @@ -1058,10 +1058,10 @@ namespace System.Net.Http // For all other known headers, send them via their pre-encoded name and the associated value. WriteBytes(knownHeader.Http2EncodedName); - string separator = null; + string? separator = null; if (headerValues.Length > 1) { - HttpHeaderParser parser = header.Key.Parser; + HttpHeaderParser? parser = header.Key.Parser; if (parser != null && parser.SupportsMultipleValues) { separator = parser.Separator; @@ -1121,6 +1121,7 @@ namespace System.Net.Http WriteBytes(_pool._http2EncodedAuthorityHostHeader); } + Debug.Assert(request.RequestUri != null); string pathAndQuery = request.RequestUri.PathAndQuery; if (pathAndQuery == "/") { @@ -1139,7 +1140,7 @@ namespace System.Net.Http // Determine cookies to send. if (_pool.Settings._useCookies) { - string cookiesFromContainer = _pool.Settings._cookieContainer.GetCookieHeader(request.RequestUri); + string cookiesFromContainer = _pool.Settings._cookieContainer!.GetCookieHeader(request.RequestUri); if (cookiesFromContainer != string.Empty) { WriteBytes(KnownHeaders.Cookie.Http2EncodedName); @@ -1832,7 +1833,7 @@ namespace System.Net.Http lock (SyncObject) { - if (!_httpStreams.Remove(http2Stream.StreamId, out Http2Stream removed)) + if (!_httpStreams.Remove(http2Stream.StreamId, out Http2Stream? removed)) { Debug.Fail($"Stream {http2Stream.StreamId} not found in dictionary during RemoveStream???"); return; @@ -1857,10 +1858,10 @@ namespace System.Net.Http public sealed override string ToString() => $"{nameof(Http2Connection)}({_pool})"; // Description for diagnostic purposes - public override void Trace(string message, [CallerMemberName] string memberName = null) => + public override void Trace(string message, [CallerMemberName] string? memberName = null) => Trace(0, message, memberName); - internal void Trace(int streamId, string message, [CallerMemberName] string memberName = null) => + internal void Trace(int streamId, string message, [CallerMemberName] string? memberName = null) => NetEventSource.Log.HandlerMessage( _pool?.GetHashCode() ?? 0, // pool ID GetHashCode(), // connection ID diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http2Stream.cs b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http2Stream.cs index ac9279d..4ca37b2 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http2Stream.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http2Stream.cs @@ -32,13 +32,13 @@ namespace System.Net.Http private readonly Http2Connection _connection; private readonly int _streamId; private readonly HttpRequestMessage _request; - private HttpResponseMessage _response; + private HttpResponseMessage? _response; /// Stores any trailers received after returning the response content to the caller. - private List> _trailers; + private List>? _trailers; private ArrayBuffer _responseBuffer; // mutable struct, do not make this readonly private int _pendingWindowUpdate; - private CancelableCreditWaiter _creditWaiter; + private CancelableCreditWaiter? _creditWaiter; private int _availableCredit; private StreamCompletionState _requestCompletionState; @@ -47,7 +47,7 @@ namespace System.Net.Http // If this is not null, then we have received a reset from the server // (i.e. RST_STREAM or general IO error processing the connection) - private Exception _resetException; + private Exception? _resetException; private bool _canRetry; // if _resetException != null, this indicates the stream was refused and so the request is retryable // This flag indicates that, per section 8.1 of the RFC, the server completed the response and then sent a RST_STREAM with error = NO_ERROR. @@ -77,12 +77,12 @@ namespace System.Net.Http /// private bool _hasWaiter; - private readonly CancellationTokenSource _requestBodyCancellationSource; + private readonly CancellationTokenSource? _requestBodyCancellationSource; // This is a linked token combining the above source and the user-supplied token to SendRequestBodyAsync private CancellationToken _requestBodyCancellationToken; - private readonly TaskCompletionSource _expect100ContinueWaiter; + private readonly TaskCompletionSource? _expect100ContinueWaiter; private int _headerBudgetRemaining; @@ -145,6 +145,7 @@ namespace System.Net.Http // Since the Http2Stream is rooted by the Http2Connection dictionary, doing so would prevent // the response stream from being collected and finalized if it were to be dropped without // being disposed first. + Debug.Assert(_response != null); HttpResponseMessage r = _response; _response = null; return r; @@ -284,10 +285,10 @@ namespace System.Net.Http // as we could end up starting the body copy operation on the main event loop thread, which could // then starve the processing of other requests. So, we make the TCS RunContinuationsAsynchronously. bool sendRequestContent; - TaskCompletionSource waiter = _expect100ContinueWaiter; + TaskCompletionSource waiter = _expect100ContinueWaiter!; using (var expect100Timer = new Timer(s => { - var thisRef = (Http2Stream)s; + var thisRef = (Http2Stream)s!; if (NetEventSource.IsEnabled) thisRef.Trace($"100-Continue timer expired."); thisRef._expect100ContinueWaiter?.TrySetResult(true); }, this, _connection._pool.Settings._expect100ContinueTimeout, Timeout.InfiniteTimeSpan)) @@ -328,7 +329,7 @@ namespace System.Net.Http lock (SyncObject) { - CreditWaiter w = _creditWaiter; + CreditWaiter? w = _creditWaiter; if (w != null) { w.Dispose(); @@ -341,7 +342,7 @@ namespace System.Net.Http { if (NetEventSource.IsEnabled) Trace(""); - CancellationTokenSource requestBodyCancellationSource = null; + CancellationTokenSource? requestBodyCancellationSource = null; bool signalWaiter = false; bool sendReset = false; @@ -542,7 +543,7 @@ namespace System.Net.Http } else if ((descriptor.HeaderType & HttpHeaderType.Content) == HttpHeaderType.Content) { - Debug.Assert(_response != null); + Debug.Assert(_response != null && _response.Content != null); _response.Content.Headers.TryAddWithoutValidation(descriptor, headerValue); } else @@ -713,7 +714,7 @@ namespace System.Net.Http if (NetEventSource.IsEnabled) Trace($"{nameof(resetException)}={resetException}, {nameof(resetStreamErrorCode)}={resetStreamErrorCode}"); bool cancel = false; - CancellationTokenSource requestBodyCancellationSource = null; + CancellationTokenSource? requestBodyCancellationSource = null; Debug.Assert(!Monitor.IsEntered(SyncObject)); lock (SyncObject) @@ -848,6 +849,7 @@ namespace System.Net.Http throw; } + Debug.Assert(_response != null && _response.Content != null); // Start to process the response body. var responseContent = (HttpConnectionResponseContent)_response.Content; if (emptyResponse) @@ -865,7 +867,7 @@ namespace System.Net.Http // Process Set-Cookie headers. if (_connection._pool.Settings._useCookies) { - CookieHelper.ProcessReceivedCookies(_response, _connection._pool.Settings._cookieContainer); + CookieHelper.ProcessReceivedCookies(_response, _connection._pool.Settings._cookieContainer!); } } @@ -1073,7 +1075,7 @@ namespace System.Net.Http // Deal with [ActiveIssue("https://github.com/dotnet/runtime/issues/17492")] // Custom HttpContent classes do not get passed the cancellationToken. // So, inject the expected CancellationToken here, to ensure we can cancel the request body send if needed. - CancellationTokenSource customCancellationSource = null; + CancellationTokenSource? customCancellationSource = null; if (!cancellationToken.CanBeCanceled) { cancellationToken = _requestBodyCancellationToken; @@ -1082,7 +1084,7 @@ namespace System.Net.Http { // User passed a custom CancellationToken. // We can't tell if it includes our Token or not, so assume it doesn't. - customCancellationSource = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, _requestBodyCancellationSource.Token); + customCancellationSource = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, _requestBodyCancellationSource!.Token); cancellationToken = customCancellationSource.Token; } @@ -1115,6 +1117,7 @@ namespace System.Net.Http if (sendSize == -1) { + Debug.Assert(_creditWaiter != null); sendSize = await _creditWaiter.AsValueTask().ConfigureAwait(false); _creditWaiter.CleanUp(); } @@ -1157,7 +1160,7 @@ namespace System.Net.Http // for this object's state transitions at a time, we allow the object to be awaited directly. All functionality // associated with the implementation is just delegated to the ManualResetValueTaskSourceCore. ValueTaskSourceStatus IValueTaskSource.GetStatus(short token) => _waitSource.GetStatus(token); - void IValueTaskSource.OnCompleted(Action continuation, object state, short token, ValueTaskSourceOnCompletedFlags flags) => _waitSource.OnCompleted(continuation, state, token, flags); + void IValueTaskSource.OnCompleted(Action continuation, object? state, short token, ValueTaskSourceOnCompletedFlags flags) => _waitSource.OnCompleted(continuation, state, token, flags); void IValueTaskSource.GetResult(short token) => _waitSource.GetResult(token); private void WaitForData() @@ -1194,7 +1197,7 @@ namespace System.Net.Http { using (cancellationToken.UnsafeRegister(s => { - var thisRef = (Http2Stream)s; + var thisRef = (Http2Stream)s!; bool signalWaiter; Debug.Assert(!Monitor.IsEntered(thisRef.SyncObject)); @@ -1218,7 +1221,7 @@ namespace System.Net.Http } } - public void Trace(string message, [CallerMemberName] string memberName = null) => + public void Trace(string message, [CallerMemberName] string? memberName = null) => _connection.Trace(_streamId, message, memberName); private enum ResponseProtocolState : byte @@ -1241,7 +1244,7 @@ namespace System.Net.Http private sealed class Http2ReadStream : HttpBaseStream { - private Http2Stream _http2Stream; + private Http2Stream? _http2Stream; private readonly HttpResponseMessage _responseMessage; public Http2ReadStream(Http2Stream http2Stream) @@ -1267,7 +1270,7 @@ namespace System.Net.Http protected override void Dispose(bool disposing) { - Http2Stream http2Stream = Interlocked.Exchange(ref _http2Stream, null); + Http2Stream? http2Stream = Interlocked.Exchange(ref _http2Stream, null); if (http2Stream == null) { return; @@ -1296,7 +1299,7 @@ namespace System.Net.Http public override ValueTask ReadAsync(Memory destination, CancellationToken cancellationToken) { - Http2Stream http2Stream = _http2Stream; + Http2Stream? http2Stream = _http2Stream; if (http2Stream == null) { @@ -1321,7 +1324,7 @@ namespace System.Net.Http public override Task CopyToAsync(Stream destination, int bufferSize, CancellationToken cancellationToken) { StreamHelpers.ValidateCopyToArgs(this, destination, bufferSize); - Http2Stream http2Stream = _http2Stream; + Http2Stream? http2Stream = _http2Stream; return http2Stream is null ? Task.FromException(ExceptionDispatchInfo.SetCurrentStackTrace(new ObjectDisposedException(nameof(Http2ReadStream)))) : cancellationToken.IsCancellationRequested ? Task.FromCanceled(cancellationToken) : @@ -1335,7 +1338,7 @@ namespace System.Net.Http private sealed class Http2WriteStream : HttpBaseStream { - private Http2Stream _http2Stream; + private Http2Stream? _http2Stream; public Http2WriteStream(Http2Stream http2Stream) { @@ -1345,7 +1348,7 @@ namespace System.Net.Http protected override void Dispose(bool disposing) { - Http2Stream http2Stream = Interlocked.Exchange(ref _http2Stream, null); + Http2Stream? http2Stream = Interlocked.Exchange(ref _http2Stream, null); if (http2Stream == null) { return; @@ -1363,7 +1366,7 @@ namespace System.Net.Http public override ValueTask WriteAsync(ReadOnlyMemory buffer, CancellationToken cancellationToken) { - Http2Stream http2Stream = _http2Stream; + Http2Stream? http2Stream = _http2Stream; if (http2Stream == null) { @@ -1380,7 +1383,7 @@ namespace System.Net.Http return Task.FromCanceled(cancellationToken); } - Http2Stream http2Stream = _http2Stream; + Http2Stream? http2Stream = _http2Stream; if (http2Stream == null) { diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http3Connection.cs b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http3Connection.cs index 9ed1fc9f..50cd701 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http3Connection.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http3Connection.cs @@ -27,11 +27,11 @@ namespace System.Net.Http private const int MaximumUnknownFramePayloadLength = 4096; private readonly HttpConnectionPool _pool; - private readonly HttpAuthority _origin; + private readonly HttpAuthority? _origin; private readonly HttpAuthority _authority; private readonly byte[] _altUsedEncodedHeader; - private QuicConnection _connection; - private Task _connectionClosedTask; + private QuicConnection? _connection; + private Task? _connectionClosedTask; // Keep a collection of requests around so we can process GOAWAY. private readonly Dictionary _activeRequests = new Dictionary(); @@ -40,7 +40,7 @@ namespace System.Net.Http private long _lastProcessedStreamId = -1; // Our control stream. - private QuicStream _clientControl; + private QuicStream? _clientControl; // Current SETTINGS from the server. private int _maximumHeadersLength = int.MaxValue; // TODO: this is not yet observed by Http3Stream when buffering headers. @@ -56,13 +56,13 @@ namespace System.Net.Http private readonly Queue> _waitingRequests = new Queue>(); // A connection-level error will abort any future operations. - private Exception _abortException; + private Exception? _abortException; public HttpAuthority Authority => _authority; public HttpConnectionPool Pool => _pool; public int MaximumRequestHeadersLength => _maximumHeadersLength; public byte[] AltUsedEncodedHeaderBytes => _altUsedEncodedHeader; - public Exception AbortException => Volatile.Read(ref _abortException); + public Exception? AbortException => Volatile.Read(ref _abortException); private object SyncObj => _activeRequests; /// @@ -77,7 +77,7 @@ namespace System.Net.Http } } - public Http3Connection(HttpConnectionPool pool, HttpAuthority origin, HttpAuthority authority, QuicConnection connection) + public Http3Connection(HttpConnectionPool pool, HttpAuthority? origin, HttpAuthority authority, QuicConnection connection) { _pool = pool; _origin = origin; @@ -148,7 +148,7 @@ namespace System.Net.Http { if (closeTask.IsFaulted && NetEventSource.IsEnabled) { - Trace($"{nameof(QuicConnection)} failed to close: {closeTask.Exception.InnerException}"); + Trace($"{nameof(QuicConnection)} failed to close: {closeTask.Exception!.InnerException}"); } try @@ -167,7 +167,7 @@ namespace System.Net.Http { // Wait for an available stream (based on QUIC MAX_STREAMS) if there isn't one available yet. - TaskCompletionSourceWithCancellation waitForAvailableStreamTcs = null; + TaskCompletionSourceWithCancellation? waitForAvailableStreamTcs = null; lock (SyncObj) { @@ -191,8 +191,8 @@ namespace System.Net.Http // Allocate an active request - QuicStream quicStream = null; - Http3RequestStream requestStream = null; + QuicStream? quicStream = null; + Http3RequestStream? requestStream = null; try { @@ -213,7 +213,7 @@ namespace System.Net.Http // 0-byte write to force QUIC to allocate a stream ID. await quicStream.WriteAsync(Array.Empty(), cancellationToken).ConfigureAwait(false); - requestStream.StreamId = quicStream.StreamId; + requestStream!.StreamId = quicStream.StreamId; bool goAway; lock (SyncObj) @@ -278,7 +278,7 @@ namespace System.Net.Http { Debug.Assert(Monitor.IsEntered(SyncObj)); - while (_waitingRequests.TryDequeue(out TaskCompletionSourceWithCancellation tcs)) + while (_waitingRequests.TryDequeue(out TaskCompletionSourceWithCancellation? tcs)) { tcs.TrySetException(new HttpRequestException(SR.net_http_request_aborted, null, RequestRetryType.RetryOnSameOrNextProxy)); } @@ -297,7 +297,7 @@ namespace System.Net.Http _requestStreamsRemaining += (newMaximumStreamCount - _maximumRequestStreams); _maximumRequestStreams = newMaximumStreamCount; - while (_requestStreamsRemaining != 0 && _waitingRequests.TryDequeue(out TaskCompletionSourceWithCancellation tcs)) + while (_requestStreamsRemaining != 0 && _waitingRequests.TryDequeue(out TaskCompletionSourceWithCancellation? tcs)) { if (tcs.TrySetResult(true)) { @@ -316,7 +316,7 @@ namespace System.Net.Http internal Exception Abort(Exception abortException) { // Only observe the first exception we get. - Exception firstException = Interlocked.CompareExchange(ref _abortException, abortException, null); + Exception? firstException = Interlocked.CompareExchange(ref _abortException, abortException, null); if (firstException != null) { @@ -412,10 +412,10 @@ namespace System.Net.Http } } - public override void Trace(string message, [CallerMemberName] string memberName = null) => + public override void Trace(string message, [CallerMemberName] string? memberName = null) => Trace(0, message, memberName); - internal void Trace(long streamId, string message, [CallerMemberName] string memberName = null) => + internal void Trace(long streamId, string message, [CallerMemberName] string? memberName = null) => NetEventSource.Log.HandlerMessage( _pool?.GetHashCode() ?? 0, // pool ID GetHashCode(), // connection ID @@ -427,7 +427,7 @@ namespace System.Net.Http { try { - _clientControl = _connection.OpenUnidirectionalStream(); + _clientControl = _connection!.OpenUnidirectionalStream(); await _clientControl.WriteAsync(_pool.Settings.Http3SettingsFrame, CancellationToken.None).ConfigureAwait(false); } catch (Exception ex) @@ -471,7 +471,7 @@ namespace System.Net.Http } // No cancellation token is needed here; we expect the operation to cancel itself when _connection is disposed. - streamTask = _connection.AcceptStreamAsync(CancellationToken.None); + streamTask = _connection!.AcceptStreamAsync(CancellationToken.None); } QuicStream stream = await streamTask.ConfigureAwait(false); diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http3RequestStream.cs b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http3RequestStream.cs index c15594b..d1be81f 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http3RequestStream.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http3RequestStream.cs @@ -14,6 +14,7 @@ using System.Runtime.CompilerServices; using System.Net.Http.QPack; using System.Runtime.ExceptionServices; using System.Buffers; +using System.Diagnostics.CodeAnalysis; namespace System.Net.Http { @@ -26,14 +27,14 @@ namespace System.Net.Http private ArrayBuffer _sendBuffer; private readonly ReadOnlyMemory[] _gatheredSendBuffer = new ReadOnlyMemory[2]; private ArrayBuffer _recvBuffer; - private TaskCompletionSource _expect100ContinueCompletionSource; // True indicates we should send content (e.g. received 100 Continue). + private TaskCompletionSource? _expect100ContinueCompletionSource; // True indicates we should send content (e.g. received 100 Continue). private bool _disposed; - private CancellationTokenSource _goawayCancellationSource; + private CancellationTokenSource? _goawayCancellationSource; private CancellationToken _goawayCancellationToken; // Allocated when we receive a :status header. - private HttpResponseMessage _response; + private HttpResponseMessage? _response; // Header decoding. private QPackDecoder _headerDecoder; @@ -44,7 +45,7 @@ namespace System.Net.Http private string[] _headerValues = Array.Empty(); /// Any trailing headers. - private List<(HeaderDescriptor name, string value)> _trailingHeaders; + private List<(HeaderDescriptor name, string value)>? _trailingHeaders; // When reading response content, keep track of the number of bytes left in the current data frame. private long _responseDataPayloadRemaining = 0; @@ -97,8 +98,8 @@ namespace System.Net.Http private void DisposeSyncHelper() { _connection.RemoveStream(_stream); - _connection = null; - _stream = null; + _connection = null!; + _stream = null!; _sendBuffer.Dispose(); _recvBuffer.Dispose(); @@ -110,7 +111,7 @@ namespace System.Net.Http public void GoAway() { // Dispose() might be called concurrently with GoAway(), we need to make sure to not Dispose/Cancel the CTS concurrently. - using CancellationTokenSource cts = Interlocked.Exchange(ref _goawayCancellationSource, null); + using CancellationTokenSource? cts = Interlocked.Exchange(ref _goawayCancellationSource, null); cts?.Cancel(); } @@ -199,6 +200,7 @@ namespace System.Net.Http // Use an atomic exchange to avoid a race to Cancel()/Dispose(). Interlocked.Exchange(ref _goawayCancellationSource, null)?.Dispose(); + Debug.Assert(_response != null && _response.Content != null); // Set our content stream. var responseContent = (HttpConnectionResponseContent)_response.Content; @@ -221,7 +223,7 @@ namespace System.Net.Http // Process any Set-Cookie headers. if (_connection.Pool.Settings._useCookies) { - CookieHelper.ProcessReceivedCookies(_response, _connection.Pool.Settings._cookieContainer); + CookieHelper.ProcessReceivedCookies(_response, _connection.Pool.Settings._cookieContainer!); } // To avoid a circular reference (stream->response->content->stream), null out the stream's response. @@ -242,7 +244,7 @@ namespace System.Net.Http { // Our stream was reset. - Exception abortException = _connection.AbortException; + Exception? abortException = _connection.AbortException; throw new HttpRequestException(SR.net_http_client_execution_error, abortException ?? ex); } catch (QuicConnectionAbortedException ex) @@ -295,6 +297,7 @@ namespace System.Net.Http /// private async Task ReadResponseAsync(CancellationToken cancellationToken) { + Debug.Assert(_response != null); do { _headerState = HeaderState.StatusHeader; @@ -323,7 +326,7 @@ namespace System.Net.Http // until we get a response back or until our timeout elapses. if (_expect100ContinueCompletionSource != null) { - Timer timer = null; + Timer? timer = null; try { @@ -331,7 +334,7 @@ namespace System.Net.Http { timer = new Timer(o => { - ((Http3RequestStream)o)._expect100ContinueCompletionSource.TrySetResult(true); + ((Http3RequestStream)o!)._expect100ContinueCompletionSource!.TrySetResult(true); }, this, _connection.Pool.Settings._expect100ContinueTimeout, Timeout.InfiniteTimeSpan); } @@ -444,7 +447,7 @@ namespace System.Net.Http goto case null; case null: // Done receiving: copy over trailing headers. - CopyTrailersToResponseMessage(_response); + CopyTrailersToResponseMessage(_response!); return; case Http3FrameType.Data: // The sum of data frames must equal content length. Because this method is only @@ -521,6 +524,7 @@ namespace System.Net.Http // The only way to reach H3 is to upgrade via an Alt-Svc header, so we can encode Alt-Used for every connection. BufferBytes(_connection.AltUsedEncodedHeaderBytes); + Debug.Assert(request.RequestUri != null); string pathAndQuery = request.RequestUri.PathAndQuery; if (pathAndQuery == "/") { @@ -544,7 +548,7 @@ namespace System.Net.Http if (_connection.Pool.Settings._useCookies) { - string cookiesFromContainer = _connection.Pool.Settings._cookieContainer.GetCookieHeader(request.RequestUri); + string cookiesFromContainer = _connection.Pool.Settings._cookieContainer!.GetCookieHeader(request.RequestUri); if (cookiesFromContainer != string.Empty) { BufferLiteralHeaderWithStaticNameReference(H3StaticTable.Cookie, cookiesFromContainer); @@ -595,7 +599,7 @@ namespace System.Net.Http Debug.Assert(headerValuesCount > 0, "No values for header??"); ReadOnlySpan headerValues = _headerValues.AsSpan(0, headerValuesCount); - KnownHeader knownHeader = header.Key.KnownHeader; + KnownHeader? knownHeader = header.Key.KnownHeader; if (knownHeader != null) { // The Host header is not sent for HTTP/3 because we send the ":authority" pseudo-header instead @@ -620,10 +624,10 @@ namespace System.Net.Http // For all other known headers, send them via their pre-encoded name and the associated value. BufferBytes(knownHeader.Http3EncodedName); - string separator = null; + string? separator = null; if (headerValues.Length > 1) { - HttpHeaderParser parser = header.Key.Parser; + HttpHeaderParser? parser = header.Key.Parser; if (parser != null && parser.SupportsMultipleValues) { separator = parser.Separator; @@ -685,7 +689,7 @@ namespace System.Net.Http _sendBuffer.Commit(bytesWritten); } - private void BufferLiteralHeaderValues(ReadOnlySpan values, string separator) + private void BufferLiteralHeaderValues(ReadOnlySpan values, string? separator) { int bytesWritten; while (!QPackEncoder.EncodeValueString(values, separator, _sendBuffer.AvailableSpan, out bytesWritten)) @@ -819,7 +823,7 @@ namespace System.Net.Http void IHttpHeadersHandler.OnStaticIndexedHeader(int index) { - GetStaticQPackHeader(index, out HeaderDescriptor descriptor, out string knownValue); + GetStaticQPackHeader(index, out HeaderDescriptor descriptor, out string? knownValue); OnHeader(index, descriptor, knownValue, literalValue: default); } @@ -829,7 +833,7 @@ namespace System.Net.Http OnHeader(index, descriptor, staticValue: null, literalValue: value); } - private void GetStaticQPackHeader(int index, out HeaderDescriptor descriptor, out string knownValue) + private void GetStaticQPackHeader(int index, out HeaderDescriptor descriptor, out string? knownValue) { if (!HeaderDescriptor.TryGetStaticQPackHeader(index, out descriptor, out knownValue)) { @@ -843,7 +847,7 @@ namespace System.Net.Http /// The static indexed value, if any. /// The literal ASCII value, if any. /// One of or will be set. - private void OnHeader(int? staticIndex, HeaderDescriptor descriptor, string staticValue, ReadOnlySpan literalValue) + private void OnHeader(int? staticIndex, HeaderDescriptor descriptor, string? staticValue, ReadOnlySpan literalValue) { if (descriptor.Name[0] == ':') { @@ -924,13 +928,13 @@ namespace System.Net.Http if (NetEventSource.IsEnabled) Trace($"Received headers without :status."); throw new Http3ConnectionException(Http3ErrorCode.ProtocolError); case HeaderState.ResponseHeaders when descriptor.HeaderType.HasFlag(HttpHeaderType.Content): - _response.Content.Headers.TryAddWithoutValidation(descriptor, headerValue); + _response!.Content!.Headers.TryAddWithoutValidation(descriptor, headerValue); break; case HeaderState.ResponseHeaders: - _response.Headers.TryAddWithoutValidation(descriptor.HeaderType.HasFlag(HttpHeaderType.Request) ? descriptor.AsCustomHeader() : descriptor, headerValue); + _response!.Headers.TryAddWithoutValidation(descriptor.HeaderType.HasFlag(HttpHeaderType.Request) ? descriptor.AsCustomHeader() : descriptor, headerValue); break; case HeaderState.TrailingHeaders: - _trailingHeaders.Add((descriptor.HeaderType.HasFlag(HttpHeaderType.Request) ? descriptor.AsCustomHeader() : descriptor, headerValue)); + _trailingHeaders!.Add((descriptor.HeaderType.HasFlag(HttpHeaderType.Request) ? descriptor.AsCustomHeader() : descriptor, headerValue)); break; default: Debug.Fail($"Unexpected {nameof(Http3RequestStream)}.{nameof(_headerState)} '{_headerState}'."); @@ -1150,14 +1154,14 @@ namespace System.Net.Http } } - public void Trace(string message, [CallerMemberName] string memberName = null) => + public void Trace(string message, [CallerMemberName] string? memberName = null) => _connection.Trace(StreamId, message, memberName); // TODO: it may be possible for Http3RequestStream to implement Stream directly and avoid this allocation. private sealed class Http3ReadStream : HttpBaseStream { private Http3RequestStream _stream; - private HttpResponseMessage _response; + private HttpResponseMessage? _response; public override bool CanRead => true; @@ -1187,10 +1191,10 @@ namespace System.Net.Http // We shouldn't be using a managed instance here, but don't have much choice -- we // need to remove the stream from the connection's GOAWAY collection. _stream._connection.RemoveStream(_stream._stream); - _stream._connection = null; + _stream._connection = null!; } - _stream = null; + _stream = null!; _response = null; } @@ -1202,7 +1206,7 @@ namespace System.Net.Http if (_stream != null) { await _stream.DisposeAsync().ConfigureAwait(false); - _stream = null; + _stream = null!; _response = null; } @@ -1216,6 +1220,7 @@ namespace System.Net.Http throw new ObjectDisposedException(nameof(Http3RequestStream)); } + Debug.Assert(_response != null); return _stream.ReadResponseContent(_response, buffer); } @@ -1226,6 +1231,7 @@ namespace System.Net.Http return new ValueTask(Task.FromException(new ObjectDisposedException(nameof(Http3RequestStream)))); } + Debug.Assert(_response != null); return _stream.ReadResponseContentAsync(_response, buffer, cancellationToken); } @@ -1238,7 +1244,7 @@ namespace System.Net.Http // TODO: it may be possible for Http3RequestStream to implement Stream directly and avoid this allocation. private sealed class Http3WriteStream : HttpBaseStream { - private Http3RequestStream _stream; + private Http3RequestStream? _stream; public override bool CanRead => false; diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpAuthority.cs b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpAuthority.cs index 428f942..f664b87 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpAuthority.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpAuthority.cs @@ -30,12 +30,13 @@ namespace System.Net.Http Port = port; } - public bool Equals(HttpAuthority other) + public bool Equals(HttpAuthority? other) { + Debug.Assert(other != null); return string.Equals(IdnHost, other.IdnHost) && Port == other.Port; } - public override bool Equals(object obj) + public override bool Equals(object? obj) { return obj is HttpAuthority other && Equals(other); } diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpBaseStream.cs b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpBaseStream.cs index db0398d..f26a766 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpBaseStream.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpBaseStream.cs @@ -13,13 +13,13 @@ namespace System.Net.Http { public sealed override bool CanSeek => false; - public sealed override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback callback, object state) => + public sealed override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback? callback, object? state) => TaskToApm.Begin(ReadAsync(buffer, offset, count, default), callback, state); public sealed override int EndRead(IAsyncResult asyncResult) => TaskToApm.End(asyncResult); - public sealed override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback callback, object state) => + public sealed override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback? callback, object? state) => TaskToApm.Begin(WriteAsync(buffer, offset, count, default), callback, state); public sealed override void EndWrite(IAsyncResult asyncResult) => diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnection.cs b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnection.cs index df4fcc2..699e5ce 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnection.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnection.cs @@ -44,12 +44,12 @@ namespace System.Net.Http private static readonly ulong s_http11Bytes = BitConverter.ToUInt64(Encoding.ASCII.GetBytes("HTTP/1.1")); private readonly HttpConnectionPool _pool; - private readonly Socket _socket; // used for polling; _stream should be used for all reading/writing. _stream owns disposal. + private readonly Socket? _socket; // used for polling; _stream should be used for all reading/writing. _stream owns disposal. private readonly Stream _stream; - private readonly TransportContext _transportContext; + private readonly TransportContext? _transportContext; private readonly WeakReference _weakThisRef; - private HttpRequestMessage _currentRequest; + private HttpRequestMessage? _currentRequest; private readonly byte[] _writeBuffer; private int _writeOffset; private int _allowedReadLineBytes; @@ -69,9 +69,9 @@ namespace System.Net.Http public HttpConnection( HttpConnectionPool pool, - Socket socket, + Socket? socket, Stream stream, - TransportContext transportContext) + TransportContext? transportContext) { Debug.Assert(pool != null); Debug.Assert(stream != null); @@ -178,7 +178,7 @@ namespace System.Net.Http return null; } - public TransportContext TransportContext => _transportContext; + public TransportContext? TransportContext => _transportContext; public HttpConnectionKind Kind => _pool.Kind; @@ -192,7 +192,7 @@ namespace System.Net.Http _readOffset += bytesToConsume; } - private async ValueTask WriteHeadersAsync(HttpHeaders headers, string cookiesFromContainer) + private async ValueTask WriteHeadersAsync(HttpHeaders headers, string? cookiesFromContainer) { if (headers.HeaderStore != null) { @@ -225,11 +225,11 @@ namespace System.Net.Http // Some headers such as User-Agent and Server use space as a separator (see: ProductInfoHeaderParser) if (headerValuesCount > 1) { - HttpHeaderParser parser = header.Key.Parser; + HttpHeaderParser? parser = header.Key.Parser; string separator = HttpHeaderParser.DefaultSeparator; if (parser != null && parser.SupportsMultipleValues) { - separator = parser.Separator; + separator = parser.Separator!; } for (int i = 1; i < headerValuesCount; i++) @@ -318,8 +318,8 @@ namespace System.Net.Http public async Task SendAsyncCore(HttpRequestMessage request, CancellationToken cancellationToken) { - TaskCompletionSource allowExpect100ToContinue = null; - Task sendRequestContentTask = null; + TaskCompletionSource? allowExpect100ToContinue = null; + Task? sendRequestContentTask = null; Debug.Assert(_currentRequest == null, $"Expected null {nameof(_currentRequest)}."); Debug.Assert(RemainingBuffer.Length == 0, "Unexpected data in read buffer"); @@ -334,6 +334,7 @@ namespace System.Net.Http CancellationTokenRegistration cancellationRegistration = RegisterCancellation(cancellationToken); try { + Debug.Assert(request.RequestUri != null); // Write request line await WriteStringAsync(normalizedMethod.Method).ConfigureAwait(false); await WriteByteAsync((byte)' ').ConfigureAwait(false); @@ -385,10 +386,10 @@ namespace System.Net.Http await WriteBytesAsync(isHttp10 ? s_spaceHttp10NewlineAsciiBytes : s_spaceHttp11NewlineAsciiBytes).ConfigureAwait(false); // Determine cookies to send - string cookiesFromContainer = null; + string? cookiesFromContainer = null; if (_pool.Settings._useCookies) { - cookiesFromContainer = _pool.Settings._cookieContainer.GetCookieHeader(request.RequestUri); + cookiesFromContainer = _pool.Settings._cookieContainer!.GetCookieHeader(request.RequestUri); if (cookiesFromContainer == "") { cookiesFromContainer = null; @@ -455,7 +456,7 @@ namespace System.Net.Http // Then kick off the request. The TCS' result indicates whether content should be sent or not. allowExpect100ToContinue = new TaskCompletionSource(); var expect100Timer = new Timer( - s => ((TaskCompletionSource)s).TrySetResult(true), + s => ((TaskCompletionSource)s!).TrySetResult(true), allowExpect100ToContinue, _pool.Settings._expect100ContinueTimeout, Timeout.InfiniteTimeSpan); sendRequestContentTask = SendRequestContentWithExpect100ContinueAsync( request, allowExpect100ToContinue.Task, CreateRequestContentStream(request), expect100Timer, cancellationToken); @@ -648,7 +649,7 @@ namespace System.Net.Http // Process Set-Cookie headers. if (_pool.Settings._useCookies) { - CookieHelper.ProcessReceivedCookies(response, _pool.Settings._cookieContainer); + CookieHelper.ProcessReceivedCookies(response, _pool.Settings._cookieContainer!); } return response; @@ -739,8 +740,8 @@ namespace System.Net.Http // artificially keeping this connection alive. return cancellationToken.Register(s => { - var weakThisRef = (WeakReference)s; - if (weakThisRef.TryGetTarget(out HttpConnection strongThisRef)) + var weakThisRef = (WeakReference)s!; + if (weakThisRef.TryGetTarget(out HttpConnection? strongThisRef)) { if (NetEventSource.IsEnabled) strongThisRef.Trace("Cancellation requested. Disposing of the connection."); strongThisRef.Dispose(); @@ -756,7 +757,7 @@ namespace System.Net.Http _canRetry = false; // Copy all of the data to the server. - await request.Content.CopyToAsync(stream, _transportContext, cancellationToken).ConfigureAwait(false); + await request.Content!.CopyToAsync(stream, _transportContext, cancellationToken).ConfigureAwait(false); // Finish the content; with a chunked upload, this includes writing the terminating chunk. await stream.FinishAsync().ConfigureAwait(false); @@ -845,7 +846,7 @@ namespace System.Net.Http else if (line[MinStatusLineLength] == ' ') { Span reasonBytes = line.Slice(MinStatusLineLength + 1); - string knownReasonPhrase = HttpStatusDescription.Get(response.StatusCode); + string? knownReasonPhrase = HttpStatusDescription.Get(response.StatusCode); if (knownReasonPhrase != null && EqualsOrdinal(knownReasonPhrase, reasonBytes)) { response.SetReasonPhraseWithoutValidation(knownReasonPhrase); @@ -941,7 +942,7 @@ namespace System.Net.Http } else if ((descriptor.HeaderType & HttpHeaderType.Content) == HttpHeaderType.Content) { - response.Content.Headers.TryAddWithoutValidation(descriptor, headerValue); + response.Content!.Headers.TryAddWithoutValidation(descriptor, headerValue); } else { @@ -1637,7 +1638,7 @@ namespace System.Net.Http // use a temporary buffer from the ArrayPool so that the connection doesn't hog large // buffers from the pool for extended durations, especially if it's going to sit in the // connection pool for a prolonged period. - byte[] origReadBuffer = null; + byte[]? origReadBuffer = null; try { while (true) @@ -1754,8 +1755,9 @@ namespace System.Net.Http throw new HttpRequestException(SR.net_http_authconnectionfailure); } + Debug.Assert(response.Content != null); Stream stream = await response.Content.ReadAsStreamAsync(cancellationToken).ConfigureAwait(false); - HttpContentReadStream responseStream = stream as HttpContentReadStream; + HttpContentReadStream? responseStream = stream as HttpContentReadStream; Debug.Assert(responseStream != null || stream is EmptyReadStream); @@ -1823,7 +1825,7 @@ namespace System.Net.Http public sealed override string ToString() => $"{nameof(HttpConnection)}({_pool})"; // Description for diagnostic purposes - public sealed override void Trace(string message, [CallerMemberName] string memberName = null) => + public sealed override void Trace(string message, [CallerMemberName] string? memberName = null) => NetEventSource.Log.HandlerMessage( _pool?.GetHashCode() ?? 0, // pool ID GetHashCode(), // connection ID @@ -1834,7 +1836,7 @@ namespace System.Net.Http internal sealed class HttpConnectionWithFinalizer : HttpConnection { - public HttpConnectionWithFinalizer(HttpConnectionPool pool, Socket socket, Stream stream, TransportContext transportContext) : base(pool, socket, stream, transportContext) { } + public HttpConnectionWithFinalizer(HttpConnectionPool pool, Socket? socket, Stream stream, TransportContext? transportContext) : base(pool, socket, stream, transportContext) { } // This class is separated from HttpConnection so we only pay the price of having a finalizer // when it's actually needed, e.g. when MaxConnectionsPerServer is enabled. diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnectionBase.cs b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnectionBase.cs index 17c9455..258be91 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnectionBase.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnectionBase.cs @@ -13,7 +13,7 @@ namespace System.Net.Http internal abstract class HttpConnectionBase : IHttpTrace { public abstract Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken); - public abstract void Trace(string message, [CallerMemberName] string memberName = null); + public abstract void Trace(string message, [CallerMemberName] string? memberName = null); protected void TraceConnection(Stream stream) { diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnectionPool.cs b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnectionPool.cs index d8f25b7..ad9a4ba 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnectionPool.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnectionPool.cs @@ -30,16 +30,16 @@ namespace System.Net.Http private readonly HttpConnectionPoolManager _poolManager; private readonly HttpConnectionKind _kind; - private readonly Uri _proxyUri; + private readonly Uri? _proxyUri; /// The origin authority used to construct the . - private readonly HttpAuthority _originAuthority; + private readonly HttpAuthority? _originAuthority; /// Initially set to null, this can be set to enable HTTP/3 based on Alt-Svc. - private volatile HttpAuthority _http3Authority; + private volatile HttpAuthority? _http3Authority; /// A timer to expire and return the pool to . Initialized on first use. - private Timer _authorityExpireTimer; + private Timer? _authorityExpireTimer; /// If true, the will persist across a network change. If false, it will be reset to . private bool _persistAuthority; @@ -48,8 +48,8 @@ namespace System.Net.Http /// When an Alt-Svc authority fails due to 421 Misdirected Request, it is placed in the blacklist to be ignored /// for milliseconds. Initialized on first use. /// - private volatile HashSet _altSvcBlacklist; - private CancellationTokenSource _altSvcBlacklistTimerCancellation; + private volatile HashSet? _altSvcBlacklist; + private CancellationTokenSource? _altSvcBlacklistTimerCancellation; private volatile bool _altSvcEnabled = true; /// @@ -67,25 +67,25 @@ namespace System.Net.Http private readonly int _maxConnections; private bool _http2Enabled; - private Http2Connection _http2Connection; - private SemaphoreSlim _http2ConnectionCreateLock; - private byte[] _http2AltSvcOriginUri; - internal readonly byte[] _http2EncodedAuthorityHostHeader; + private Http2Connection? _http2Connection; + private SemaphoreSlim? _http2ConnectionCreateLock; + private byte[]? _http2AltSvcOriginUri; + internal readonly byte[]? _http2EncodedAuthorityHostHeader; private readonly bool _http3Enabled; - private Http3Connection _http3Connection; - private SemaphoreSlim _http3ConnectionCreateLock; - internal readonly byte[] _http3EncodedAuthorityHostHeader; + private Http3Connection? _http3Connection; + private SemaphoreSlim? _http3ConnectionCreateLock; + internal readonly byte[]? _http3EncodedAuthorityHostHeader; /// For non-proxy connection pools, this is the host name in bytes; for proxies, null. - private readonly byte[] _hostHeaderValueBytes; + private readonly byte[]? _hostHeaderValueBytes; /// Options specialized and cached for this pool and its key. - private readonly SslClientAuthenticationOptions _sslOptionsHttp11; - private readonly SslClientAuthenticationOptions _sslOptionsHttp2; - private readonly SslClientAuthenticationOptions _sslOptionsHttp3; + private readonly SslClientAuthenticationOptions? _sslOptionsHttp11; + private readonly SslClientAuthenticationOptions? _sslOptionsHttp2; + private readonly SslClientAuthenticationOptions? _sslOptionsHttp3; /// Queue of waiters waiting for a connection. Created on demand. - private Queue> _waiters; + private Queue>? _waiters; /// The number of connections associated with the pool. Some of these may be in , others may be in use. private int _associatedConnectionCount; @@ -99,7 +99,7 @@ namespace System.Net.Http /// Initializes the pool. /// The maximum number of connections allowed to be associated with the pool at any given time. - public HttpConnectionPool(HttpConnectionPoolManager poolManager, HttpConnectionKind kind, string host, int port, string sslHostName, Uri proxyUri, int maxConnections) + public HttpConnectionPool(HttpConnectionPoolManager poolManager, HttpConnectionKind kind, string? host, int port, string? sslHostName, Uri? proxyUri, int maxConnections) { _poolManager = poolManager; _kind = kind; @@ -186,7 +186,7 @@ namespace System.Net.Http _altSvcEnabled = false; } - string hostHeader = null; + string? hostHeader = null; if (_originAuthority != null) { // Precalculate ASCII bytes for Host header @@ -281,15 +281,15 @@ namespace System.Net.Http return sslOptions; } - public HttpAuthority OriginAuthority => _originAuthority; + public HttpAuthority? OriginAuthority => _originAuthority; public HttpConnectionSettings Settings => _poolManager.Settings; public bool IsSecure => _sslOptionsHttp11 != null; public HttpConnectionKind Kind => _kind; public bool AnyProxyKind => (_proxyUri != null); - public Uri ProxyUri => _proxyUri; - public ICredentials ProxyCredentials => _poolManager.ProxyCredentials; - public byte[] HostHeaderValueBytes => _hostHeaderValueBytes; - public CredentialCache PreAuthCredentials { get; } + public Uri? ProxyUri => _proxyUri; + public ICredentials? ProxyCredentials => _poolManager.ProxyCredentials; + public byte[]? HostHeaderValueBytes => _hostHeaderValueBytes; + public CredentialCache? PreAuthCredentials { get; } /// /// An ASCII origin string per RFC 6454 Section 6.2, in format <scheme>://<host>[:<port>] @@ -305,6 +305,7 @@ namespace System.Net.Http { var sb = new StringBuilder(); + Debug.Assert(_originAuthority != null); sb .Append(_kind == HttpConnectionKind.Https ? "https://" : "http://") .Append(_originAuthority.IdnHost); @@ -326,12 +327,12 @@ namespace System.Net.Http /// Object used to synchronize access to state in the pool. private object SyncObj => _idleConnections; - private ValueTask<(HttpConnectionBase connection, bool isNewConnection, HttpResponseMessage failureResponse)> + private ValueTask<(HttpConnectionBase? connection, bool isNewConnection, HttpResponseMessage? failureResponse)> GetConnectionAsync(HttpRequestMessage request, CancellationToken cancellationToken) { if (_http3Enabled && request.Version.Major >= 3) { - HttpAuthority authority = _http3Authority; + HttpAuthority? authority = _http3Authority; if (authority != null) { return GetHttp3ConnectionAsync(request, authority, cancellationToken); @@ -346,11 +347,11 @@ namespace System.Net.Http return GetHttpConnectionAsync(request, cancellationToken); } - private ValueTask GetOrReserveHttp11ConnectionAsync(CancellationToken cancellationToken) + private ValueTask GetOrReserveHttp11ConnectionAsync(CancellationToken cancellationToken) { if (cancellationToken.IsCancellationRequested) { - return new ValueTask(Task.FromCanceled(cancellationToken)); + return new ValueTask(Task.FromCanceled(cancellationToken)); } TimeSpan pooledConnectionLifetime = _poolManager.Settings._pooledConnectionLifetime; @@ -360,7 +361,7 @@ namespace System.Net.Http // Try to find a usable cached connection. // If we can't find one, we will either wait for one to become available (if at the connection limit) // or just increment the connection count and return null so the caller can create a new connection. - TaskCompletionSourceWithCancellation waiter; + TaskCompletionSourceWithCancellation waiter; while (true) { CachedConnection cachedConnection; @@ -381,7 +382,7 @@ namespace System.Net.Http // We are under the connection limit, so just increment the count and return null // to indicate to the caller that they should create a new connection. IncrementConnectionCountNoLock(); - return new ValueTask((HttpConnection)null); + return new ValueTask((HttpConnection?)null); } else { @@ -410,7 +411,7 @@ namespace System.Net.Http { // We found a valid connection. Return it. if (NetEventSource.IsEnabled) conn.Trace("Found usable connection in pool."); - return new ValueTask(conn); + return new ValueTask(conn); } // We got a connection, but it was already closed by the server or the @@ -425,10 +426,10 @@ namespace System.Net.Http return waiter.WaitWithCancellationAsync(cancellationToken); } - private async ValueTask<(HttpConnectionBase connection, bool isNewConnection, HttpResponseMessage failureResponse)> + private async ValueTask<(HttpConnectionBase? connection, bool isNewConnection, HttpResponseMessage? failureResponse)> GetHttpConnectionAsync(HttpRequestMessage request, CancellationToken cancellationToken) { - HttpConnection connection = await GetOrReserveHttp11ConnectionAsync(cancellationToken).ConfigureAwait(false); + HttpConnection? connection = await GetOrReserveHttp11ConnectionAsync(cancellationToken).ConfigureAwait(false); if (connection != null) { return (connection, false, null); @@ -438,7 +439,7 @@ namespace System.Net.Http try { - HttpResponseMessage failureResponse; + HttpResponseMessage? failureResponse; (connection, failureResponse) = await CreateHttp11ConnectionAsync(request, cancellationToken).ConfigureAwait(false); if (connection == null) { @@ -454,13 +455,13 @@ namespace System.Net.Http } } - private async ValueTask<(HttpConnectionBase connection, bool isNewConnection, HttpResponseMessage failureResponse)> + private async ValueTask<(HttpConnectionBase? connection, bool isNewConnection, HttpResponseMessage? failureResponse)> GetHttp2ConnectionAsync(HttpRequestMessage request, CancellationToken cancellationToken) { Debug.Assert(_kind == HttpConnectionKind.Https || _kind == HttpConnectionKind.SslProxyTunnel || _kind == HttpConnectionKind.Http); // See if we have an HTTP2 connection - Http2Connection http2Connection = _http2Connection; + Http2Connection? http2Connection = _http2Connection; if (http2Connection != null) { @@ -493,9 +494,9 @@ namespace System.Net.Http } // Try to establish an HTTP2 connection - Socket socket = null; - SslStream sslStream = null; - TransportContext transportContext = null; + Socket? socket = null; + SslStream? sslStream = null; + TransportContext? transportContext = null; // Serialize creation attempt await _http2ConnectionCreateLock.WaitAsync(cancellationToken).ConfigureAwait(false); @@ -521,8 +522,8 @@ namespace System.Net.Http Trace("Attempting new HTTP2 connection."); } - Stream stream; - HttpResponseMessage failureResponse; + Stream? stream; + HttpResponseMessage? failureResponse; (socket, stream, transportContext, failureResponse) = await ConnectAsync(request, true, cancellationToken).ConfigureAwait(false); if (failureResponse != null) @@ -532,7 +533,7 @@ namespace System.Net.Http if (_kind == HttpConnectionKind.Http) { - http2Connection = new Http2Connection(this, stream); + http2Connection = new Http2Connection(this, stream!); await http2Connection.SetupAsync().ConfigureAwait(false); Debug.Assert(_http2Connection == null); @@ -546,7 +547,7 @@ namespace System.Net.Http return (_http2Connection, true, null); } - sslStream = (SslStream)stream; + sslStream = (SslStream)stream!; if (sslStream.NegotiatedApplicationProtocol == SslApplicationProtocol.Http2) { // The server accepted our request for HTTP2. @@ -625,13 +626,13 @@ namespace System.Net.Http return await GetHttpConnectionAsync(request, cancellationToken).ConfigureAwait(false); } - private async ValueTask<(HttpConnectionBase connection, bool isNewConnection, HttpResponseMessage failureResponse)> + private async ValueTask<(HttpConnectionBase? connection, bool isNewConnection, HttpResponseMessage? failureResponse)> GetHttp3ConnectionAsync(HttpRequestMessage request, HttpAuthority authority, CancellationToken cancellationToken) { Debug.Assert(_kind == HttpConnectionKind.Https); Debug.Assert(_http3Enabled == true); - Http3Connection http3Connection = Volatile.Read(ref _http3Connection); + Http3Connection? http3Connection = Volatile.Read(ref _http3Connection); if (http3Connection != null) { @@ -716,7 +717,7 @@ namespace System.Net.Http { // Loop on connection failures and retry if possible. - (HttpConnectionBase connection, bool isNewConnection, HttpResponseMessage failureResponse) = await GetConnectionAsync(request, cancellationToken).ConfigureAwait(false); + (HttpConnectionBase? connection, bool isNewConnection, HttpResponseMessage? failureResponse) = await GetConnectionAsync(request, cancellationToken).ConfigureAwait(false); if (failureResponse != null) { // Proxy tunnel failure; return proxy response @@ -735,7 +736,7 @@ namespace System.Net.Http } else { - response = await connection.SendAsync(request, cancellationToken).ConfigureAwait(false); + response = await connection!.SendAsync(request, cancellationToken).ConfigureAwait(false); } } catch (HttpRequestException e) when (e.AllowRetry == RequestRetryType.RetryOnLowerHttpVersion) @@ -763,7 +764,7 @@ namespace System.Net.Http } // Check for the Alt-Svc header, to upgrade to HTTP/3. - if (_altSvcEnabled && response.Headers.TryGetValues(KnownHeaders.AltSvc.Descriptor, out IEnumerable altSvcHeaderValues)) + if (_altSvcEnabled && response.Headers.TryGetValues(KnownHeaders.AltSvc.Descriptor, out IEnumerable? altSvcHeaderValues)) { HandleAltSvc(altSvcHeaderValues, response.Headers.Age); } @@ -788,7 +789,7 @@ namespace System.Net.Http /// TODO: common case will likely be a single value. Optimize for that. internal void HandleAltSvc(IEnumerable altSvcHeaderValues, TimeSpan? responseAge) { - HttpAuthority nextAuthority = null; + HttpAuthority? nextAuthority = null; TimeSpan nextAuthorityMaxAge = default; bool nextAuthorityPersist = false; @@ -796,7 +797,7 @@ namespace System.Net.Http { int parseIdx = 0; - while (AltSvcHeaderParser.Parser.TryParseValue(altSvcHeaderValue, null, ref parseIdx, out object parsedValue)) + while (AltSvcHeaderParser.Parser.TryParseValue(altSvcHeaderValue, null, ref parseIdx, out object? parsedValue)) { var value = (AltSvcHeaderValue)parsedValue; @@ -804,13 +805,14 @@ namespace System.Net.Http if (value == AltSvcHeaderValue.Clear) { ExpireAltSvcAuthority(); + Debug.Assert(_authorityExpireTimer != null); _authorityExpireTimer.Change(Timeout.Infinite, Timeout.Infinite); break; } if (nextAuthority == null && value.AlpnProtocolName == "h3") { - var authority = new HttpAuthority(value.Host, value.Port); + var authority = new HttpAuthority(value.Host!, value.Port); if (_altSvcBlacklist != null) { @@ -868,8 +870,8 @@ namespace System.Net.Http _authorityExpireTimer = new Timer(o => { - var wr = (WeakReference)o; - if (wr.TryGetTarget(out HttpConnectionPool @this)) + var wr = (WeakReference)o!; + if (wr.TryGetTarget(out HttpConnectionPool? @this)) { @this.ExpireAltSvcAuthority(); } @@ -923,7 +925,7 @@ namespace System.Net.Http Debug.Assert(badAuthority != null); Debug.Assert(badAuthority != _originAuthority); - HashSet altSvcBlacklist = _altSvcBlacklist; + HashSet? altSvcBlacklist = _altSvcBlacklist; if (altSvcBlacklist == null) { @@ -957,13 +959,15 @@ namespace System.Net.Http if (_http3Authority == badAuthority) { ExpireAltSvcAuthority(); + Debug.Assert(_authorityExpireTimer != null); _authorityExpireTimer.Change(Timeout.Infinite, Timeout.Infinite); } } + Debug.Assert(_altSvcBlacklistTimerCancellation != null); if (added) { - _ = Task.Delay(AltSvcBlacklistTimeoutInMilliseconds) + _ = Task.Delay(AltSvcBlacklistTimeoutInMilliseconds) .ContinueWith(t => { lock (altSvcBlacklist) @@ -990,6 +994,7 @@ namespace System.Net.Http if (_http3Authority != null && _persistAuthority == false) { ExpireAltSvcAuthority(); + Debug.Assert(_authorityExpireTimer != null); _authorityExpireTimer.Change(Timeout.Infinite, Timeout.Infinite); } } @@ -1017,7 +1022,7 @@ namespace System.Net.Http { if (AnyProxyKind && ProxyCredentials != null) { - return AuthenticationHelper.SendWithNtProxyAuthAsync(request, ProxyUri, ProxyCredentials, connection, this, cancellationToken); + return AuthenticationHelper.SendWithNtProxyAuthAsync(request, ProxyUri!, ProxyCredentials, connection, this, cancellationToken); } return connection.SendAsync(request, cancellationToken); @@ -1029,7 +1034,7 @@ namespace System.Net.Http if ((_kind == HttpConnectionKind.Proxy || _kind == HttpConnectionKind.ProxyConnect) && _poolManager.ProxyCredentials != null) { - return AuthenticationHelper.SendWithProxyAuthAsync(request, _proxyUri, _poolManager.ProxyCredentials, doRequestAuth, this, cancellationToken); + return AuthenticationHelper.SendWithProxyAuthAsync(request, _proxyUri!, _poolManager.ProxyCredentials, doRequestAuth, this, cancellationToken); } return SendWithRetryAsync(request, doRequestAuth, cancellationToken); @@ -1045,11 +1050,11 @@ namespace System.Net.Http return SendWithProxyAuthAsync(request, doRequestAuth, cancellationToken); } - private async ValueTask<(Socket, Stream, TransportContext, HttpResponseMessage)> ConnectAsync(HttpRequestMessage request, bool allowHttp2, CancellationToken cancellationToken) + private async ValueTask<(Socket?, Stream?, TransportContext?, HttpResponseMessage?)> ConnectAsync(HttpRequestMessage request, bool allowHttp2, CancellationToken cancellationToken) { // If a non-infinite connect timeout has been set, create and use a new CancellationToken that'll be canceled // when either the original token is canceled or a connect timeout occurs. - CancellationTokenSource cancellationWithConnectTimeout = null; + CancellationTokenSource? cancellationWithConnectTimeout = null; if (Settings._connectTimeout != Timeout.InfiniteTimeSpan) { cancellationWithConnectTimeout = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken); @@ -1059,22 +1064,23 @@ namespace System.Net.Http try { - Stream stream = null; + Stream? stream = null; switch (_kind) { case HttpConnectionKind.Http: case HttpConnectionKind.Https: case HttpConnectionKind.ProxyConnect: + Debug.Assert(_originAuthority != null); stream = await ConnectHelper.ConnectAsync(_originAuthority.IdnHost, _originAuthority.Port, cancellationToken).ConfigureAwait(false); break; case HttpConnectionKind.Proxy: - stream = await ConnectHelper.ConnectAsync(_proxyUri.IdnHost, _proxyUri.Port, cancellationToken).ConfigureAwait(false); + stream = await ConnectHelper.ConnectAsync(_proxyUri!.IdnHost, _proxyUri.Port, cancellationToken).ConfigureAwait(false); break; case HttpConnectionKind.ProxyTunnel: case HttpConnectionKind.SslProxyTunnel: - HttpResponseMessage response; + HttpResponseMessage? response; (stream, response) = await EstablishProxyTunnel(request.HasHeaders ? request.Headers : null, cancellationToken).ConfigureAwait(false); if (response != null) { @@ -1085,12 +1091,12 @@ namespace System.Net.Http break; } - Socket socket = (stream as NetworkStream)?.Socket; + Socket? socket = (stream as NetworkStream)?.Socket; - TransportContext transportContext = null; + TransportContext? transportContext = null; if (_kind == HttpConnectionKind.Https || _kind == HttpConnectionKind.SslProxyTunnel) { - SslStream sslStream = await ConnectHelper.EstablishSslConnectionAsync(allowHttp2 ? _sslOptionsHttp2 : _sslOptionsHttp11, request, stream, cancellationToken).ConfigureAwait(false); + SslStream sslStream = await ConnectHelper.EstablishSslConnectionAsync(allowHttp2 ? _sslOptionsHttp2! : _sslOptionsHttp11!, request, stream!, cancellationToken).ConfigureAwait(false); stream = sslStream; transportContext = sslStream.TransportContext; } @@ -1103,9 +1109,9 @@ namespace System.Net.Http } } - internal async ValueTask<(HttpConnection, HttpResponseMessage)> CreateHttp11ConnectionAsync(HttpRequestMessage request, CancellationToken cancellationToken) + internal async ValueTask<(HttpConnection?, HttpResponseMessage?)> CreateHttp11ConnectionAsync(HttpRequestMessage request, CancellationToken cancellationToken) { - (Socket socket, Stream stream, TransportContext transportContext, HttpResponseMessage failureResponse) = + (Socket? socket, Stream? stream, TransportContext? transportContext, HttpResponseMessage? failureResponse) = await ConnectAsync(request, false, cancellationToken).ConfigureAwait(false); if (failureResponse != null) @@ -1113,10 +1119,10 @@ namespace System.Net.Http return (null, failureResponse); } - return (ConstructHttp11Connection(socket, stream, transportContext), null); + return (ConstructHttp11Connection(socket, stream!, transportContext), null); } - private HttpConnection ConstructHttp11Connection(Socket socket, Stream stream, TransportContext transportContext) + private HttpConnection ConstructHttp11Connection(Socket? socket, Stream stream, TransportContext? transportContext) { return _maxConnections == int.MaxValue ? new HttpConnection(this, socket, stream, transportContext) : @@ -1124,29 +1130,30 @@ namespace System.Net.Http } // Returns the established stream or an HttpResponseMessage from the proxy indicating failure. - private async ValueTask<(Stream, HttpResponseMessage)> EstablishProxyTunnel(HttpRequestHeaders headers, CancellationToken cancellationToken) + private async ValueTask<(Stream?, HttpResponseMessage?)> EstablishProxyTunnel(HttpRequestHeaders? headers, CancellationToken cancellationToken) { + Debug.Assert(_originAuthority != null); // Send a CONNECT request to the proxy server to establish a tunnel. HttpRequestMessage tunnelRequest = new HttpRequestMessage(HttpMethod.Connect, _proxyUri); tunnelRequest.Headers.Host = $"{_originAuthority.IdnHost}:{_originAuthority.Port}"; // This specifies destination host/port to connect to - if (headers != null && headers.TryGetValues(HttpKnownHeaderNames.UserAgent, out IEnumerable values)) + if (headers != null && headers.TryGetValues(HttpKnownHeaderNames.UserAgent, out IEnumerable? values)) { tunnelRequest.Headers.TryAddWithoutValidation(HttpKnownHeaderNames.UserAgent, values); } - HttpResponseMessage tunnelResponse = await _poolManager.SendProxyConnectAsync(tunnelRequest, _proxyUri, cancellationToken).ConfigureAwait(false); + HttpResponseMessage tunnelResponse = await _poolManager.SendProxyConnectAsync(tunnelRequest, _proxyUri!, cancellationToken).ConfigureAwait(false); if (tunnelResponse.StatusCode != HttpStatusCode.OK) { return (null, tunnelResponse); } - return (await tunnelResponse.Content.ReadAsStreamAsync(cancellationToken).ConfigureAwait(false), null); + return (await tunnelResponse.Content!.ReadAsStreamAsync(cancellationToken).ConfigureAwait(false), null); } /// Enqueues a waiter to the waiters list. - private TaskCompletionSourceWithCancellation EnqueueWaiter() + private TaskCompletionSourceWithCancellation EnqueueWaiter() { Debug.Assert(Monitor.IsEntered(SyncObj)); Debug.Assert(Settings._maxConnectionsPerServer != int.MaxValue); @@ -1154,10 +1161,10 @@ namespace System.Net.Http if (_waiters == null) { - _waiters = new Queue>(); + _waiters = new Queue>(); } - var waiter = new TaskCompletionSourceWithCancellation(); + var waiter = new TaskCompletionSourceWithCancellation(); _waiters.Enqueue(waiter); return waiter; } @@ -1171,13 +1178,13 @@ namespace System.Net.Http /// Dequeues a waiter from the waiters list. The list must not be empty. /// The dequeued waiter. - private TaskCompletionSourceWithCancellation DequeueWaiter() + private TaskCompletionSourceWithCancellation DequeueWaiter() { Debug.Assert(Monitor.IsEntered(SyncObj)); Debug.Assert(Settings._maxConnectionsPerServer != int.MaxValue); Debug.Assert(_idleConnections.Count == 0, $"With {_idleConnections.Count} idle connections, we shouldn't have a waiter."); - return _waiters.Dequeue(); + return _waiters!.Dequeue(); } private void IncrementConnectionCountNoLock() @@ -1201,13 +1208,13 @@ namespace System.Net.Http } } - private bool TransferConnection(HttpConnection connection) + private bool TransferConnection(HttpConnection? connection) { Debug.Assert(Monitor.IsEntered(SyncObj)); while (HasWaiter()) { - TaskCompletionSource waiter = DequeueWaiter(); + TaskCompletionSource waiter = DequeueWaiter(); // Try to complete the task. If it's been cancelled already, this will fail. if (waiter.TrySetResult(connection)) @@ -1386,7 +1393,7 @@ namespace System.Net.Http TimeSpan pooledConnectionIdleTimeout = _poolManager.Settings._pooledConnectionIdleTimeout; List list = _idleConnections; - List toDispose = null; + List? toDispose = null; bool tookLock = false; try @@ -1397,7 +1404,7 @@ namespace System.Net.Http // Get the current time. This is compared against each connection's last returned // time to determine whether a connection is too old and should be closed. long nowTicks = Environment.TickCount64; - Http2Connection http2Connection = _http2Connection; + Http2Connection? http2Connection = _http2Connection; if (http2Connection != null) { @@ -1500,12 +1507,12 @@ namespace System.Net.Http (_proxyUri == null ? (_sslOptionsHttp11 == null ? $"http://{_originAuthority}" : - $"https://{_originAuthority}" + (_sslOptionsHttp11.TargetHost != _originAuthority.IdnHost ? $", SSL TargetHost={_sslOptionsHttp11.TargetHost}" : null)) : + $"https://{_originAuthority}" + (_sslOptionsHttp11.TargetHost != _originAuthority!.IdnHost ? $", SSL TargetHost={_sslOptionsHttp11.TargetHost}" : null)) : (_sslOptionsHttp11 == null ? $"Proxy {_proxyUri}" : - $"https://{_originAuthority}/ tunnelled via Proxy {_proxyUri}" + (_sslOptionsHttp11.TargetHost != _originAuthority.IdnHost ? $", SSL TargetHost={_sslOptionsHttp11.TargetHost}" : null))); + $"https://{_originAuthority}/ tunnelled via Proxy {_proxyUri}" + (_sslOptionsHttp11.TargetHost != _originAuthority!.IdnHost ? $", SSL TargetHost={_sslOptionsHttp11.TargetHost}" : null))); - private void Trace(string message, [CallerMemberName] string memberName = null) => + private void Trace(string? message, [CallerMemberName] string? memberName = null) => NetEventSource.Log.HandlerMessage( GetHashCode(), // pool ID 0, // connection ID @@ -1574,7 +1581,7 @@ namespace System.Net.Http } public bool Equals(CachedConnection other) => ReferenceEquals(other._connection, _connection); - public override bool Equals(object obj) => obj is CachedConnection && Equals((CachedConnection)obj); + public override bool Equals(object? obj) => obj is CachedConnection && Equals((CachedConnection)obj); public override int GetHashCode() => _connection?.GetHashCode() ?? 0; } } diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnectionPoolManager.cs b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnectionPoolManager.cs index d7cf040..252c3e5 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnectionPoolManager.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnectionPoolManager.cs @@ -36,15 +36,15 @@ namespace System.Net.Http /// The pools, indexed by endpoint. private readonly ConcurrentDictionary _pools; /// Timer used to initiate cleaning of the pools. - private readonly Timer _cleaningTimer; + private readonly Timer? _cleaningTimer; /// The maximum number of connections allowed per pool. indicates unlimited. private readonly int _maxConnectionsPerServer; // Temporary private readonly HttpConnectionSettings _settings; - private readonly IWebProxy _proxy; - private readonly ICredentials _proxyCredentials; + private readonly IWebProxy? _proxy; + private readonly ICredentials? _proxyCredentials; - private NetworkChangeCleanup _networkChangeCleanup; + private NetworkChangeCleanup? _networkChangeCleanup; /// /// Keeps track of whether or not the cleanup timer is running. It helps us avoid the expensive @@ -105,8 +105,8 @@ namespace System.Net.Http // implementation until the handler is Disposed (or indefinitely if it's not). _cleaningTimer = new Timer(s => { - var wr = (WeakReference)s; - if (wr.TryGetTarget(out HttpConnectionPoolManager thisRef)) + var wr = (WeakReference)s!; + if (wr.TryGetTarget(out HttpConnectionPoolManager? thisRef)) { thisRef.RemoveStalePools(); } @@ -149,7 +149,7 @@ namespace System.Net.Http var poolsRef = new WeakReference>(_pools); NetworkAddressChangedEventHandler networkChangedDelegate = delegate { - if (poolsRef.TryGetTarget(out ConcurrentDictionary pools)) + if (poolsRef.TryGetTarget(out ConcurrentDictionary? pools)) { foreach (HttpConnectionPool pool in pools.Values) { @@ -201,7 +201,7 @@ namespace System.Net.Http } public HttpConnectionSettings Settings => _settings; - public ICredentials ProxyCredentials => _proxyCredentials; + public ICredentials? ProxyCredentials => _proxyCredentials; private static string ParseHostNameFromHeader(string hostHeader) { @@ -232,9 +232,10 @@ namespace System.Net.Http return hostHeader; } - private HttpConnectionKey GetConnectionKey(HttpRequestMessage request, Uri proxyUri, bool isProxyConnect) + private HttpConnectionKey GetConnectionKey(HttpRequestMessage request, Uri? proxyUri, bool isProxyConnect) { - Uri uri = request.RequestUri; + Uri? uri = request.RequestUri; + Debug.Assert(uri != null); if (isProxyConnect) { @@ -242,10 +243,10 @@ namespace System.Net.Http return new HttpConnectionKey(HttpConnectionKind.ProxyConnect, uri.IdnHost, uri.Port, null, proxyUri, GetIdentityIfDefaultCredentialsUsed(_settings._defaultCredentialsUsedForProxy)); } - string sslHostName = null; + string? sslHostName = null; if (HttpUtilities.IsSupportedSecureScheme(uri.Scheme)) { - string hostHeader = request.Headers.Host; + string? hostHeader = request.Headers.Host; if (hostHeader != null) { sslHostName = ParseHostNameFromHeader(hostHeader); @@ -293,11 +294,11 @@ namespace System.Net.Http } } - public Task SendAsyncCore(HttpRequestMessage request, Uri proxyUri, bool doRequestAuth, bool isProxyConnect, CancellationToken cancellationToken) + public Task SendAsyncCore(HttpRequestMessage request, Uri? proxyUri, bool doRequestAuth, bool isProxyConnect, CancellationToken cancellationToken) { HttpConnectionKey key = GetConnectionKey(request, proxyUri, isProxyConnect); - HttpConnectionPool pool; + HttpConnectionPool? pool; while (!_pools.TryGetValue(key, out pool)) { pool = new HttpConnectionPool(this, key.Kind, key.Host, key.Port, key.SslHostName, key.ProxyUri, _maxConnectionsPerServer); @@ -345,9 +346,10 @@ namespace System.Net.Http } // Do proxy lookup. - Uri proxyUri = null; + Uri? proxyUri = null; try { + Debug.Assert(request.RequestUri != null); if (!_proxy.IsBypassed(request.RequestUri)) { if (_proxy is IMultiWebProxy multiWebProxy) @@ -385,9 +387,9 @@ namespace System.Net.Http /// /// The set of proxies to use. /// The first proxy try. - private async Task SendAsyncMultiProxy(HttpRequestMessage request, bool doRequestAuth, MultiProxy multiProxy, Uri firstProxy, CancellationToken cancellationToken) + private async Task SendAsyncMultiProxy(HttpRequestMessage request, bool doRequestAuth, MultiProxy multiProxy, Uri? firstProxy, CancellationToken cancellationToken) { - HttpRequestException rethrowException = null; + HttpRequestException rethrowException; do { @@ -424,7 +426,7 @@ namespace System.Net.Http { try { - _cleaningTimer.Change(timeout, timeout); + _cleaningTimer!.Change(timeout, timeout); _timerIsRunning = timeout != Timeout.InfiniteTimeSpan; } catch (ObjectDisposedException) @@ -486,13 +488,13 @@ namespace System.Net.Http internal readonly struct HttpConnectionKey : IEquatable { public readonly HttpConnectionKind Kind; - public readonly string Host; + public readonly string? Host; public readonly int Port; - public readonly string SslHostName; // null if not SSL - public readonly Uri ProxyUri; + public readonly string? SslHostName; // null if not SSL + public readonly Uri? ProxyUri; public readonly string Identity; - public HttpConnectionKey(HttpConnectionKind kind, string host, int port, string sslHostName, Uri proxyUri, string identity) + public HttpConnectionKey(HttpConnectionKind kind, string? host, int port, string? sslHostName, Uri? proxyUri, string identity) { Kind = kind; Host = host; @@ -508,10 +510,9 @@ namespace System.Net.Http HashCode.Combine(Kind, Host, Port, ProxyUri, Identity) : HashCode.Combine(Kind, Host, Port, SslHostName, ProxyUri, Identity)); - public override bool Equals(object obj) => - obj != null && - obj is HttpConnectionKey && - Equals((HttpConnectionKey)obj); + public override bool Equals(object? obj) => + obj is HttpConnectionKey hck && + Equals(hck); public bool Equals(HttpConnectionKey other) => Kind == other.Kind && diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnectionResponseContent.cs b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnectionResponseContent.cs index 360c06e..7ed050b 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnectionResponseContent.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnectionResponseContent.cs @@ -11,7 +11,7 @@ namespace System.Net.Http { internal sealed class HttpConnectionResponseContent : HttpContent { - private Stream _stream; + private Stream? _stream; private bool _consumedStream; // separate from _stream so that Dispose can drain _stream public void SetStream(Stream stream) @@ -34,10 +34,10 @@ namespace System.Net.Http return _stream; } - protected sealed override Task SerializeToStreamAsync(Stream stream, TransportContext context) => + protected sealed override Task SerializeToStreamAsync(Stream stream, TransportContext? context) => SerializeToStreamAsync(stream, context, CancellationToken.None); - protected sealed override async Task SerializeToStreamAsync(Stream stream, TransportContext context, CancellationToken cancellationToken) + protected sealed override async Task SerializeToStreamAsync(Stream stream, TransportContext? context, CancellationToken cancellationToken) { Debug.Assert(stream != null); diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnectionSettings.cs b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnectionSettings.cs index 3971c9d..7e847ad 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnectionSettings.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnectionSettings.cs @@ -20,16 +20,16 @@ namespace System.Net.Http internal DecompressionMethods _automaticDecompression = HttpHandlerDefaults.DefaultAutomaticDecompression; internal bool _useCookies = HttpHandlerDefaults.DefaultUseCookies; - internal CookieContainer _cookieContainer; + internal CookieContainer? _cookieContainer; internal bool _useProxy = HttpHandlerDefaults.DefaultUseProxy; - internal IWebProxy _proxy; - internal ICredentials _defaultProxyCredentials; + internal IWebProxy? _proxy; + internal ICredentials? _defaultProxyCredentials; internal bool _defaultCredentialsUsedForProxy; internal bool _defaultCredentialsUsedForServer; internal bool _preAuthenticate = HttpHandlerDefaults.DefaultPreAuthenticate; - internal ICredentials _credentials; + internal ICredentials? _credentials; internal bool _allowAutoRedirect = HttpHandlerDefaults.DefaultAutomaticRedirection; internal int _maxAutomaticRedirections = HttpHandlerDefaults.DefaultMaxAutomaticRedirections; @@ -51,9 +51,9 @@ namespace System.Net.Http // Used for testing until https://github.com/dotnet/runtime/issues/987 internal bool _assumePrenegotiatedHttp3ForTesting; - internal SslClientAuthenticationOptions _sslOptions; + internal SslClientAuthenticationOptions? _sslOptions; - internal IDictionary _properties; + internal IDictionary? _properties; public HttpConnectionSettings() { @@ -120,7 +120,7 @@ namespace System.Net.Http } // AppContext switch wasn't used. Check the environment variable. - string envVar = Environment.GetEnvironmentVariable(Http2SupportEnvironmentVariableSettingName); + string? envVar = Environment.GetEnvironmentVariable(Http2SupportEnvironmentVariableSettingName); if (envVar != null && (envVar.Equals("false", StringComparison.OrdinalIgnoreCase) || envVar.Equals("0"))) { // Disallow HTTP/2 protocol. @@ -146,7 +146,7 @@ namespace System.Net.Http } // AppContext switch wasn't used. Check the environment variable. - string envVar = Environment.GetEnvironmentVariable(Http2UnencryptedSupportEnvironmentVariableSettingName); + string? envVar = Environment.GetEnvironmentVariable(Http2UnencryptedSupportEnvironmentVariableSettingName); if (envVar != null && (envVar.Equals("true", StringComparison.OrdinalIgnoreCase) || envVar.Equals("1"))) { // Allow HTTP/2.0 protocol for HTTP endpoints. @@ -172,7 +172,7 @@ namespace System.Net.Http } // AppContext switch wasn't used. Check the environment variable. - string envVar = Environment.GetEnvironmentVariable(Http3DraftSupportEnvironmentVariableSettingName); + string? envVar = Environment.GetEnvironmentVariable(Http3DraftSupportEnvironmentVariableSettingName); if (envVar != null && (envVar.Equals("true", StringComparison.OrdinalIgnoreCase) || envVar.Equals("1"))) { // Allow HTTP/3 protocol for HTTP endpoints. @@ -184,7 +184,7 @@ namespace System.Net.Http } } - private byte[] _http3SettingsFrame; + private byte[]? _http3SettingsFrame; internal byte[] Http3SettingsFrame => _http3SettingsFrame ??= Http3Connection.BuildSettingsFrame(this); } } diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpContentReadStream.cs b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpContentReadStream.cs index 11ac180..af41e3f 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpContentReadStream.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpContentReadStream.cs @@ -61,8 +61,8 @@ namespace System.Net.Http private async Task DrainOnDisposeAsync() { - HttpConnection connection = _connection; // Will be null after drain succeeds - + HttpConnection? connection = _connection; // Will be null after drain succeeds + Debug.Assert(connection != null); try { bool drained = await DrainAsync(connection._pool.Settings._maxResponseDrainSize).ConfigureAwait(false); diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpContentStream.cs b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpContentStream.cs index 860fb55..2943890 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpContentStream.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpContentStream.cs @@ -6,7 +6,7 @@ namespace System.Net.Http { internal abstract class HttpContentStream : HttpBaseStream { - protected HttpConnection _connection; + protected HttpConnection? _connection; public HttpContentStream(HttpConnection connection) { diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpContentWriteStream.cs b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpContentWriteStream.cs index 3c53400..9cdd9a6 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpContentWriteStream.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpContentWriteStream.cs @@ -24,10 +24,10 @@ namespace System.Net.Http public sealed override Task FlushAsync(CancellationToken ignored) { - HttpConnection connection = _connection; + HttpConnection? connection = _connection; return connection != null ? connection.FlushAsync().AsTask() : - default; + default!; } public sealed override int Read(Span buffer) => throw new NotSupportedException(); diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpEnvironmentProxy.Unix.cs b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpEnvironmentProxy.Unix.cs index 91fea8c..9798c72 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpEnvironmentProxy.Unix.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpEnvironmentProxy.Unix.cs @@ -2,6 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +using System.Diagnostics.CodeAnalysis; + namespace System.Net.Http { internal sealed partial class HttpEnvironmentProxy : IWebProxy @@ -11,24 +13,24 @@ namespace System.Net.Http private const string EnvHttpsProxyLC = "https_proxy"; private const string EnvNoProxyLC = "no_proxy"; - public static bool TryCreate(out IWebProxy proxy) + public static bool TryCreate([NotNullWhen(true)] out IWebProxy? proxy) { // Get environment variables. Protocol specific take precedence over // general all_*, lower case variable has precedence over upper case. // Note that curl uses HTTPS_PROXY but not HTTP_PROXY. - Uri httpProxy = GetUriFromString(Environment.GetEnvironmentVariable(EnvHttpProxyLC)); + Uri? httpProxy = GetUriFromString(Environment.GetEnvironmentVariable(EnvHttpProxyLC)); if (httpProxy == null && Environment.GetEnvironmentVariable(EnvCGI) == null) { httpProxy = GetUriFromString(Environment.GetEnvironmentVariable(EnvHttpProxyUC)); } - Uri httpsProxy = GetUriFromString(Environment.GetEnvironmentVariable(EnvHttpsProxyLC)) ?? + Uri? httpsProxy = GetUriFromString(Environment.GetEnvironmentVariable(EnvHttpsProxyLC)) ?? GetUriFromString(Environment.GetEnvironmentVariable(EnvHttpsProxyUC)); if (httpProxy == null || httpsProxy == null) { - Uri allProxy = GetUriFromString(Environment.GetEnvironmentVariable(EnvAllProxyLC)) ?? + Uri? allProxy = GetUriFromString(Environment.GetEnvironmentVariable(EnvAllProxyLC)) ?? GetUriFromString(Environment.GetEnvironmentVariable(EnvAllProxyUC)); if (httpProxy == null) @@ -50,7 +52,7 @@ namespace System.Net.Http return false; } - string noProxy = Environment.GetEnvironmentVariable(EnvNoProxyLC) ?? + string? noProxy = Environment.GetEnvironmentVariable(EnvNoProxyLC) ?? Environment.GetEnvironmentVariable(EnvNoProxyUC); proxy = new HttpEnvironmentProxy(httpProxy, httpsProxy, noProxy); diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpEnvironmentProxy.Windows.cs b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpEnvironmentProxy.Windows.cs index da78df4..0c977a7 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpEnvironmentProxy.Windows.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpEnvironmentProxy.Windows.cs @@ -2,26 +2,28 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +using System.Diagnostics.CodeAnalysis; + namespace System.Net.Http { internal sealed partial class HttpEnvironmentProxy : IWebProxy { - public static bool TryCreate(out IWebProxy proxy) + public static bool TryCreate([NotNullWhen(true)] out IWebProxy? proxy) { // Get environment variables. Protocol specific take precedence over // general all_*. On Windows, environment variables are case insensitive. - Uri httpProxy = null; + Uri? httpProxy = null; if (Environment.GetEnvironmentVariable(EnvCGI) == null) { httpProxy = GetUriFromString(Environment.GetEnvironmentVariable(EnvHttpProxyUC)); } - Uri httpsProxy = GetUriFromString(Environment.GetEnvironmentVariable(EnvHttpsProxyUC)); + Uri? httpsProxy = GetUriFromString(Environment.GetEnvironmentVariable(EnvHttpsProxyUC)); if (httpProxy == null || httpsProxy == null) { - Uri allProxy = GetUriFromString(Environment.GetEnvironmentVariable(EnvAllProxyUC)); + Uri? allProxy = GetUriFromString(Environment.GetEnvironmentVariable(EnvAllProxyUC)); if (httpProxy == null) { @@ -42,7 +44,7 @@ namespace System.Net.Http return false; } - string noProxy = Environment.GetEnvironmentVariable(EnvNoProxyUC); + string? noProxy = Environment.GetEnvironmentVariable(EnvNoProxyUC); proxy = new HttpEnvironmentProxy(httpProxy, httpsProxy, noProxy); return true; diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpEnvironmentProxy.cs b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpEnvironmentProxy.cs index 43268fe..f110c70 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpEnvironmentProxy.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpEnvironmentProxy.cs @@ -12,13 +12,13 @@ namespace System.Net.Http internal sealed class HttpEnvironmentProxyCredentials : ICredentials { // Wrapper class for cases when http and https has different authentication. - private readonly NetworkCredential _httpCred; - private readonly NetworkCredential _httpsCred; - private readonly Uri _httpProxy; - private readonly Uri _httpsProxy; + private readonly NetworkCredential? _httpCred; + private readonly NetworkCredential? _httpsCred; + private readonly Uri? _httpProxy; + private readonly Uri? _httpsProxy; - public HttpEnvironmentProxyCredentials(Uri httpProxy, NetworkCredential httpCred, - Uri httpsProxy, NetworkCredential httpsCred) + public HttpEnvironmentProxyCredentials(Uri? httpProxy, NetworkCredential? httpCred, + Uri? httpsProxy, NetworkCredential? httpsCred) { _httpCred = httpCred; _httpsCred = httpsCred; @@ -26,7 +26,7 @@ namespace System.Net.Http _httpsProxy = httpsProxy; } - public NetworkCredential GetCredential(Uri uri, string authType) + public NetworkCredential? GetCredential(Uri? uri, string authType) { if (uri == null) { @@ -36,10 +36,10 @@ namespace System.Net.Http uri.Equals(_httpsProxy) ? _httpsCred : null; } - public static HttpEnvironmentProxyCredentials TryCreate(Uri httpProxy, Uri httpsProxy) + public static HttpEnvironmentProxyCredentials? TryCreate(Uri? httpProxy, Uri? httpsProxy) { - NetworkCredential httpCred = null; - NetworkCredential httpsCred = null; + NetworkCredential? httpCred = null; + NetworkCredential? httpsCred = null; if (httpProxy != null) { @@ -59,7 +59,7 @@ namespace System.Net.Http /// /// Converts string containing user:password to NetworkCredential object /// - private static NetworkCredential GetCredentialsFromString(string value) + private static NetworkCredential? GetCredentialsFromString(string? value) { if (string.IsNullOrWhiteSpace(value)) { @@ -69,7 +69,7 @@ namespace System.Net.Http value = Uri.UnescapeDataString(value); string password = ""; - string domain = null; + string? domain = null; int idx = value.IndexOf(':'); if (idx != -1) { @@ -96,12 +96,12 @@ namespace System.Net.Http private const string EnvNoProxyUC = "NO_PROXY"; private const string EnvCGI = "GATEWAY_INTERFACE"; // Running in a CGI environment. - private readonly Uri _httpProxyUri; // String URI for HTTP requests - private readonly Uri _httpsProxyUri; // String URI for HTTPS requests - private readonly string[] _bypass = null; // list of domains not to proxy - private ICredentials _credentials; + private readonly Uri? _httpProxyUri; // String URI for HTTP requests + private readonly Uri? _httpsProxyUri; // String URI for HTTPS requests + private readonly string[]? _bypass = null; // list of domains not to proxy + private ICredentials? _credentials; - private HttpEnvironmentProxy(Uri httpProxy, Uri httpsProxy, string bypassList) + private HttpEnvironmentProxy(Uri? httpProxy, Uri? httpsProxy, string? bypassList) { _httpProxyUri = httpProxy; _httpsProxyUri = httpsProxy; @@ -133,7 +133,7 @@ namespace System.Net.Http /// it to Uri object. The string could contain URI fragment, IP address and port /// tuple or just IP address or name. It will return null if parsing fails. /// - private static Uri GetUriFromString(string value) + private static Uri? GetUriFromString(string? value) { if (string.IsNullOrEmpty(value)) { @@ -144,10 +144,10 @@ namespace System.Net.Http value = value.Substring(7); } - string user = null; - string password = null; + string? user = null; + string? password = null; ushort port = 80; - string host = null; + string host; // Check if there is authentication part with user and possibly password. // Curl accepts raw text and that may break URI parser. @@ -264,7 +264,7 @@ namespace System.Net.Http /// /// Gets the proxy URI. (iWebProxy interface) /// - public Uri GetProxy(Uri uri) + public Uri? GetProxy(Uri uri) { return HttpUtilities.IsSupportedNonSecureScheme(uri.Scheme) ? _httpProxyUri : _httpsProxyUri; } @@ -277,7 +277,7 @@ namespace System.Net.Http return GetProxy(uri) == null ? true : IsMatchInBypassList(uri); } - public ICredentials Credentials + public ICredentials? Credentials { get { diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpNoProxy.cs b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpNoProxy.cs index bc33faf..1189cfa 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpNoProxy.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpNoProxy.cs @@ -6,8 +6,8 @@ namespace System.Net.Http { internal sealed class HttpNoProxy : IWebProxy { - public ICredentials Credentials { get; set; } - public Uri GetProxy(Uri destination) => null; + public ICredentials? Credentials { get; set; } + public Uri? GetProxy(Uri destination) => null; public bool IsBypassed(Uri host) => true; } } diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpWindowsProxy.cs b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpWindowsProxy.cs index 3434641..277dd27 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpWindowsProxy.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpWindowsProxy.cs @@ -6,6 +6,7 @@ using System.Collections; using System.Collections.Concurrent; using System.Collections.Generic; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.IO.Compression; using System.Net.NetworkInformation; using System.Runtime.InteropServices; @@ -20,19 +21,19 @@ namespace System.Net.Http private readonly MultiProxy _insecureProxy; // URI of the http system proxy if set private readonly MultiProxy _secureProxy; // URI of the https system proxy if set private readonly FailedProxyCache _failedProxies = new FailedProxyCache(); - private readonly List _bypass; // list of domains not to proxy + private readonly List? _bypass; // list of domains not to proxy private readonly bool _bypassLocal = false; // we should bypass domain considered local - private readonly List _localIp; - private ICredentials _credentials; + private readonly List? _localIp; + private ICredentials? _credentials; private readonly WinInetProxyHelper _proxyHelper; - private SafeWinHttpHandle _sessionHandle; + private SafeWinHttpHandle? _sessionHandle; private bool _disposed; - public static bool TryCreate(out IWebProxy proxy) + public static bool TryCreate([NotNullWhen(true)] out IWebProxy? proxy) { // This will get basic proxy setting from system using existing // WinInetProxyHelper functions. If no proxy is enabled, it will return null. - SafeWinHttpHandle sessionHandle = null; + SafeWinHttpHandle? sessionHandle = null; proxy = null; WinInetProxyHelper proxyHelper = new WinInetProxyHelper(); @@ -63,7 +64,7 @@ namespace System.Net.Http return true; } - private HttpWindowsProxy(WinInetProxyHelper proxyHelper, SafeWinHttpHandle sessionHandle) + private HttpWindowsProxy(WinInetProxyHelper proxyHelper, SafeWinHttpHandle? sessionHandle) { _proxyHelper = proxyHelper; _sessionHandle = sessionHandle; @@ -79,7 +80,7 @@ namespace System.Net.Http { int idx = 0; int start = 0; - string tmp; + string? tmp; // Process bypass list for manual setting. // Initial list size is best guess based on string length assuming each entry is at least 5 characters on average. @@ -177,9 +178,9 @@ namespace System.Net.Http /// /// Gets the proxy URI. (IWebProxy interface) /// - public Uri GetProxy(Uri uri) + public Uri? GetProxy(Uri uri) { - GetMultiProxy(uri).ReadNext(out Uri proxyUri, out _); + GetMultiProxy(uri).ReadNext(out Uri? proxyUri, out _); return proxyUri; } @@ -209,7 +210,7 @@ namespace System.Net.Http { if (proxyInfo.Proxy != IntPtr.Zero) { - string proxyStr = Marshal.PtrToStringUni(proxyInfo.Proxy); + string proxyStr = Marshal.PtrToStringUni(proxyInfo.Proxy)!; return MultiProxy.CreateLazy(_failedProxies, proxyStr, IsSecureUri(uri)); } @@ -242,7 +243,7 @@ namespace System.Net.Http { if (_bypassLocal) { - IPAddress address = null; + IPAddress? address; if (uri.IsLoopback) { @@ -261,7 +262,7 @@ namespace System.Net.Http { // Host is valid IP address. // Check if it belongs to local system. - foreach (IPAddress a in _localIp) + foreach (IPAddress a in _localIp!) { if (a.Equals(address)) { @@ -317,7 +318,7 @@ namespace System.Net.Http return false; } - public ICredentials Credentials + public ICredentials? Credentials { get { @@ -330,6 +331,6 @@ namespace System.Net.Http } // Access function for unit tests. - internal List BypassList => _bypass; + internal List? BypassList => _bypass; } } diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/IHttpTrace.cs b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/IHttpTrace.cs index e98938f..4e86a82 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/IHttpTrace.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/IHttpTrace.cs @@ -8,6 +8,6 @@ namespace System.Net.Http { internal interface IHttpTrace { - void Trace(string message, [CallerMemberName] string memberName = null); + void Trace(string message, [CallerMemberName] string? memberName = null); } } diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/MacProxy.cs b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/MacProxy.cs index 881f9c4..135fe10 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/MacProxy.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/MacProxy.cs @@ -17,7 +17,7 @@ namespace System.Net.Http { internal sealed class MacProxy : IWebProxy { - public ICredentials Credentials { get; set; } + public ICredentials? Credentials { get; set; } private static Uri GetProxyUri(string scheme, CFProxy proxy) { @@ -31,9 +31,9 @@ namespace System.Net.Http return uriBuilder.Uri; } - public Uri ExecuteProxyAutoConfiguration(SafeCreateHandle cfurl, CFProxy proxy) + public Uri? ExecuteProxyAutoConfiguration(SafeCreateHandle cfurl, CFProxy proxy) { - Uri result = null; + Uri? result = null; CFRunLoopRef runLoop = CFRunLoopGetCurrent(); // Callback that will be called after executing the configuration script @@ -68,7 +68,7 @@ namespace System.Net.Http CFNetworkExecuteProxyAutoConfigurationURL(proxy.AutoConfigurationURL, cfurl, cb, ref clientContext) : CFNetworkExecuteProxyAutoConfigurationScript(proxy.AutoConfigurationJavaScript, cfurl, cb, ref clientContext); - using (var mode = CFStringCreateWithCString(typeof(MacProxy).FullName)) + using (var mode = CFStringCreateWithCString(typeof(MacProxy).FullName!)) { IntPtr modeHandle = mode.DangerousGetHandle(); CFRunLoopAddSource(runLoop, loopSource, modeHandle); @@ -81,7 +81,7 @@ namespace System.Net.Http return result; } - public Uri GetProxy(Uri targetUri) + public Uri? GetProxy(Uri targetUri) { using (SafeCFDictionaryHandle systemProxySettings = CFNetworkCopySystemProxySettings()) using (SafeCreateHandle cfurl = CFURLCreateWithString(targetUri.AbsoluteUri)) @@ -97,7 +97,7 @@ namespace System.Net.Http if (proxy.ProxyType == CFProxy.kCFProxyTypeAutoConfigurationURL || proxy.ProxyType == CFProxy.kCFProxyTypeAutoConfigurationJavaScript) { - Uri result = ExecuteProxyAutoConfiguration(cfurl, proxy); + Uri? result = ExecuteProxyAutoConfiguration(cfurl, proxy); if (result != null) return result; } @@ -117,7 +117,7 @@ namespace System.Net.Http if (targetUri == null) throw new ArgumentNullException(nameof(targetUri)); - Uri proxyUri = GetProxy(targetUri); + Uri? proxyUri = GetProxy(targetUri); return Equals(proxyUri, targetUri) || proxyUri == null; } } diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/MultiProxy.cs b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/MultiProxy.cs index 985e943..3ffc877 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/MultiProxy.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/MultiProxy.cs @@ -3,6 +3,7 @@ // See the LICENSE file in the project root for more information. using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; namespace System.Net.Http { @@ -12,16 +13,16 @@ namespace System.Net.Http internal struct MultiProxy { private static readonly char[] s_proxyDelimiters = { ';', ' ', '\n', '\r', '\t' }; - private readonly FailedProxyCache _failedProxyCache; - private readonly Uri[] _uris; - private readonly string _proxyConfig; + private readonly FailedProxyCache? _failedProxyCache; + private readonly Uri[]? _uris; + private readonly string? _proxyConfig; private readonly bool _secure; private int _currentIndex; - private Uri _currentUri; + private Uri? _currentUri; public static MultiProxy Empty => new MultiProxy(null, Array.Empty()); - private MultiProxy(FailedProxyCache failedProxyCache, Uri[] uris) + private MultiProxy(FailedProxyCache? failedProxyCache, Uri[] uris) { _failedProxyCache = failedProxyCache; _uris = uris; @@ -46,14 +47,14 @@ namespace System.Net.Http /// /// The WinHTTP proxy config to parse. /// If true, return proxies suitable for use with a secure connection. If false, return proxies suitable for an insecure connection. - public static MultiProxy Parse(FailedProxyCache failedProxyCache, string proxyConfig, bool secure) + public static MultiProxy Parse(FailedProxyCache failedProxyCache, string? proxyConfig, bool secure) { Debug.Assert(failedProxyCache != null); Uri[] uris = Array.Empty(); ReadOnlySpan span = proxyConfig; - while (TryParseProxyConfigPart(span, secure, out Uri uri, out int charactersConsumed)) + while (TryParseProxyConfigPart(span, secure, out Uri? uri, out int charactersConsumed)) { int idx = uris.Length; @@ -89,11 +90,12 @@ namespace System.Net.Http /// The next proxy to use for the request. /// If true, indicates there are no further proxies to read from the config. /// If there is a proxy available, true. Otherwise, false. - public bool ReadNext(out Uri uri, out bool isFinalProxy) + public bool ReadNext([NotNullWhen(true)] out Uri? uri, out bool isFinalProxy) { // Enumerating indicates the previous proxy has failed; mark it as such. if (_currentUri != null) { + Debug.Assert(_failedProxyCache != null); _failedProxyCache.SetProxyFailed(_currentUri); } @@ -105,11 +107,12 @@ namespace System.Net.Http } // If this is the first ReadNext() and all proxies are marked as failed, return the proxy that is closest to renewal. - Uri oldestFailedProxyUri = null; + Uri? oldestFailedProxyUri = null; long oldestFailedProxyTicks = long.MaxValue; do { + Debug.Assert(_failedProxyCache != null); long renewTicks = _failedProxyCache.GetProxyRenewTicks(uri); // Proxy hasn't failed recently, return for use. @@ -135,6 +138,7 @@ namespace System.Net.Http if (oldestFailedProxyUri != null) { + Debug.Assert(uri != null); _failedProxyCache.TryRenewProxy(uri, oldestFailedProxyTicks); return true; } @@ -146,7 +150,7 @@ namespace System.Net.Http /// /// Reads the next proxy URI from the MultiProxy, either via parsing a config string or from an array. /// - private bool ReadNextHelper(out Uri uri, out bool isFinalProxy) + private bool ReadNextHelper([NotNullWhen(true)] out Uri? uri, out bool isFinalProxy) { Debug.Assert(_uris != null || _proxyConfig != null, $"{nameof(ReadNext)} must not be called on a default-initialized {nameof(MultiProxy)}."); @@ -164,6 +168,7 @@ namespace System.Net.Http return true; } + Debug.Assert(_proxyConfig != null); if (_currentIndex < _proxyConfig.Length) { bool hasProxy = TryParseProxyConfigPart(_proxyConfig.AsSpan(_currentIndex), _secure, out uri, out int charactersConsumed); @@ -187,7 +192,7 @@ namespace System.Net.Http /// The strings are a semicolon or whitespace separated list, with each entry in the following format: /// ([<scheme>=][<scheme>"://"]<server>[":"<port>]) /// - private static bool TryParseProxyConfigPart(ReadOnlySpan proxyString, bool secure, out Uri uri, out int charactersConsumed) + private static bool TryParseProxyConfigPart(ReadOnlySpan proxyString, bool secure, [NotNullWhen(true)] out Uri? uri, out int charactersConsumed) { const int SECURE_FLAG = 1; const int INSECURE_FLAG = 2; diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/RawConnectionStream.cs b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/RawConnectionStream.cs index 05ec6f4..9d1184d 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/RawConnectionStream.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/RawConnectionStream.cs @@ -23,7 +23,7 @@ namespace System.Net.Http public override int Read(Span buffer) { - HttpConnection connection = _connection; + HttpConnection? connection = _connection; if (connection == null || buffer.Length == 0) { // Response body fully consumed or the caller didn't ask for any data @@ -45,7 +45,7 @@ namespace System.Net.Http { CancellationHelper.ThrowIfCancellationRequested(cancellationToken); - HttpConnection connection = _connection; + HttpConnection? connection = _connection; if (connection == null || buffer.Length == 0) { // Response body fully consumed or the caller didn't ask for any data @@ -97,7 +97,7 @@ namespace System.Net.Http return Task.FromCanceled(cancellationToken); } - HttpConnection connection = _connection; + HttpConnection? connection = _connection; if (connection == null) { // null if response body fully consumed @@ -154,7 +154,7 @@ namespace System.Net.Http public override void Write(ReadOnlySpan buffer) { - HttpConnection connection = _connection; + HttpConnection? connection = _connection; if (connection == null) { throw new IOException(SR.ObjectDisposed_StreamClosed); @@ -173,7 +173,7 @@ namespace System.Net.Http return new ValueTask(Task.FromCanceled(cancellationToken)); } - HttpConnection connection = _connection; + HttpConnection? connection = _connection; if (connection == null) { return new ValueTask(Task.FromException(ExceptionDispatchInfo.SetCurrentStackTrace(new IOException(SR.ObjectDisposed_StreamClosed)))); @@ -199,7 +199,7 @@ namespace System.Net.Http return Task.FromCanceled(cancellationToken); } - HttpConnection connection = _connection; + HttpConnection? connection = _connection; if (connection == null) { return Task.CompletedTask; diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/RedirectHandler.cs b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/RedirectHandler.cs index 06050c9..8917d85 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/RedirectHandler.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/RedirectHandler.cs @@ -33,7 +33,8 @@ namespace System.Net.Http HttpResponseMessage response = await _initialInnerHandler.SendAsync(request, cancellationToken).ConfigureAwait(false); uint redirectCount = 0; - Uri redirectUri; + Uri? redirectUri; + Debug.Assert(request.RequestUri != null); while ((redirectUri = GetUriForRedirect(request.RequestUri, response)) != null) { redirectCount++; @@ -86,7 +87,7 @@ namespace System.Net.Http return response; } - private Uri GetUriForRedirect(Uri requestUri, HttpResponseMessage response) + private Uri? GetUriForRedirect(Uri requestUri, HttpResponseMessage response) { switch (response.StatusCode) { @@ -102,7 +103,7 @@ namespace System.Net.Http return null; } - Uri location = response.Headers.Location; + Uri? location = response.Headers.Location; if (location == null) { return null; @@ -131,7 +132,7 @@ namespace System.Net.Http { if (NetEventSource.IsEnabled) { - TraceError($"Insecure https to http redirect from '{requestUri}' to '{location}' blocked.", response.RequestMessage.GetHashCode()); + TraceError($"Insecure https to http redirect from '{requestUri}' to '{location}' blocked.", response.RequestMessage!.GetHashCode()); } return null; @@ -165,10 +166,10 @@ namespace System.Net.Http base.Dispose(disposing); } - internal void Trace(string message, int requestId, [CallerMemberName] string memberName = null) => + internal void Trace(string message, int requestId, [CallerMemberName] string? memberName = null) => NetEventSource.Log.HandlerMessage(0, 0, requestId, memberName, ToString() + ": " + message); - internal void TraceError(string message, int requestId, [CallerMemberName] string memberName = null) => + internal void TraceError(string message, int requestId, [CallerMemberName] string? memberName = null) => NetEventSource.Log.HandlerMessageError(0, 0, requestId, memberName, ToString() + ": " + message); } } diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/SocketsHttpHandler.cs b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/SocketsHttpHandler.cs index 161d8b4..6d31471 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/SocketsHttpHandler.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/SocketsHttpHandler.cs @@ -6,13 +6,14 @@ using System.Collections.Generic; using System.Net.Security; using System.Threading; using System.Threading.Tasks; +using System.Diagnostics.CodeAnalysis; namespace System.Net.Http { public sealed class SocketsHttpHandler : HttpMessageHandler { private readonly HttpConnectionSettings _settings = new HttpConnectionSettings(); - private HttpMessageHandler _handler; + private HttpMessageHandler? _handler; private bool _disposed; private void CheckDisposed() @@ -72,7 +73,7 @@ namespace System.Net.Http } } - public IWebProxy Proxy + public IWebProxy? Proxy { get => _settings._proxy; set @@ -82,7 +83,7 @@ namespace System.Net.Http } } - public ICredentials DefaultProxyCredentials + public ICredentials? DefaultProxyCredentials { get => _settings._defaultProxyCredentials; set @@ -102,7 +103,7 @@ namespace System.Net.Http } } - public ICredentials Credentials + public ICredentials? Credentials { get => _settings._credentials; set @@ -198,6 +199,7 @@ namespace System.Net.Http } } + [AllowNull] public SslClientAuthenticationOptions SslOptions { get => _settings._sslOptions ?? (_settings._sslOptions = new SslClientAuthenticationOptions()); @@ -270,8 +272,8 @@ namespace System.Net.Http } } - public IDictionary Properties => - _settings._properties ?? (_settings._properties = new Dictionary()); + public IDictionary Properties => + _settings._properties ?? (_settings._properties = new Dictionary()); protected override void Dispose(bool disposing) { @@ -336,7 +338,7 @@ namespace System.Net.Http CheckDisposed(); HttpMessageHandler handler = _handler ?? SetupHandlerChain(); - Exception error = ValidateAndNormalizeRequest(request); + Exception? error = ValidateAndNormalizeRequest(request); if (error != null) { return Task.FromException(error); @@ -345,7 +347,7 @@ namespace System.Net.Http return handler.SendAsync(request, cancellationToken); } - private Exception ValidateAndNormalizeRequest(HttpRequestMessage request) + private Exception? ValidateAndNormalizeRequest(HttpRequestMessage request) { if (request.Version.Major == 0) { diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/SystemProxyInfo.OSX.cs b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/SystemProxyInfo.OSX.cs index ce164aa..dee627e 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/SystemProxyInfo.OSX.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/SystemProxyInfo.OSX.cs @@ -9,7 +9,7 @@ namespace System.Net.Http // On OSX we get default proxy configuration from either environment variables or the OSX system proxy. public static IWebProxy ConstructSystemProxy() { - return HttpEnvironmentProxy.TryCreate(out IWebProxy proxy) ? proxy : new MacProxy(); + return HttpEnvironmentProxy.TryCreate(out IWebProxy? proxy) ? proxy : new MacProxy(); } } } diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/SystemProxyInfo.Unix.cs b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/SystemProxyInfo.Unix.cs index bb9ec76..daa1220 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/SystemProxyInfo.Unix.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/SystemProxyInfo.Unix.cs @@ -11,7 +11,7 @@ namespace System.Net.Http // the "no proxy" object. public static IWebProxy ConstructSystemProxy() { - return HttpEnvironmentProxy.TryCreate(out IWebProxy proxy) ? proxy : new HttpNoProxy(); + return HttpEnvironmentProxy.TryCreate(out IWebProxy? proxy) ? proxy : new HttpNoProxy(); } } } diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/SystemProxyInfo.Windows.cs b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/SystemProxyInfo.Windows.cs index 68ae86b..e42cc46 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/SystemProxyInfo.Windows.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/SystemProxyInfo.Windows.cs @@ -9,7 +9,7 @@ namespace System.Net.Http // On Windows we get default proxy configuration from either environment variables or the Windows system proxy. public static IWebProxy ConstructSystemProxy() { - if (!HttpEnvironmentProxy.TryCreate(out IWebProxy proxy)) + if (!HttpEnvironmentProxy.TryCreate(out IWebProxy? proxy)) { HttpWindowsProxy.TryCreate(out proxy); } diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/StreamContent.cs b/src/libraries/System.Net.Http/src/System/Net/Http/StreamContent.cs index b0e6852..c4e4e80 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/StreamContent.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/StreamContent.cs @@ -11,7 +11,7 @@ namespace System.Net.Http { public class StreamContent : HttpContent { - private Stream _content; + private Stream _content = null!; // Initialized in helper private int _bufferSize; private bool _contentConsumed; private long _start; @@ -52,10 +52,10 @@ namespace System.Net.Http if (NetEventSource.IsEnabled) NetEventSource.Associate(this, content); } - protected override Task SerializeToStreamAsync(Stream stream, TransportContext context) => + protected override Task SerializeToStreamAsync(Stream stream, TransportContext? context) => SerializeToStreamAsyncCore(stream, default); - protected override Task SerializeToStreamAsync(Stream stream, TransportContext context, CancellationToken cancellationToken) => + protected override Task SerializeToStreamAsync(Stream stream, TransportContext? context, CancellationToken cancellationToken) => // Only skip the original protected virtual SerializeToStreamAsync if this // isn't a derived type that may have overridden the behavior. GetType() == typeof(StreamContent) ? SerializeToStreamAsyncCore(stream, cancellationToken) : @@ -102,7 +102,7 @@ namespace System.Net.Http return Task.FromResult(new ReadOnlyStream(_content)); } - internal override Stream TryCreateContentReadStream() => + internal override Stream? TryCreateContentReadStream() => GetType() == typeof(StreamContent) ? new ReadOnlyStream(_content) : // type check ensures we use possible derived type's CreateContentReadStreamAsync override null; diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/StringContent.cs b/src/libraries/System.Net.Http/src/System/Net/Http/StringContent.cs index 139f0a8..d19d8f2 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/StringContent.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/StringContent.cs @@ -19,12 +19,12 @@ namespace System.Net.Http { } - public StringContent(string content, Encoding encoding) + public StringContent(string content, Encoding? encoding) : this(content, encoding, null) { } - public StringContent(string content, Encoding encoding, string mediaType) + public StringContent(string content, Encoding? encoding, string? mediaType) : base(GetContentByteArray(content, encoding)) { // Initialize the 'Content-Type' header with information provided by parameters. @@ -37,7 +37,7 @@ namespace System.Net.Http // A StringContent is essentially a ByteArrayContent. We serialize the string into a byte-array in the // constructor using encoding information provided by the caller (if any). When this content is sent, the // Content-Length can be retrieved easily (length of the array). - private static byte[] GetContentByteArray(string content, Encoding encoding) + private static byte[] GetContentByteArray(string content, Encoding? encoding) { // In this case we treat 'null' strings different from string.Empty in order to be consistent with our // other *Content constructors: 'null' throws, empty values are allowed. @@ -54,13 +54,13 @@ namespace System.Net.Http return encoding.GetBytes(content); } - protected override Task SerializeToStreamAsync(Stream stream, TransportContext context, CancellationToken cancellationToken) => + protected override Task SerializeToStreamAsync(Stream stream, TransportContext? context, CancellationToken cancellationToken) => // Only skip the original protected virtual SerializeToStreamAsync if this // isn't a derived type that may have overridden the behavior. GetType() == typeof(StringContent) ? SerializeToStreamAsyncCore(stream, cancellationToken) : base.SerializeToStreamAsync(stream, context, cancellationToken); - internal override Stream TryCreateContentReadStream() => + internal override Stream? TryCreateContentReadStream() => GetType() == typeof(StringContent) ? CreateMemoryStreamForByteArray() : // type check ensures we use possible derived type's CreateContentReadStreamAsync override null; } diff --git a/src/libraries/System.Net.Http/tests/UnitTests/System.Net.Http.Unit.Tests.csproj b/src/libraries/System.Net.Http/tests/UnitTests/System.Net.Http.Unit.Tests.csproj index 1de59a3..6350fbf 100644 --- a/src/libraries/System.Net.Http/tests/UnitTests/System.Net.Http.Unit.Tests.csproj +++ b/src/libraries/System.Net.Http/tests/UnitTests/System.Net.Http.Unit.Tests.csproj @@ -4,6 +4,7 @@ true true $(NetCoreAppCurrent)-Windows_NT;$(NetCoreAppCurrent)-Unix;$(NetCoreAppCurrent)-OSX;$(NetCoreAppCurrent)-iOS + annotations -- 2.7.4