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 7ac85b3155bbc..82a8218338ca5 100644
--- a/src/libraries/Common/src/Interop/Windows/WinHttp/Interop.winhttp.cs
+++ b/src/libraries/Common/src/Interop/Windows/WinHttp/Interop.winhttp.cs
@@ -13,8 +13,8 @@ internal static partial class WinHttp
public static extern SafeWinHttpHandle WinHttpOpen(
IntPtr userAgent,
uint accessType,
- string proxyName,
- string proxyBypass, int flags);
+ string? proxyName,
+ string? proxyBypass, int flags);
[DllImport(Interop.Libraries.WinHttp, CharSet = CharSet.Unicode, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
@@ -33,7 +33,7 @@ public static extern SafeWinHttpHandle WinHttpOpenRequest(
SafeWinHttpHandle connectHandle,
string verb,
string objectName,
- string version,
+ string? version,
string referrer,
string acceptTypes,
uint flags);
@@ -161,8 +161,8 @@ public static extern bool WinHttpSetCredentials(
SafeWinHttpHandle requestHandle,
uint authTargets,
uint authScheme,
- string userName,
- string password,
+ string? userName,
+ string? password,
IntPtr reserved);
[DllImport(Interop.Libraries.WinHttp, CharSet = CharSet.Unicode, SetLastError = true)]
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 525d50608ff7d..99e54a8c729c9 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
@@ -10,8 +10,6 @@
SR.PlatformNotSupported_WinHttpHandler
-
- annotations
diff --git a/src/libraries/System.Net.Http.WinHttpHandler/src/System/Net/Http/WinHttpAuthHelper.cs b/src/libraries/System.Net.Http.WinHttpHandler/src/System/Net/Http/WinHttpAuthHelper.cs
index f659c9c2f07e2..b0b6d86c67541 100644
--- a/src/libraries/System.Net.Http.WinHttpHandler/src/System/Net/Http/WinHttpAuthHelper.cs
+++ b/src/libraries/System.Net.Http.WinHttpHandler/src/System/Net/Http/WinHttpAuthHelper.cs
@@ -2,7 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.
using System.Diagnostics;
-
+using System.Diagnostics.CodeAnalysis;
using SafeWinHttpHandle = Interop.WinHttp.SafeWinHttpHandle;
namespace System.Net.Http
@@ -14,7 +14,7 @@ internal sealed class WinHttpAuthHelper
// WINHTTP_AUTH_SCHEME_NTLM = 0x00000002;
// WINHTTP_AUTH_SCHEME_DIGEST = 0x00000008;
// WINHTTP_AUTH_SCHEME_NEGOTIATE = 0x00000010;
- private static readonly string[] s_authSchemeStringMapping =
+ private static readonly string?[] s_authSchemeStringMapping =
{
null,
"Basic",
@@ -54,6 +54,10 @@ public void CheckResponseForAuthentication(
uint supportedSchemes = 0;
uint firstSchemeIgnored = 0;
uint authTarget = 0;
+
+ Debug.Assert(state.RequestMessage != null);
+ Debug.Assert(state.RequestMessage.RequestUri != null);
+ Debug.Assert(state.RequestHandle != null);
Uri uri = state.RequestMessage.RequestUri;
state.RetryRequest = false;
@@ -121,7 +125,7 @@ public void CheckResponseForAuthentication(
state.LastStatusCode = statusCode;
// If we don't have any proxy credentials to try, then we end up with 407.
- ICredentials proxyCreds = state.Proxy == null ?
+ ICredentials? proxyCreds = state.Proxy == null ?
state.DefaultProxyCredentials :
state.Proxy.Credentials;
if (proxyCreds == null)
@@ -161,6 +165,7 @@ public void CheckResponseForAuthentication(
default:
if (state.PreAuthenticate && serverAuthScheme != 0)
{
+ Debug.Assert(state.ServerCredentials != null);
SaveServerCredentialsToCache(uri, serverAuthScheme, state.ServerCredentials);
}
break;
@@ -169,6 +174,10 @@ public void CheckResponseForAuthentication(
public void PreAuthenticateRequest(WinHttpRequestState state, uint proxyAuthScheme)
{
+ Debug.Assert(state.RequestHandle != null);
+ Debug.Assert(state.RequestMessage != null);
+ Debug.Assert(state.RequestMessage.RequestUri != null);
+
// Set proxy credentials if we have them.
// If a proxy authentication challenge was responded to, reset
// those credentials before each SendRequest, because the proxy
@@ -177,8 +186,9 @@ public void PreAuthenticateRequest(WinHttpRequestState state, uint proxyAuthSche
// 407-401-407-401- loop.
if (proxyAuthScheme != 0)
{
- ICredentials proxyCredentials;
- Uri proxyUri;
+ ICredentials? proxyCredentials;
+ Uri? proxyUri;
+
if (state.Proxy != null)
{
proxyCredentials = state.Proxy.Credentials;
@@ -190,6 +200,9 @@ public void PreAuthenticateRequest(WinHttpRequestState state, uint proxyAuthSche
proxyUri = state.RequestMessage.RequestUri;
}
+ Debug.Assert(proxyCredentials != null);
+ Debug.Assert(proxyUri != null);
+
SetWinHttpCredential(
state.RequestHandle,
proxyCredentials,
@@ -202,7 +215,7 @@ public void PreAuthenticateRequest(WinHttpRequestState state, uint proxyAuthSche
if (state.PreAuthenticate)
{
uint authScheme;
- NetworkCredential serverCredentials;
+ NetworkCredential? serverCredentials;
if (GetServerCredentialsFromCache(
state.RequestMessage.RequestUri,
out authScheme,
@@ -226,18 +239,18 @@ public void PreAuthenticateRequest(WinHttpRequestState state, uint proxyAuthSche
public bool GetServerCredentialsFromCache(
Uri uri,
out uint serverAuthScheme,
- out NetworkCredential serverCredentials)
+ [NotNullWhen(true)] out NetworkCredential? serverCredentials)
{
serverAuthScheme = 0;
serverCredentials = null;
- NetworkCredential cred = null;
+ NetworkCredential? cred = null;
lock (_credentialCacheLock)
{
foreach (uint authScheme in s_authSchemePriorityOrder)
{
- cred = _credentialCache.GetCredential(uri, s_authSchemeStringMapping[authScheme]);
+ cred = _credentialCache.GetCredential(uri, s_authSchemeStringMapping[authScheme]!);
if (cred != null)
{
serverAuthScheme = authScheme;
@@ -253,10 +266,10 @@ public bool GetServerCredentialsFromCache(
public void SaveServerCredentialsToCache(Uri uri, uint authScheme, ICredentials serverCredentials)
{
- string authType = s_authSchemeStringMapping[authScheme];
+ string? authType = s_authSchemeStringMapping[authScheme];
Debug.Assert(!string.IsNullOrEmpty(authType));
- NetworkCredential cred = serverCredentials.GetCredential(uri, authType);
+ NetworkCredential? cred = serverCredentials.GetCredential(uri, authType);
if (cred != null)
{
lock (_credentialCacheLock)
@@ -303,15 +316,17 @@ private bool SetWinHttpCredential(
uint authScheme,
uint authTarget)
{
- string userName;
- string password;
+ string? userName;
+ string? password;
Debug.Assert(credentials != null);
Debug.Assert(authScheme != 0);
Debug.Assert(authTarget == Interop.WinHttp.WINHTTP_AUTH_TARGET_PROXY ||
authTarget == Interop.WinHttp.WINHTTP_AUTH_TARGET_SERVER);
- NetworkCredential networkCredential = credentials.GetCredential(uri, s_authSchemeStringMapping[authScheme]);
+ string? authType = s_authSchemeStringMapping[authScheme];
+ Debug.Assert(!string.IsNullOrEmpty(authType));
+ NetworkCredential? networkCredential = credentials.GetCredential(uri, authType);
if (networkCredential == null)
{
@@ -367,7 +382,7 @@ private bool SetWinHttpCredential(
return true;
}
- private static uint ChooseAuthScheme(uint supportedSchemes, Uri uri, ICredentials credentials)
+ private static uint ChooseAuthScheme(uint supportedSchemes, Uri? uri, ICredentials? credentials)
{
if (credentials == null)
{
@@ -383,9 +398,11 @@ private static uint ChooseAuthScheme(uint supportedSchemes, Uri uri, ICredential
return 0;
}
+ Debug.Assert(uri != null);
+
foreach (uint authScheme in s_authSchemePriorityOrder)
{
- if ((supportedSchemes & authScheme) != 0 && credentials.GetCredential(uri, s_authSchemeStringMapping[authScheme]) != null)
+ if ((supportedSchemes & authScheme) != 0 && credentials.GetCredential(uri, s_authSchemeStringMapping[authScheme]!) != null)
{
return authScheme;
}
diff --git a/src/libraries/System.Net.Http.WinHttpHandler/src/System/Net/Http/WinHttpCertificateHelper.cs b/src/libraries/System.Net.Http.WinHttpHandler/src/System/Net/Http/WinHttpCertificateHelper.cs
index da4baadb35903..472116113faca 100644
--- a/src/libraries/System.Net.Http.WinHttpHandler/src/System/Net/Http/WinHttpCertificateHelper.cs
+++ b/src/libraries/System.Net.Http.WinHttpHandler/src/System/Net/Http/WinHttpCertificateHelper.cs
@@ -1,6 +1,7 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
+using System.Diagnostics;
using System.Net.Security;
using System.Runtime.InteropServices;
using System.Security.Cryptography;
@@ -20,7 +21,6 @@ public static void BuildChain(
out X509Chain chain,
out SslPolicyErrors sslPolicyErrors)
{
- chain = null;
sslPolicyErrors = SslPolicyErrors.None;
// Build the chain.
@@ -69,6 +69,8 @@ public static void BuildChain(
Interop.Crypt32.CertChainPolicyIgnoreFlags.CERT_CHAIN_POLICY_IGNORE_ALL &
~Interop.Crypt32.CertChainPolicyIgnoreFlags.CERT_CHAIN_POLICY_IGNORE_INVALID_NAME_FLAG;
+ Debug.Assert(chain.SafeHandle != null);
+
Interop.Crypt32.CERT_CHAIN_POLICY_STATUS status = default;
status.cbSize = (uint)sizeof(Interop.Crypt32.CERT_CHAIN_POLICY_STATUS);
if (Interop.Crypt32.CertVerifyCertificateChainPolicy(
diff --git a/src/libraries/System.Net.Http.WinHttpHandler/src/System/Net/Http/WinHttpChannelBinding.cs b/src/libraries/System.Net.Http.WinHttpHandler/src/System/Net/Http/WinHttpChannelBinding.cs
index 5e862724d0e7f..d011279e0ce54 100644
--- a/src/libraries/System.Net.Http.WinHttpHandler/src/System/Net/Http/WinHttpChannelBinding.cs
+++ b/src/libraries/System.Net.Http.WinHttpHandler/src/System/Net/Http/WinHttpChannelBinding.cs
@@ -13,7 +13,7 @@ namespace System.Net.Http
internal sealed class WinHttpChannelBinding : ChannelBinding
{
private int _size;
- private string _cachedToString;
+ private string? _cachedToString;
internal WinHttpChannelBinding(SafeWinHttpHandle requestHandle)
{
@@ -55,7 +55,7 @@ public override int Size
}
}
- public override string ToString()
+ public override string? ToString()
{
if (_cachedToString == null && !IsInvalid)
{
diff --git a/src/libraries/System.Net.Http.WinHttpHandler/src/System/Net/Http/WinHttpCookieContainerAdapter.cs b/src/libraries/System.Net.Http.WinHttpHandler/src/System/Net/Http/WinHttpCookieContainerAdapter.cs
index ff0ac8798aeed..739995f5e732c 100644
--- a/src/libraries/System.Net.Http.WinHttpHandler/src/System/Net/Http/WinHttpCookieContainerAdapter.cs
+++ b/src/libraries/System.Net.Http.WinHttpHandler/src/System/Net/Http/WinHttpCookieContainerAdapter.cs
@@ -15,17 +15,21 @@ internal static class WinHttpCookieContainerAdapter
public static void AddResponseCookiesToContainer(WinHttpRequestState state)
{
- HttpRequestMessage request = state.RequestMessage;
- SafeWinHttpHandle requestHandle = state.RequestHandle;
- CookieContainer cookieContainer = state.Handler.CookieContainer;
+ HttpRequestMessage? request = state.RequestMessage;
+ SafeWinHttpHandle? requestHandle = state.RequestHandle;
+ Debug.Assert(state.Handler != null);
+ CookieContainer? cookieContainer = state.Handler.CookieContainer;
Debug.Assert(state.Handler.CookieUsePolicy == CookieUsePolicy.UseSpecifiedCookieContainer);
+ Debug.Assert(request != null);
+ Debug.Assert(requestHandle != null);
Debug.Assert(cookieContainer != null);
+ Debug.Assert(request.RequestUri != null);
// Get 'Set-Cookie' headers from response.
- char[] buffer = null;
+ char[]? buffer = null;
uint index = 0;
- string cookieHeader;
+ string? cookieHeader;
while (WinHttpResponseParser.GetResponseHeader(
requestHandle, Interop.WinHttp.WINHTTP_QUERY_SET_COOKIE, ref buffer, ref index, out cookieHeader))
{
@@ -44,9 +48,12 @@ public static void AddResponseCookiesToContainer(WinHttpRequestState state)
public static void ResetCookieRequestHeaders(WinHttpRequestState state, Uri redirectUri)
{
- SafeWinHttpHandle requestHandle = state.RequestHandle;
+ SafeWinHttpHandle? requestHandle = state.RequestHandle;
+ Debug.Assert(state.Handler != null);
Debug.Assert(state.Handler.CookieUsePolicy == CookieUsePolicy.UseSpecifiedCookieContainer);
+ Debug.Assert(state.Handler.CookieContainer != null);
+ Debug.Assert(requestHandle != null);
// Clear cookies.
if (!Interop.WinHttp.WinHttpAddRequestHeaders(
@@ -64,7 +71,7 @@ public static void ResetCookieRequestHeaders(WinHttpRequestState state, Uri redi
// Re-add cookies. The GetCookieHeader() method will return the correct set of
// cookies based on the redirectUri.
- string cookieHeader = GetCookieHeader(redirectUri, state.Handler.CookieContainer);
+ string? cookieHeader = GetCookieHeader(redirectUri, state.Handler.CookieContainer);
if (!string.IsNullOrEmpty(cookieHeader))
{
if (!Interop.WinHttp.WinHttpAddRequestHeaders(
@@ -78,9 +85,9 @@ public static void ResetCookieRequestHeaders(WinHttpRequestState state, Uri redi
}
}
- public static string GetCookieHeader(Uri uri, CookieContainer cookies)
+ public static string? GetCookieHeader(Uri uri, CookieContainer cookies)
{
- string cookieHeader = null;
+ string? cookieHeader = null;
Debug.Assert(cookies != null);
diff --git a/src/libraries/System.Net.Http.WinHttpHandler/src/System/Net/Http/WinHttpHandler.cs b/src/libraries/System.Net.Http.WinHttpHandler/src/System/Net/Http/WinHttpHandler.cs
index 63bd0aaf92f36..9ee9ef6110907 100644
--- a/src/libraries/System.Net.Http.WinHttpHandler/src/System/Net/Http/WinHttpHandler.cs
+++ b/src/libraries/System.Net.Http.WinHttpHandler/src/System/Net/Http/WinHttpHandler.cs
@@ -46,16 +46,16 @@ public class WinHttpHandler : HttpMessageHandler
private static readonly StringWithQualityHeaderValue s_deflateHeaderValue = new StringWithQualityHeaderValue("deflate");
[ThreadStatic]
- private static StringBuilder t_requestHeadersBuilder;
+ private static StringBuilder? t_requestHeadersBuilder;
private readonly object _lockObject = new object();
private bool _doManualDecompressionCheck;
- private WinInetProxyHelper _proxyHelper;
+ private WinInetProxyHelper? _proxyHelper;
private bool _automaticRedirection = HttpHandlerDefaults.DefaultAutomaticRedirection;
private int _maxAutomaticRedirections = HttpHandlerDefaults.DefaultMaxAutomaticRedirections;
private DecompressionMethods _automaticDecompression = HttpHandlerDefaults.DefaultAutomaticDecompression;
private CookieUsePolicy _cookieUsePolicy = CookieUsePolicy.UseInternalCookieStoreOnly;
- private CookieContainer _cookieContainer;
+ private CookieContainer? _cookieContainer;
private bool _enableMultipleHttp2Connections;
private SslProtocols _sslProtocols = SslProtocols.None; // Use most secure protocols available.
@@ -64,15 +64,15 @@ private Func<
X509Certificate2,
X509Chain,
SslPolicyErrors,
- bool> _serverCertificateValidationCallback;
+ bool>? _serverCertificateValidationCallback;
private bool _checkCertificateRevocationList;
private ClientCertificateOption _clientCertificateOption = ClientCertificateOption.Manual;
- private X509Certificate2Collection _clientCertificates; // Only create collection when required.
- private ICredentials _serverCredentials;
+ private X509Certificate2Collection? _clientCertificates; // Only create collection when required.
+ private ICredentials? _serverCredentials;
private bool _preAuthenticate;
private WindowsProxyUsePolicy _windowsProxyUsePolicy = WindowsProxyUsePolicy.UseWinHttpProxy;
- private ICredentials _defaultProxyCredentials;
- private IWebProxy _proxy;
+ private ICredentials? _defaultProxyCredentials;
+ private IWebProxy? _proxy;
private int _maxConnectionsPerServer = int.MaxValue;
private TimeSpan _sendTimeout = TimeSpan.FromSeconds(30);
private TimeSpan _receiveHeadersTimeout = TimeSpan.FromSeconds(30);
@@ -86,10 +86,10 @@ private Func<
private int _maxResponseHeadersLength = HttpHandlerDefaults.DefaultMaxResponseHeadersLength;
private int _maxResponseDrainSize = 64 * 1024;
- private IDictionary _properties; // Only create dictionary when required.
+ private IDictionary? _properties; // Only create dictionary when required.
private volatile bool _operationStarted;
private volatile bool _disposed;
- private SafeWinHttpHandle _sessionHandle;
+ private SafeWinHttpHandle? _sessionHandle;
private readonly WinHttpAuthHelper _authHelper = new WinHttpAuthHelper();
public WinHttpHandler()
@@ -617,8 +617,8 @@ protected override Task SendAsync(
Task.Factory.StartNew(s =>
{
- var whrs = (WinHttpRequestState)s;
- _ = whrs.Handler.StartRequestAsync(whrs);
+ var whrs = (WinHttpRequestState)s!;
+ _ = whrs.Handler!.StartRequestAsync(whrs);
},
state,
CancellationToken.None,
@@ -638,7 +638,7 @@ private static WinHttpChunkMode GetChunkedModeForSend(HttpRequestMessage request
chunkedMode = WinHttpChunkMode.Manual;
}
- HttpContent requestContent = requestMessage.Content;
+ HttpContent? requestContent = requestMessage.Content;
if (requestContent != null)
{
if (requestContent.Headers.ContentLength.HasValue)
@@ -686,12 +686,14 @@ private static WinHttpChunkMode GetChunkedModeForSend(HttpRequestMessage request
private static void AddRequestHeaders(
SafeWinHttpHandle requestHandle,
HttpRequestMessage requestMessage,
- CookieContainer cookies,
+ CookieContainer? cookies,
DecompressionMethods manuallyProcessedDecompressionMethods)
{
+ Debug.Assert(requestMessage.RequestUri != null);
+
// Get a StringBuilder to use for creating the request headers.
// We cache one in TLS to avoid creating a new one for each request.
- StringBuilder requestHeadersBuffer = t_requestHeadersBuilder;
+ StringBuilder? requestHeadersBuffer = t_requestHeadersBuilder;
if (requestHeadersBuffer != null)
{
requestHeadersBuffer.Clear();
@@ -724,7 +726,7 @@ private static void AddRequestHeaders(
// Manually add cookies.
if (cookies != null && cookies.Count > 0)
{
- string cookieHeader = WinHttpCookieContainerAdapter.GetCookieHeader(requestMessage.RequestUri, cookies);
+ string? cookieHeader = WinHttpCookieContainerAdapter.GetCookieHeader(requestMessage.RequestUri, cookies);
if (!string.IsNullOrEmpty(cookieHeader))
{
requestHeadersBuffer.AppendLine(cookieHeader);
@@ -778,6 +780,8 @@ private void EnsureSessionHandleExists(WinHttpRequestState state)
if (state.WindowsProxyUsePolicy == WindowsProxyUsePolicy.UseCustomProxy)
{
Debug.Assert(state.Proxy != null);
+ Debug.Assert(state.RequestMessage != null);
+ Debug.Assert(state.RequestMessage.RequestUri != null);
try
{
state.Proxy.GetProxy(state.RequestMessage.RequestUri);
@@ -867,6 +871,11 @@ private void EnsureSessionHandleExists(WinHttpRequestState state)
private async Task StartRequestAsync(WinHttpRequestState state)
{
+ Debug.Assert(state.RequestMessage != null);
+ Debug.Assert(state.RequestMessage.RequestUri != null);
+ Debug.Assert(state.Handler != null);
+ Debug.Assert(state.Tcs != null);
+
if (state.CancellationToken.IsCancellationRequested)
{
state.Tcs.TrySetCanceled(state.CancellationToken);
@@ -874,11 +883,12 @@ private async Task StartRequestAsync(WinHttpRequestState state)
return;
}
- Task sendRequestBodyTask = null;
- SafeWinHttpHandle connectHandle = null;
+ Task? sendRequestBodyTask = null;
+ SafeWinHttpHandle? connectHandle = null;
try
{
EnsureSessionHandleExists(state);
+ Debug.Assert(_sessionHandle != null);
SetEnableHttp2PlusClientCertificate(state.RequestMessage.RequestUri, state.RequestMessage.Version);
@@ -893,7 +903,7 @@ private async Task StartRequestAsync(WinHttpRequestState state)
// Try to use the requested version if a known/supported version was explicitly requested.
// Otherwise, we simply use winhttp's default.
- string httpVersion = null;
+ string? httpVersion = null;
if (state.RequestMessage.Version == HttpVersion.Version10)
{
httpVersion = "HTTP/1.0";
@@ -929,7 +939,7 @@ private async Task StartRequestAsync(WinHttpRequestState state)
// will have the side-effect of WinHTTP cancelling any pending I/O and accelerating its callbacks
// on the handle and thus releasing the awaiting tasks in the loop below. This helps to provide
// a more timely, cooperative, cancellation pattern.
- using (state.CancellationToken.Register(s => ((WinHttpRequestState)s).RequestHandle.Dispose(), state))
+ using (state.CancellationToken.Register(s => ((WinHttpRequestState)s!).RequestHandle!.Dispose(), state))
{
do
{
@@ -1031,8 +1041,10 @@ private async Task StartRequestAsync(WinHttpRequestState state)
}
}
- private void OpenRequestHandle(WinHttpRequestState state, SafeWinHttpHandle connectHandle, string httpVersion, out WinHttpChunkMode chunkedModeForSend, out SafeWinHttpHandle requestHandle)
+ private void OpenRequestHandle(WinHttpRequestState state, SafeWinHttpHandle connectHandle, string? httpVersion, out WinHttpChunkMode chunkedModeForSend, out SafeWinHttpHandle requestHandle)
{
+ Debug.Assert(state.RequestMessage != null);
+ Debug.Assert(state.RequestMessage.RequestUri != null);
chunkedModeForSend = GetChunkedModeForSend(state.RequestMessage);
// Create an HTTP request handle.
@@ -1079,7 +1091,7 @@ static uint GetRequestFlags(WinHttpRequestState state, WinHttpChunkMode chunkedM
// .NET Framework behavior. System.Uri establishes the baseline rules for percent-encoding
// of reserved characters.
uint flags = Interop.WinHttp.WINHTTP_FLAG_ESCAPE_DISABLE;
- if (state.RequestMessage.RequestUri.Scheme == UriScheme.Https)
+ if (state.RequestMessage!.RequestUri!.Scheme == UriScheme.Https)
{
flags |= Interop.WinHttp.WINHTTP_FLAG_SECURE;
}
@@ -1193,6 +1205,10 @@ private void SetSessionHandleTimeoutOptions(SafeWinHttpHandle sessionHandle)
private void SetRequestHandleOptions(WinHttpRequestState state)
{
+ Debug.Assert(state.RequestHandle != null);
+ Debug.Assert(state.RequestMessage != null);
+ Debug.Assert(state.RequestMessage.RequestUri != null);
+
SetRequestHandleProxyOptions(state);
SetRequestHandleDecompressionOptions(state.RequestHandle);
SetRequestHandleRedirectionOptions(state.RequestHandle);
@@ -1206,6 +1222,10 @@ private void SetRequestHandleOptions(WinHttpRequestState state)
private void SetRequestHandleProxyOptions(WinHttpRequestState state)
{
+ Debug.Assert(state.RequestMessage != null);
+ Debug.Assert(state.RequestMessage.RequestUri != null);
+ Debug.Assert(state.RequestHandle != null);
+
// We've already set the proxy on the session handle if we're using no proxy or default proxy settings.
// We only need to change it on the request handle if we have a specific IWebProxy or need to manually
// implement Wininet-style auto proxy detection.
@@ -1222,14 +1242,15 @@ private void SetRequestHandleProxyOptions(WinHttpRequestState state)
{
Debug.Assert(state.WindowsProxyUsePolicy == WindowsProxyUsePolicy.UseCustomProxy);
updateProxySettings = true;
- if (state.Proxy.IsBypassed(uri))
+
+ Uri? proxyUri = state.Proxy.IsBypassed(uri) ? null : state.Proxy.GetProxy(uri);
+ if (proxyUri == null)
{
proxyInfo.AccessType = Interop.WinHttp.WINHTTP_ACCESS_TYPE_NO_PROXY;
}
else
{
proxyInfo.AccessType = Interop.WinHttp.WINHTTP_ACCESS_TYPE_NAMED_PROXY;
- Uri proxyUri = state.Proxy.GetProxy(uri);
string proxyString = proxyUri.Scheme + "://" + proxyUri.Authority;
proxyInfo.Proxy = Marshal.StringToHGlobalUni(proxyString);
}
@@ -1362,7 +1383,7 @@ private void SetRequestHandleClientCertificateOptions(SafeWinHttpHandle requestH
return;
}
- X509Certificate2 clientCertificate = null;
+ X509Certificate2? clientCertificate = null;
if (_clientCertificateOption == ClientCertificateOption.Manual)
{
clientCertificate = CertificateHelper.GetEligibleClientCertificate(ClientCertificates);
@@ -1388,6 +1409,8 @@ private void SetRequestHandleClientCertificateOptions(SafeWinHttpHandle requestH
private void SetEnableHttp2PlusClientCertificate(Uri requestUri, Version requestVersion)
{
+ Debug.Assert(_sessionHandle != null);
+
if (requestUri.Scheme != UriScheme.Https || requestVersion != HttpVersion20)
{
return;
@@ -1436,6 +1459,7 @@ internal static void SetNoClientCertificate(SafeWinHttpHandle requestHandle)
private void SetRequestHandleCredentialsOptions(WinHttpRequestState state)
{
+ Debug.Assert(state.RequestHandle != null);
// By default, WinHTTP sets the default credentials policy such that it automatically sends default credentials
// (current user's logged on Windows credentials) to a proxy when needed (407 response). It only sends
// default credentials to a server (401 response) if the server is considered to be on the Intranet.
@@ -1506,6 +1530,7 @@ private static void SetWinHttpOption(
private void HandleAsyncException(WinHttpRequestState state, Exception ex)
{
+ Debug.Assert(state.Tcs != null);
if (state.CancellationToken.IsCancellationRequested)
{
// If the exception was due to the cancellation token being canceled, throw cancellation exception.
@@ -1597,6 +1622,8 @@ private RendezvousAwaitable InternalSendRequestAsync(WinHttpRequestState st
{
lock (state.Lock)
{
+ Debug.Assert(state.RequestHandle != null);
+
state.Pin();
if (!Interop.WinHttp.WinHttpSendRequest(
state.RequestHandle,
@@ -1622,6 +1649,9 @@ private RendezvousAwaitable InternalSendRequestAsync(WinHttpRequestState st
private async Task InternalSendRequestBodyAsync(WinHttpRequestState state, WinHttpChunkMode chunkedModeForSend)
{
+ Debug.Assert(state.RequestMessage != null);
+ Debug.Assert(state.RequestMessage.Content != null);
+
using (var requestStream = new WinHttpRequestStream(state, chunkedModeForSend))
{
await state.RequestMessage.Content.CopyToAsync(requestStream, state.TransportContext).ConfigureAwait(false);
@@ -1633,6 +1663,8 @@ private RendezvousAwaitable InternalReceiveResponseHeadersAsync(WinHttpRequ
{
lock (state.Lock)
{
+ Debug.Assert(state.RequestHandle != null);
+
if (!Interop.WinHttp.WinHttpReceiveResponse(state.RequestHandle, IntPtr.Zero))
{
throw WinHttpException.CreateExceptionUsingLastError(nameof(Interop.WinHttp.WinHttpReceiveResponse));
diff --git a/src/libraries/System.Net.Http.WinHttpHandler/src/System/Net/Http/WinHttpRequestCallback.cs b/src/libraries/System.Net.Http.WinHttpHandler/src/System/Net/Http/WinHttpRequestCallback.cs
index 3b2212ec42aa7..f4a8f6eef82ec 100644
--- a/src/libraries/System.Net.Http.WinHttpHandler/src/System/Net/Http/WinHttpRequestCallback.cs
+++ b/src/libraries/System.Net.Http.WinHttpHandler/src/System/Net/Http/WinHttpRequestCallback.cs
@@ -40,7 +40,7 @@ public static void WinHttpCallback(
return;
}
- WinHttpRequestState state = WinHttpRequestState.FromIntPtr(context);
+ WinHttpRequestState? state = WinHttpRequestState.FromIntPtr(context);
Debug.Assert(state != null, "WinHttpCallback must have a non-null state object");
RequestCallback(handle, state, internetStatus, statusInformation, statusInformationLength);
@@ -84,8 +84,7 @@ private static void RequestCallback(
return;
case Interop.WinHttp.WINHTTP_CALLBACK_STATUS_REDIRECT:
- string redirectUriString = Marshal.PtrToStringUni(statusInformation);
- var redirectUri = new Uri(redirectUriString);
+ var redirectUri = new Uri(Marshal.PtrToStringUni(statusInformation)!);
OnRequestRedirect(state, redirectUri);
return;
@@ -192,6 +191,8 @@ private static void OnRequestReceiveResponseHeadersComplete(WinHttpRequestState
private static void OnRequestRedirect(WinHttpRequestState state, Uri redirectUri)
{
Debug.Assert(state != null, "OnRequestRedirect: state is null");
+ Debug.Assert(state.Handler != null, "OnRequestRedirect: state.Handler is null");
+ Debug.Assert(state.RequestMessage != null, "OnRequestRedirect: state.RequestMessage is null");
Debug.Assert(redirectUri != null, "OnRequestRedirect: redirectUri is null");
// If we're manually handling cookies, we need to reset them based on the new URI.
@@ -234,6 +235,8 @@ private static void OnRequestSendingRequest(WinHttpRequestState state)
{
Debug.Assert(state != null, "OnRequestSendingRequest: state is null");
Debug.Assert(state.RequestHandle != null, "OnRequestSendingRequest: state.RequestHandle is null");
+ Debug.Assert(state.RequestMessage != null, "OnRequestSendingRequest: state.RequestMessage is null");
+ Debug.Assert(state.RequestMessage.RequestUri != null, "OnRequestSendingRequest: state.RequestMessage.RequestUri is null");
if (state.RequestMessage.RequestUri.Scheme != UriScheme.Https)
{
@@ -280,7 +283,7 @@ private static void OnRequestSendingRequest(WinHttpRequestState state)
var serverCertificate = new X509Certificate2(certHandle);
Interop.Crypt32.CertFreeCertificateContext(certHandle);
- X509Chain chain = null;
+ X509Chain? chain = null;
SslPolicyErrors sslPolicyErrors;
bool result = false;
@@ -391,6 +394,7 @@ private static void OnRequestError(WinHttpRequestState state, Interop.WinHttp.WI
break;
case Interop.WinHttp.API_WRITE_DATA:
+ Debug.Assert(state.TcsInternalWriteDataToRequestStream != null);
if (asyncResult.dwError == Interop.WinHttp.ERROR_WINHTTP_OPERATION_CANCELLED)
{
if (NetEventSource.Log.IsEnabled()) NetEventSource.Error(state, "API_WRITE_DATA - ERROR_WINHTTP_OPERATION_CANCELLED");
@@ -414,7 +418,8 @@ private static void OnRequestError(WinHttpRequestState state, Interop.WinHttp.WI
private static void ResetAuthRequestHeaders(WinHttpRequestState state)
{
const string AuthHeaderNameWithColon = "Authorization:";
- SafeWinHttpHandle requestHandle = state.RequestHandle;
+ SafeWinHttpHandle? requestHandle = state.RequestHandle;
+ Debug.Assert(requestHandle != null);
// Clear auth headers.
if (!Interop.WinHttp.WinHttpAddRequestHeaders(
diff --git a/src/libraries/System.Net.Http.WinHttpHandler/src/System/Net/Http/WinHttpRequestState.cs b/src/libraries/System.Net.Http.WinHttpHandler/src/System/Net/Http/WinHttpRequestState.cs
index 93595b1d12af6..fca5fa8097770 100644
--- a/src/libraries/System.Net.Http.WinHttpHandler/src/System/Net/Http/WinHttpRequestState.cs
+++ b/src/libraries/System.Net.Http.WinHttpHandler/src/System/Net/Http/WinHttpRequestState.cs
@@ -3,6 +3,7 @@
using System;
using System.Diagnostics;
+using System.Diagnostics.CodeAnalysis;
using System.Net.Security;
using System.Runtime.InteropServices;
using System.Security.Cryptography.X509Certificates;
@@ -28,7 +29,7 @@ internal sealed class WinHttpRequestState : IDisposable
// A GCHandle for this operation object.
// This is owned by the callback and will be deallocated when the sessionHandle has been closed.
private GCHandle _operationHandle;
- private WinHttpTransportContext _transportContext;
+ private WinHttpTransportContext? _transportContext;
private volatile bool _disposed; // To detect redundant calls.
public WinHttpRequestState()
@@ -49,10 +50,10 @@ public void Pin()
}
}
- public static WinHttpRequestState FromIntPtr(IntPtr gcHandle)
+ public static WinHttpRequestState? FromIntPtr(IntPtr gcHandle)
{
GCHandle stateHandle = GCHandle.FromIntPtr(gcHandle);
- return (WinHttpRequestState)stateHandle.Target;
+ return (WinHttpRequestState?)stateHandle.Target;
}
public IntPtr ToIntPtr()
@@ -92,16 +93,16 @@ public void ClearSendRequestState()
}
}
- public TaskCompletionSource Tcs { get; set; }
+ public TaskCompletionSource? Tcs { get; set; }
public CancellationToken CancellationToken { get; set; }
- public HttpRequestMessage RequestMessage { get; set; }
+ public HttpRequestMessage? RequestMessage { get; set; }
- public WinHttpHandler Handler { get; set; }
+ public WinHttpHandler? Handler { get; set; }
- private SafeWinHttpHandle _requestHandle;
- public SafeWinHttpHandle RequestHandle
+ private SafeWinHttpHandle? _requestHandle;
+ public SafeWinHttpHandle? RequestHandle
{
get
{
@@ -120,12 +121,13 @@ public SafeWinHttpHandle RequestHandle
}
}
- public Exception SavedException { get; set; }
+ public Exception? SavedException { get; set; }
public bool CheckCertificateRevocationList { get; set; }
- public Func ServerCertificateValidationCallback { get; set; }
+ public Func? ServerCertificateValidationCallback { get; set; }
+ [AllowNull]
public WinHttpTransportContext TransportContext
{
get { return _transportContext ?? (_transportContext = new WinHttpTransportContext()); }
@@ -134,11 +136,11 @@ public WinHttpTransportContext TransportContext
public WindowsProxyUsePolicy WindowsProxyUsePolicy { get; set; }
- public IWebProxy Proxy { get; set; }
+ public IWebProxy? Proxy { get; set; }
- public ICredentials ServerCredentials { get; set; }
+ public ICredentials? ServerCredentials { get; set; }
- public ICredentials DefaultProxyCredentials { get; set; }
+ public ICredentials? DefaultProxyCredentials { get; set; }
public bool PreAuthenticate { get; set; }
@@ -147,7 +149,7 @@ public WinHttpTransportContext TransportContext
public bool RetryRequest { get; set; }
public RendezvousAwaitable LifecycleAwaitable { get; set; } = new RendezvousAwaitable();
- public TaskCompletionSource TcsInternalWriteDataToRequestStream { get; set; }
+ public TaskCompletionSource? TcsInternalWriteDataToRequestStream { get; set; }
public bool AsyncReadInProgress { get; set; }
// WinHttpResponseStream state.
diff --git a/src/libraries/System.Net.Http.WinHttpHandler/src/System/Net/Http/WinHttpRequestStream.cs b/src/libraries/System.Net.Http.WinHttpHandler/src/System/Net/Http/WinHttpRequestStream.cs
index 301e5a6a21fc8..5e79072f44ba8 100644
--- a/src/libraries/System.Net.Http.WinHttpHandler/src/System/Net/Http/WinHttpRequestStream.cs
+++ b/src/libraries/System.Net.Http.WinHttpHandler/src/System/Net/Http/WinHttpRequestStream.cs
@@ -33,6 +33,7 @@ internal WinHttpRequestStream(WinHttpRequestState state, WinHttpChunkMode chunke
// Take copy of handle from state.
// The state's request handle will be set to null once the response stream starts.
+ Debug.Assert(_state.RequestHandle != null);
_requestHandle = _state.RequestHandle;
}
diff --git a/src/libraries/System.Net.Http.WinHttpHandler/src/System/Net/Http/WinHttpResponseHeaderReader.cs b/src/libraries/System.Net.Http.WinHttpHandler/src/System/Net/Http/WinHttpResponseHeaderReader.cs
index 02ce3184f8fe4..f2e3292321ced 100644
--- a/src/libraries/System.Net.Http.WinHttpHandler/src/System/Net/Http/WinHttpResponseHeaderReader.cs
+++ b/src/libraries/System.Net.Http.WinHttpHandler/src/System/Net/Http/WinHttpResponseHeaderReader.cs
@@ -2,6 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.
using System.Diagnostics;
+using System.Diagnostics.CodeAnalysis;
namespace System.Net.Http
{
@@ -28,7 +29,7 @@ public WinHttpResponseHeaderReader(char[] buffer, int startIndex, int length)
/// Empty header lines are skipped, as are malformed header lines that are missing a colon character.
///
/// true if the next header was read successfully, or false if all characters have been read.
- public bool ReadHeader(out string name, out string value)
+ public bool ReadHeader([NotNullWhen(true)] out string? name, [NotNullWhen(true)] out string? value)
{
int startIndex;
int length;
diff --git a/src/libraries/System.Net.Http.WinHttpHandler/src/System/Net/Http/WinHttpResponseParser.cs b/src/libraries/System.Net.Http.WinHttpHandler/src/System/Net/Http/WinHttpResponseParser.cs
index 9f324ada27a0f..053091aadbbf8 100644
--- a/src/libraries/System.Net.Http.WinHttpHandler/src/System/Net/Http/WinHttpResponseParser.cs
+++ b/src/libraries/System.Net.Http.WinHttpHandler/src/System/Net/Http/WinHttpResponseParser.cs
@@ -3,6 +3,7 @@
using System.Buffers;
using System.Diagnostics;
+using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.IO.Compression;
using System.Net.Http.Headers;
@@ -21,8 +22,11 @@ public static HttpResponseMessage CreateResponseMessage(
WinHttpRequestState state,
DecompressionMethods manuallyProcessedDecompressionMethods)
{
- HttpRequestMessage request = state.RequestMessage;
- SafeWinHttpHandle requestHandle = state.RequestHandle;
+ HttpRequestMessage? request = state.RequestMessage;
+ SafeWinHttpHandle? requestHandle = state.RequestHandle;
+ Debug.Assert(request != null);
+ Debug.Assert(requestHandle != null);
+
var response = new HttpResponseMessage();
bool stripEncodingHeaders = false;
@@ -133,9 +137,9 @@ public static uint GetResponseHeaderNumberInfo(SafeWinHttpHandle requestHandle,
public static unsafe bool GetResponseHeader(
SafeWinHttpHandle requestHandle,
uint infoLevel,
- ref char[] buffer,
+ ref char[]? buffer,
ref uint index,
- out string headerValue)
+ [NotNullWhen(true)] out string? headerValue)
{
const int StackLimit = 128;
@@ -286,7 +290,7 @@ private static string GetReasonPhrase(HttpStatusCode statusCode, char[] buffer,
// If it's a known reason phrase, use the known reason phrase instead of allocating a new string.
- string knownReasonPhrase = HttpStatusDescription.Get(statusCode);
+ string? knownReasonPhrase = HttpStatusDescription.Get(statusCode);
return (knownReasonPhrase != null && knownReasonPhrase.AsSpan().SequenceEqual(buffer.AsSpan(0, bufferLength))) ?
knownReasonPhrase :
@@ -313,7 +317,7 @@ private static void ParseResponseHeaders(
reader.ReadLine();
// Parse the array of headers and split them between Content headers and Response headers.
- while (reader.ReadHeader(out string headerName, out string headerValue))
+ while (reader.ReadHeader(out string? headerName, out string? headerValue))
{
if (!responseHeaders.TryAddWithoutValidation(headerName, headerValue))
{
@@ -350,7 +354,7 @@ public static void ParseResponseTrailers(
var reader = new WinHttpResponseHeaderReader(buffer, 0, bufferLength);
// Parse the array of headers and split them between Content headers and Response headers.
- while (reader.ReadHeader(out string headerName, out string headerValue))
+ while (reader.ReadHeader(out string? headerName, out string? headerValue))
{
responseTrailers.TryAddWithoutValidation(headerName, headerValue);
}
diff --git a/src/libraries/System.Net.Http.WinHttpHandler/src/System/Net/Http/WinHttpResponseStream.cs b/src/libraries/System.Net.Http.WinHttpHandler/src/System/Net/Http/WinHttpResponseStream.cs
index d7432541b94b9..74f0abbbb8050 100644
--- a/src/libraries/System.Net.Http.WinHttpHandler/src/System/Net/Http/WinHttpResponseStream.cs
+++ b/src/libraries/System.Net.Http.WinHttpHandler/src/System/Net/Http/WinHttpResponseStream.cs
@@ -113,7 +113,7 @@ public override Task CopyToAsync(Stream destination, int bufferSize, Cancellatio
private async Task CopyToAsyncCore(Stream destination, byte[] buffer, CancellationToken cancellationToken)
{
_state.PinReceiveBuffer(buffer);
- CancellationTokenRegistration ctr = cancellationToken.Register(s => ((WinHttpResponseStream)s).CancelPendingResponseStreamReadOperation(), this);
+ CancellationTokenRegistration ctr = cancellationToken.Register(s => ((WinHttpResponseStream)s!).CancelPendingResponseStreamReadOperation(), this);
_state.AsyncReadInProgress = true;
try
{
@@ -223,7 +223,7 @@ private async Task ReadAsyncCore(byte[] buffer, int offset, int count, Canc
}
_state.PinReceiveBuffer(buffer);
- var ctr = token.Register(s => ((WinHttpResponseStream)s).CancelPendingResponseStreamReadOperation(), this);
+ var ctr = token.Register(s => ((WinHttpResponseStream)s!).CancelPendingResponseStreamReadOperation(), this);
_state.AsyncReadInProgress = true;
try
{
@@ -330,7 +330,7 @@ protected override void Dispose(bool disposing)
if (_requestHandle != null)
{
_requestHandle.Dispose();
- _requestHandle = null;
+ _requestHandle = null!;
}
}
}
diff --git a/src/libraries/System.Net.Http.WinHttpHandler/src/System/Net/Http/WinHttpTraceHelper.cs b/src/libraries/System.Net.Http.WinHttpHandler/src/System/Net/Http/WinHttpTraceHelper.cs
index 104808b472a9f..2210d16138dea 100644
--- a/src/libraries/System.Net.Http.WinHttpHandler/src/System/Net/Http/WinHttpTraceHelper.cs
+++ b/src/libraries/System.Net.Http.WinHttpHandler/src/System/Net/Http/WinHttpTraceHelper.cs
@@ -9,7 +9,7 @@ namespace System.Net.Http
{
internal static class WinHttpTraceHelper
{
- public static void TraceCallbackStatus(object thisOrContextObject, IntPtr handle, IntPtr context, uint status, [CallerMemberName] string memberName = null)
+ public static void TraceCallbackStatus(object? thisOrContextObject, IntPtr handle, IntPtr context, uint status, [CallerMemberName] string? memberName = null)
{
Debug.Assert(NetEventSource.Log.IsEnabled());
@@ -19,7 +19,7 @@ public static void TraceCallbackStatus(object thisOrContextObject, IntPtr handle
memberName);
}
- public static void TraceAsyncError(object thisOrContextObject, Interop.WinHttp.WINHTTP_ASYNC_RESULT asyncResult, [CallerMemberName] string memberName = null)
+ public static void TraceAsyncError(object thisOrContextObject, Interop.WinHttp.WINHTTP_ASYNC_RESULT asyncResult, [CallerMemberName] string? memberName = null)
{
Debug.Assert(NetEventSource.Log.IsEnabled());
diff --git a/src/libraries/System.Net.Http.WinHttpHandler/src/System/Net/Http/WinHttpTransportContext.cs b/src/libraries/System.Net.Http.WinHttpHandler/src/System/Net/Http/WinHttpTransportContext.cs
index 1c3d5eea71799..ab8ee83c1a3e2 100644
--- a/src/libraries/System.Net.Http.WinHttpHandler/src/System/Net/Http/WinHttpTransportContext.cs
+++ b/src/libraries/System.Net.Http.WinHttpHandler/src/System/Net/Http/WinHttpTransportContext.cs
@@ -10,13 +10,13 @@ namespace System.Net.Http
{
internal sealed class WinHttpTransportContext : TransportContext
{
- private WinHttpChannelBinding _channelBinding;
+ private WinHttpChannelBinding? _channelBinding;
internal WinHttpTransportContext()
{
}
- public override ChannelBinding GetChannelBinding(ChannelBindingKind kind)
+ public override ChannelBinding? GetChannelBinding(ChannelBindingKind kind)
{
// WinHTTP only supports retrieval of ChannelBindingKind.Endpoint for CBT.
if (kind == ChannelBindingKind.Endpoint)