From d90735ef88d92da148607d59cc9ea2572b4cac70 Mon Sep 17 00:00:00 2001 From: campersau Date: Wed, 4 Mar 2026 19:38:14 +0100 Subject: [PATCH 1/2] Enable nullable --- .../Docker.DotNet.BasicAuth.csproj | 3 + .../Docker.DotNet.LegacyHttp.csproj | 3 + .../Docker.DotNet.NPipe.csproj | 3 + .../Docker.DotNet.NativeHttp.csproj | 3 + .../Docker.DotNet.Unix.csproj | 3 + .../CertificateCredentials.cs | 7 +- .../Docker.DotNet.X509.csproj | 3 + .../Models/ObjectExtensionData.cs | 2 +- src/Docker.DotNet/QueryString.cs | 2 +- .../BufferedReadStream.cs | 10 +-- .../HttpConnectionResponseContent.cs | 14 ++-- .../ManagedHandler.cs | 71 ++++++++++--------- .../Microsoft.Net.Http.Client.csproj | 3 + .../RequestExtensions.cs | 22 +++--- 14 files changed, 89 insertions(+), 60 deletions(-) diff --git a/src/Docker.DotNet.BasicAuth/Docker.DotNet.BasicAuth.csproj b/src/Docker.DotNet.BasicAuth/Docker.DotNet.BasicAuth.csproj index 4bfe41cf..8d5fde6a 100644 --- a/src/Docker.DotNet.BasicAuth/Docker.DotNet.BasicAuth.csproj +++ b/src/Docker.DotNet.BasicAuth/Docker.DotNet.BasicAuth.csproj @@ -4,6 +4,9 @@ Docker.DotNet.Enhanced.BasicAuth A Docker.DotNet extension that adds Basic Authentication for remote Docker Engine connections. + + enable + diff --git a/src/Docker.DotNet.LegacyHttp/Docker.DotNet.LegacyHttp.csproj b/src/Docker.DotNet.LegacyHttp/Docker.DotNet.LegacyHttp.csproj index 237dead7..c99394d1 100644 --- a/src/Docker.DotNet.LegacyHttp/Docker.DotNet.LegacyHttp.csproj +++ b/src/Docker.DotNet.LegacyHttp/Docker.DotNet.LegacyHttp.csproj @@ -4,6 +4,9 @@ Docker.DotNet.Enhanced.LegacyHttp A Docker.DotNet transport implementation for HTTP(S) Docker Engine connections. + + enable + true diff --git a/src/Docker.DotNet.NPipe/Docker.DotNet.NPipe.csproj b/src/Docker.DotNet.NPipe/Docker.DotNet.NPipe.csproj index 24a83d25..a50ff391 100644 --- a/src/Docker.DotNet.NPipe/Docker.DotNet.NPipe.csproj +++ b/src/Docker.DotNet.NPipe/Docker.DotNet.NPipe.csproj @@ -4,6 +4,9 @@ Docker.DotNet.Enhanced.NPipe A Docker.DotNet transport implementation for Windows named pipe (npipe) Docker Engine connections. + + enable + true diff --git a/src/Docker.DotNet.NativeHttp/Docker.DotNet.NativeHttp.csproj b/src/Docker.DotNet.NativeHttp/Docker.DotNet.NativeHttp.csproj index 84632d93..e93a7abd 100644 --- a/src/Docker.DotNet.NativeHttp/Docker.DotNet.NativeHttp.csproj +++ b/src/Docker.DotNet.NativeHttp/Docker.DotNet.NativeHttp.csproj @@ -4,6 +4,9 @@ Docker.DotNet.Enhanced.NativeHttp A Docker.DotNet transport implementation for HTTP(S) Docker Engine connections. + + enable + diff --git a/src/Docker.DotNet.Unix/Docker.DotNet.Unix.csproj b/src/Docker.DotNet.Unix/Docker.DotNet.Unix.csproj index 67570157..7a00243c 100644 --- a/src/Docker.DotNet.Unix/Docker.DotNet.Unix.csproj +++ b/src/Docker.DotNet.Unix/Docker.DotNet.Unix.csproj @@ -4,6 +4,9 @@ Docker.DotNet.Enhanced.Unix A Docker.DotNet transport implementation for Unix domain socket Docker Engine connections. + + enable + true diff --git a/src/Docker.DotNet.X509/CertificateCredentials.cs b/src/Docker.DotNet.X509/CertificateCredentials.cs index d72efbd8..9e4e09f5 100644 --- a/src/Docker.DotNet.X509/CertificateCredentials.cs +++ b/src/Docker.DotNet.X509/CertificateCredentials.cs @@ -11,7 +11,7 @@ public CertificateCredentials(X509Certificate2 certificate) public bool TlsEnabled => true; - public RemoteCertificateValidationCallback ServerCertificateValidationCallback { get; set; } + public RemoteCertificateValidationCallback? ServerCertificateValidationCallback { get; set; } public HttpMessageHandler ConfigureHandler(HttpMessageHandler handler) { @@ -35,7 +35,10 @@ public HttpMessageHandler ConfigureHandler(HttpMessageHandler handler) httpHandler.ClientCertificates.Add(_certificate); } - httpHandler.ServerCertificateCustomValidationCallback = (message, certificate, chain, sslPolicyErrors) => ServerCertificateValidationCallback(message, certificate, chain, sslPolicyErrors); + if (ServerCertificateValidationCallback is { } serverCertificateValidationCallback) + { + httpHandler.ServerCertificateCustomValidationCallback = (message, certificate, chain, sslPolicyErrors) => serverCertificateValidationCallback(message, certificate, chain, sslPolicyErrors); + } return httpHandler; } #endif diff --git a/src/Docker.DotNet.X509/Docker.DotNet.X509.csproj b/src/Docker.DotNet.X509/Docker.DotNet.X509.csproj index 940b24c6..53e592c8 100644 --- a/src/Docker.DotNet.X509/Docker.DotNet.X509.csproj +++ b/src/Docker.DotNet.X509/Docker.DotNet.X509.csproj @@ -4,6 +4,9 @@ Docker.DotNet.Enhanced.X509 A Docker.DotNet extension that adds X.509 client certificate authentication for remote Docker Engine connections. + + enable + true diff --git a/src/Docker.DotNet/Models/ObjectExtensionData.cs b/src/Docker.DotNet/Models/ObjectExtensionData.cs index 9ab55629..3933f08c 100644 --- a/src/Docker.DotNet/Models/ObjectExtensionData.cs +++ b/src/Docker.DotNet/Models/ObjectExtensionData.cs @@ -3,5 +3,5 @@ namespace Docker.DotNet.Models; public class ObjectExtensionData { [JsonExtensionData] - public IDictionary ExtensionData { get; set; } + public IDictionary? ExtensionData { get; set; } } \ No newline at end of file diff --git a/src/Docker.DotNet/QueryString.cs b/src/Docker.DotNet/QueryString.cs index b2a750a0..f7b6e72d 100644 --- a/src/Docker.DotNet/QueryString.cs +++ b/src/Docker.DotNet/QueryString.cs @@ -109,7 +109,7 @@ private Tuple[] FindAttributedPublicProperties(pi, pi.GetCustomAttribute())).ToArray(); } - private static bool IsDefaultOfType(object o) + private static bool IsDefaultOfType(object? o) { if (o is ValueType) { diff --git a/src/Microsoft.Net.Http.Client/BufferedReadStream.cs b/src/Microsoft.Net.Http.Client/BufferedReadStream.cs index 64357bb8..72c67968 100644 --- a/src/Microsoft.Net.Http.Client/BufferedReadStream.cs +++ b/src/Microsoft.Net.Http.Client/BufferedReadStream.cs @@ -4,7 +4,7 @@ internal sealed class BufferedReadStream : WriteClosableStream, IPeekableStream { private readonly Stream _inner; - private readonly Socket _socket; + private readonly Socket? _socket; private readonly byte[] _buffer; @@ -16,14 +16,14 @@ internal sealed class BufferedReadStream : WriteClosableStream, IPeekableStream private int _bufferCount; - private MemoryStream _readLineBuffer; + private MemoryStream? _readLineBuffer; - public BufferedReadStream(Stream inner, Socket socket, ILogger logger) + public BufferedReadStream(Stream inner, Socket? socket, ILogger logger) : this(inner, socket, 8192, logger) { } - public BufferedReadStream(Stream inner, Socket socket, int bufferLength, ILogger logger) + public BufferedReadStream(Stream inner, Socket? socket, int bufferLength, ILogger logger) { _inner = inner ?? throw new ArgumentNullException(nameof(inner)); _socket = socket; @@ -146,7 +146,7 @@ public bool Peek(byte[] buffer, uint toPeek, out uint peeked, out uint available throw new NotSupportedException("_inner stream isn't a peekable stream"); } - public async Task ReadLineAsync(CancellationToken cancellationToken) + public async Task ReadLineAsync(CancellationToken cancellationToken) { if (_readLineBuffer == null) { diff --git a/src/Microsoft.Net.Http.Client/HttpConnectionResponseContent.cs b/src/Microsoft.Net.Http.Client/HttpConnectionResponseContent.cs index 985e7f61..4fbaefc2 100644 --- a/src/Microsoft.Net.Http.Client/HttpConnectionResponseContent.cs +++ b/src/Microsoft.Net.Http.Client/HttpConnectionResponseContent.cs @@ -3,7 +3,7 @@ namespace Microsoft.Net.Http.Client; public class HttpConnectionResponseContent : HttpContent { private readonly HttpConnection _connection; - private Stream _responseStream; + private Stream? _responseStream; internal HttpConnectionResponseContent(HttpConnection connection) { @@ -40,21 +40,21 @@ public WriteClosableStream HijackStream() return _connection.Transport; } - protected override Task SerializeToStreamAsync(Stream stream, TransportContext context) + protected override Task SerializeToStreamAsync(Stream stream, TransportContext? context) { - return _responseStream.CopyToAsync(stream); + return _responseStream!.CopyToAsync(stream); } #if NET6_0_OR_GREATER - protected override Task SerializeToStreamAsync(Stream stream, TransportContext context, CancellationToken cancellationToken) + protected override Task SerializeToStreamAsync(Stream stream, TransportContext? context, CancellationToken cancellationToken) { - return _responseStream.CopyToAsync(stream, cancellationToken); + return _responseStream!.CopyToAsync(stream, cancellationToken); } #endif protected override Task CreateContentReadStreamAsync() { - return Task.FromResult(_responseStream); + return Task.FromResult(_responseStream!); } protected override bool TryComputeLength(out long length) @@ -69,7 +69,7 @@ protected override void Dispose(bool disposing) { if (disposing) { - _responseStream.Dispose(); + _responseStream?.Dispose(); _connection.Dispose(); } } diff --git a/src/Microsoft.Net.Http.Client/ManagedHandler.cs b/src/Microsoft.Net.Http.Client/ManagedHandler.cs index 17131920..cd0f87cb 100644 --- a/src/Microsoft.Net.Http.Client/ManagedHandler.cs +++ b/src/Microsoft.Net.Http.Client/ManagedHandler.cs @@ -4,11 +4,11 @@ public class ManagedHandler : HttpMessageHandler { private readonly ILogger _logger; - private readonly StreamOpener _streamOpener; + private readonly StreamOpener? _streamOpener; - private readonly SocketOpener _socketOpener; + private readonly SocketOpener? _socketOpener; - private IWebProxy _proxy; + private IWebProxy? _proxy; public delegate Task StreamOpener(string host, int port, CancellationToken cancellationToken); @@ -32,7 +32,7 @@ public ManagedHandler(SocketOpener opener, ILogger logger) _socketOpener = opener ?? throw new ArgumentNullException(nameof(opener)); } - public IWebProxy Proxy + public IWebProxy? Proxy { get { @@ -55,7 +55,7 @@ public IWebProxy Proxy public RedirectMode RedirectMode { get; set; } = RedirectMode.NoDowngrade; - public RemoteCertificateValidationCallback ServerCertificateValidationCallback { get; set; } + public RemoteCertificateValidationCallback? ServerCertificateValidationCallback { get; set; } public X509CertificateCollection ClientCertificates { get; set; } = new X509Certificate2Collection(); @@ -66,7 +66,7 @@ protected override async Task SendAsync(HttpRequestMessage throw new ArgumentNullException(nameof(httpRequestMessage)); } - HttpResponseMessage httpResponseMessage = null; + HttpResponseMessage? httpResponseMessage = null; for (var i = 0; i < MaxAutomaticRedirects; i++) { @@ -81,7 +81,7 @@ protected override async Task SendAsync(HttpRequestMessage } } - return httpResponseMessage; + return httpResponseMessage!; } private bool IsRedirectResponse(HttpRequestMessage request, HttpResponseMessage response) @@ -142,20 +142,24 @@ private async Task ProcessRequestAsync(HttpRequestMessage r request.Headers.ConnectionClose = !request.Headers.Contains("Connection"); // TODO: Connection reuse is not supported. ProxyMode proxyMode = DetermineProxyModeAndAddressLine(request); - Socket socket; + Socket? socket; Stream transport; try { if (_socketOpener != null) { - socket = await _socketOpener(request.GetConnectionHostProperty(), request.GetConnectionPortProperty().Value, cancellationToken).ConfigureAwait(false); + socket = await _socketOpener(request.GetConnectionHostProperty()!, request.GetConnectionPortProperty()!.Value, cancellationToken).ConfigureAwait(false); transport = new NetworkStream(socket, true); } - else + else if (_streamOpener != null) { socket = null; - transport = await _streamOpener(request.GetConnectionHostProperty(), request.GetConnectionPortProperty().Value, cancellationToken).ConfigureAwait(false); + transport = await _streamOpener(request.GetConnectionHostProperty()!, request.GetConnectionPortProperty()!.Value, cancellationToken).ConfigureAwait(false); + } + else + { + throw new Exception("Missing socketOpener or streamOpener"); } } catch (SocketException e) @@ -171,7 +175,7 @@ private async Task ProcessRequestAsync(HttpRequestMessage r if (request.IsHttps()) { SslStream sslStream = new SslStream(transport, false, ServerCertificateValidationCallback); - await sslStream.AuthenticateAsClientAsync(request.GetHostProperty(), ClientCertificates, SslProtocols.Tls12, false); + await sslStream.AuthenticateAsClientAsync(request.GetHostProperty()!, ClientCertificates, SslProtocols.Tls12, false); transport = sslStream; } @@ -183,10 +187,10 @@ private async Task ProcessRequestAsync(HttpRequestMessage r // Data comes from either the request.RequestUri or from the request.Properties private static void ProcessUrl(HttpRequestMessage request) { - string scheme = request.GetSchemeProperty(); + string? scheme = request.GetSchemeProperty(); if (string.IsNullOrWhiteSpace(scheme)) { - if (!request.RequestUri.IsAbsoluteUri) + if (!request.RequestUri!.IsAbsoluteUri) { throw new InvalidOperationException("Missing URL Scheme"); } @@ -196,13 +200,13 @@ private static void ProcessUrl(HttpRequestMessage request) if (!request.IsHttp() && !request.IsHttps()) { - throw new InvalidOperationException("Only HTTP or HTTPS are supported, not: " + request.RequestUri.Scheme); + throw new InvalidOperationException("Only HTTP or HTTPS are supported, not: " + request.RequestUri?.Scheme); } - string host = request.GetHostProperty(); + string? host = request.GetHostProperty(); if (string.IsNullOrWhiteSpace(host)) { - if (!request.RequestUri.IsAbsoluteUri) + if (!request.RequestUri!.IsAbsoluteUri) { throw new InvalidOperationException("Missing URL Scheme"); } @@ -210,7 +214,7 @@ private static void ProcessUrl(HttpRequestMessage request) request.SetHostProperty(host); } - string connectionHost = request.GetConnectionHostProperty(); + string? connectionHost = request.GetConnectionHostProperty(); if (string.IsNullOrWhiteSpace(connectionHost)) { request.SetConnectionHostProperty(host); @@ -219,7 +223,7 @@ private static void ProcessUrl(HttpRequestMessage request) int? port = request.GetPortProperty(); if (!port.HasValue) { - if (!request.RequestUri.IsAbsoluteUri) + if (!request.RequestUri!.IsAbsoluteUri) { throw new InvalidOperationException("Missing URL Scheme"); } @@ -233,10 +237,10 @@ private static void ProcessUrl(HttpRequestMessage request) request.SetConnectionPortProperty(port); } - string pathAndQuery = request.GetPathAndQueryProperty(); + string? pathAndQuery = request.GetPathAndQueryProperty(); if (string.IsNullOrWhiteSpace(pathAndQuery)) { - if (request.RequestUri.IsAbsoluteUri) + if (request.RequestUri!.IsAbsoluteUri) { pathAndQuery = request.RequestUri.PathAndQuery; } @@ -252,9 +256,9 @@ private static void ProcessHostHeader(HttpRequestMessage request) { if (string.IsNullOrWhiteSpace(request.Headers.Host)) { - string host = request.GetHostProperty(); - int port = request.GetPortProperty().Value; - if (host.Contains(':')) + string? host = request.GetHostProperty(); + int port = request.GetPortProperty()!.Value; + if (host?.Contains(':') == true) { // IPv6 host = '[' + host + ']'; @@ -266,11 +270,8 @@ private static void ProcessHostHeader(HttpRequestMessage request) private ProxyMode DetermineProxyModeAndAddressLine(HttpRequestMessage request) { - string scheme = request.GetSchemeProperty(); - string host = request.GetHostProperty(); - int? port = request.GetPortProperty(); - string pathAndQuery = request.GetPathAndQueryProperty(); - string addressLine = request.GetAddressLineProperty(); + string? pathAndQuery = request.GetPathAndQueryProperty(); + string? addressLine = request.GetAddressLineProperty(); if (string.IsNullOrEmpty(addressLine)) { @@ -279,7 +280,7 @@ private ProxyMode DetermineProxyModeAndAddressLine(HttpRequestMessage request) try { - if (!UseProxy || Proxy == null || Proxy.IsBypassed(request.RequestUri)) + if (!UseProxy || Proxy == null || Proxy.IsBypassed(request.RequestUri!)) { return ProxyMode.None; } @@ -289,7 +290,7 @@ private ProxyMode DetermineProxyModeAndAddressLine(HttpRequestMessage request) return ProxyMode.None; } - var proxyUri = Proxy.GetProxy(request.RequestUri); + var proxyUri = Proxy.GetProxy(request.RequestUri!); if (proxyUri == null) { return ProxyMode.None; @@ -299,7 +300,11 @@ private ProxyMode DetermineProxyModeAndAddressLine(HttpRequestMessage request) { if (string.IsNullOrEmpty(addressLine)) { - addressLine = scheme + "://" + host + ":" + port.Value + pathAndQuery; + string? scheme = request.GetSchemeProperty(); + string? host = request.GetHostProperty(); + int port = request.GetPortProperty()!.Value; + + addressLine = scheme + "://" + host + ":" + port.ToString(CultureInfo.InvariantCulture) + pathAndQuery; request.SetAddressLineProperty(addressLine); } request.SetConnectionHostProperty(proxyUri.DnsSafeHost); @@ -357,7 +362,7 @@ private async Task TunnelThroughProxyAsync(HttpRequestMessage request, Stream tr connectRequest.Headers.ProxyAuthorization = request.Headers.ProxyAuthorization; connectRequest.Method = new HttpMethod("CONNECT"); // TODO: IPv6 hosts - string authority = request.GetHostProperty() + ":" + request.GetPortProperty().Value; + string authority = request.GetHostProperty() + ":" + request.GetPortProperty()!.Value; connectRequest.SetAddressLineProperty(authority); connectRequest.Headers.Host = authority; diff --git a/src/Microsoft.Net.Http.Client/Microsoft.Net.Http.Client.csproj b/src/Microsoft.Net.Http.Client/Microsoft.Net.Http.Client.csproj index 86a18f11..648162b9 100644 --- a/src/Microsoft.Net.Http.Client/Microsoft.Net.Http.Client.csproj +++ b/src/Microsoft.Net.Http.Client/Microsoft.Net.Http.Client.csproj @@ -2,6 +2,9 @@ false + + enable + diff --git a/src/Microsoft.Net.Http.Client/RequestExtensions.cs b/src/Microsoft.Net.Http.Client/RequestExtensions.cs index 4c998bc3..c7872e17 100644 --- a/src/Microsoft.Net.Http.Client/RequestExtensions.cs +++ b/src/Microsoft.Net.Http.Client/RequestExtensions.cs @@ -12,22 +12,22 @@ public static bool IsHttps(this HttpRequestMessage request) return string.Equals("https", request.GetSchemeProperty(), StringComparison.OrdinalIgnoreCase); } - public static string GetSchemeProperty(this HttpRequestMessage request) + public static string? GetSchemeProperty(this HttpRequestMessage request) { return request.GetProperty("url.Scheme"); } - public static void SetSchemeProperty(this HttpRequestMessage request, string scheme) + public static void SetSchemeProperty(this HttpRequestMessage request, string? scheme) { request.SetProperty("url.Scheme", scheme); } - public static string GetHostProperty(this HttpRequestMessage request) + public static string? GetHostProperty(this HttpRequestMessage request) { return request.GetProperty("url.Host"); } - public static void SetHostProperty(this HttpRequestMessage request, string host) + public static void SetHostProperty(this HttpRequestMessage request, string? host) { request.SetProperty("url.Host", host); } @@ -42,12 +42,12 @@ public static void SetPortProperty(this HttpRequestMessage request, int? port) request.SetProperty("url.Port", port); } - public static string GetConnectionHostProperty(this HttpRequestMessage request) + public static string? GetConnectionHostProperty(this HttpRequestMessage request) { return request.GetProperty("url.ConnectionHost"); } - public static void SetConnectionHostProperty(this HttpRequestMessage request, string host) + public static void SetConnectionHostProperty(this HttpRequestMessage request, string? host) { request.SetProperty("url.ConnectionHost", host); } @@ -62,27 +62,27 @@ public static void SetConnectionPortProperty(this HttpRequestMessage request, in request.SetProperty("url.ConnectionPort", port); } - public static string GetPathAndQueryProperty(this HttpRequestMessage request) + public static string? GetPathAndQueryProperty(this HttpRequestMessage request) { return request.GetProperty("url.PathAndQuery"); } - public static void SetPathAndQueryProperty(this HttpRequestMessage request, string pathAndQuery) + public static void SetPathAndQueryProperty(this HttpRequestMessage request, string? pathAndQuery) { request.SetProperty("url.PathAndQuery", pathAndQuery); } - public static string GetAddressLineProperty(this HttpRequestMessage request) + public static string? GetAddressLineProperty(this HttpRequestMessage request) { return request.GetProperty("url.AddressLine"); } - public static void SetAddressLineProperty(this HttpRequestMessage request, string addressLine) + public static void SetAddressLineProperty(this HttpRequestMessage request, string? addressLine) { request.SetProperty("url.AddressLine", addressLine); } - public static T GetProperty(this HttpRequestMessage request, string key) + public static T? GetProperty(this HttpRequestMessage request, string key) { #if NET6_0_OR_GREATER return request.Options.TryGetValue(new HttpRequestOptionsKey(key), out var obj) ? obj : default; From 80fbfce0dac91adb4db38ed96881aec9274d1d02 Mon Sep 17 00:00:00 2001 From: campersau Date: Sat, 7 Mar 2026 20:18:20 +0100 Subject: [PATCH 2/2] move nullable to Directory.Build.props and fix all null warnings --- src/Directory.Build.props | 4 ++ .../Docker.DotNet.BasicAuth.csproj | 3 -- .../Docker.DotNet.Handler.Abstractions.csproj | 3 -- .../Docker.DotNet.LegacyHttp.csproj | 3 -- .../Docker.DotNet.NPipe.csproj | 3 -- .../Docker.DotNet.NativeHttp.csproj | 3 -- .../Docker.DotNet.Unix.csproj | 3 -- .../Docker.DotNet.X509.csproj | 3 -- src/Docker.DotNet/Docker.DotNet.csproj | 3 -- .../EnumerableQueryStringConverter.cs | 6 +-- src/Docker.DotNet/JsonEnumMemberConverter.cs | 2 +- src/Docker.DotNet/JsonSerializer.cs | 8 ++-- src/Docker.DotNet/QueryString.cs | 39 ++++++++++--------- .../HttpConnection.cs | 2 +- .../Microsoft.Net.Http.Client.csproj | 3 -- 15 files changed, 34 insertions(+), 54 deletions(-) diff --git a/src/Directory.Build.props b/src/Directory.Build.props index 00b70293..d944f19f 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -18,6 +18,10 @@ https://github.com/testcontainers/Docker.DotNet/raw/main/icon.png + + enable + + true diff --git a/src/Docker.DotNet.BasicAuth/Docker.DotNet.BasicAuth.csproj b/src/Docker.DotNet.BasicAuth/Docker.DotNet.BasicAuth.csproj index 8d5fde6a..4bfe41cf 100644 --- a/src/Docker.DotNet.BasicAuth/Docker.DotNet.BasicAuth.csproj +++ b/src/Docker.DotNet.BasicAuth/Docker.DotNet.BasicAuth.csproj @@ -4,9 +4,6 @@ Docker.DotNet.Enhanced.BasicAuth A Docker.DotNet extension that adds Basic Authentication for remote Docker Engine connections. - - enable - diff --git a/src/Docker.DotNet.Handler.Abstractions/Docker.DotNet.Handler.Abstractions.csproj b/src/Docker.DotNet.Handler.Abstractions/Docker.DotNet.Handler.Abstractions.csproj index ba251a6f..5ba5c828 100644 --- a/src/Docker.DotNet.Handler.Abstractions/Docker.DotNet.Handler.Abstractions.csproj +++ b/src/Docker.DotNet.Handler.Abstractions/Docker.DotNet.Handler.Abstractions.csproj @@ -4,9 +4,6 @@ Docker.DotNet.Enhanced.Handler.Abstractions An abstraction layer for Docker.DotNet that defines the classes and interfaces for implementing Docker Engine handlers. - - enable - diff --git a/src/Docker.DotNet.LegacyHttp/Docker.DotNet.LegacyHttp.csproj b/src/Docker.DotNet.LegacyHttp/Docker.DotNet.LegacyHttp.csproj index c99394d1..237dead7 100644 --- a/src/Docker.DotNet.LegacyHttp/Docker.DotNet.LegacyHttp.csproj +++ b/src/Docker.DotNet.LegacyHttp/Docker.DotNet.LegacyHttp.csproj @@ -4,9 +4,6 @@ Docker.DotNet.Enhanced.LegacyHttp A Docker.DotNet transport implementation for HTTP(S) Docker Engine connections. - - enable - true diff --git a/src/Docker.DotNet.NPipe/Docker.DotNet.NPipe.csproj b/src/Docker.DotNet.NPipe/Docker.DotNet.NPipe.csproj index a50ff391..24a83d25 100644 --- a/src/Docker.DotNet.NPipe/Docker.DotNet.NPipe.csproj +++ b/src/Docker.DotNet.NPipe/Docker.DotNet.NPipe.csproj @@ -4,9 +4,6 @@ Docker.DotNet.Enhanced.NPipe A Docker.DotNet transport implementation for Windows named pipe (npipe) Docker Engine connections. - - enable - true diff --git a/src/Docker.DotNet.NativeHttp/Docker.DotNet.NativeHttp.csproj b/src/Docker.DotNet.NativeHttp/Docker.DotNet.NativeHttp.csproj index e93a7abd..84632d93 100644 --- a/src/Docker.DotNet.NativeHttp/Docker.DotNet.NativeHttp.csproj +++ b/src/Docker.DotNet.NativeHttp/Docker.DotNet.NativeHttp.csproj @@ -4,9 +4,6 @@ Docker.DotNet.Enhanced.NativeHttp A Docker.DotNet transport implementation for HTTP(S) Docker Engine connections. - - enable - diff --git a/src/Docker.DotNet.Unix/Docker.DotNet.Unix.csproj b/src/Docker.DotNet.Unix/Docker.DotNet.Unix.csproj index 7a00243c..67570157 100644 --- a/src/Docker.DotNet.Unix/Docker.DotNet.Unix.csproj +++ b/src/Docker.DotNet.Unix/Docker.DotNet.Unix.csproj @@ -4,9 +4,6 @@ Docker.DotNet.Enhanced.Unix A Docker.DotNet transport implementation for Unix domain socket Docker Engine connections. - - enable - true diff --git a/src/Docker.DotNet.X509/Docker.DotNet.X509.csproj b/src/Docker.DotNet.X509/Docker.DotNet.X509.csproj index 53e592c8..940b24c6 100644 --- a/src/Docker.DotNet.X509/Docker.DotNet.X509.csproj +++ b/src/Docker.DotNet.X509/Docker.DotNet.X509.csproj @@ -4,9 +4,6 @@ Docker.DotNet.Enhanced.X509 A Docker.DotNet extension that adds X.509 client certificate authentication for remote Docker Engine connections. - - enable - true diff --git a/src/Docker.DotNet/Docker.DotNet.csproj b/src/Docker.DotNet/Docker.DotNet.csproj index dcc00047..da5c71ad 100644 --- a/src/Docker.DotNet/Docker.DotNet.csproj +++ b/src/Docker.DotNet/Docker.DotNet.csproj @@ -4,9 +4,6 @@ Docker.DotNet.Enhanced A .NET client for the Docker Engine API with fully asynchronous, non-blocking, object-oriented APIs. - - enable - diff --git a/src/Docker.DotNet/EnumerableQueryStringConverter.cs b/src/Docker.DotNet/EnumerableQueryStringConverter.cs index 262eb83f..1558ccd3 100644 --- a/src/Docker.DotNet/EnumerableQueryStringConverter.cs +++ b/src/Docker.DotNet/EnumerableQueryStringConverter.cs @@ -7,7 +7,7 @@ internal class EnumerableQueryStringConverter : IQueryStringConverter { public bool CanConvert(Type t) { - return typeof (IEnumerable).GetTypeInfo().IsAssignableFrom(t.GetTypeInfo()); + return typeof(IEnumerable).GetTypeInfo().IsAssignableFrom(t.GetTypeInfo()); } public string[] Convert(object o) @@ -16,12 +16,12 @@ public string[] Convert(object o) Debug.Assert(o is IEnumerable); var items = new List(); - foreach (var e in ((IEnumerable) o)) + foreach (var e in (IEnumerable)o!) { if (e is ValueType || e is string) { - items.Add(e.ToString()); + items.Add(e.ToString()!); } else { diff --git a/src/Docker.DotNet/JsonEnumMemberConverter.cs b/src/Docker.DotNet/JsonEnumMemberConverter.cs index 8b92af6e..0730ffe1 100644 --- a/src/Docker.DotNet/JsonEnumMemberConverter.cs +++ b/src/Docker.DotNet/JsonEnumMemberConverter.cs @@ -5,7 +5,7 @@ internal sealed class JsonEnumMemberConverter : JsonConverter wher private readonly Dictionary _enumFields = typeof(TEnum).GetFields(BindingFlags.Public | BindingFlags.Static) .Select(field => (Name: field.Name, Attribute: field.GetCustomAttribute())) .Where(item => item.Attribute != null && item.Attribute.Value != null) - .ToDictionary(item => item.Name, item => item.Attribute.Value); + .ToDictionary(item => item.Name, item => item.Attribute!.Value!); public override TEnum Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { diff --git a/src/Docker.DotNet/JsonSerializer.cs b/src/Docker.DotNet/JsonSerializer.cs index 30ca2c29..87e11f9b 100644 --- a/src/Docker.DotNet/JsonSerializer.cs +++ b/src/Docker.DotNet/JsonSerializer.cs @@ -48,12 +48,12 @@ public byte[] SerializeToUtf8Bytes(T value) public T Deserialize(byte[] json) { - return System.Text.Json.JsonSerializer.Deserialize(json, _options); + return System.Text.Json.JsonSerializer.Deserialize(json, _options)!; } public Task DeserializeAsync(HttpContent content, CancellationToken cancellationToken) { - return content.ReadFromJsonAsync(_options, cancellationToken); + return content.ReadFromJsonAsync(_options, cancellationToken)!; } public async IAsyncEnumerable DeserializeAsync(Stream stream, [EnumeratorCancellation] CancellationToken cancellationToken) @@ -69,7 +69,7 @@ public async IAsyncEnumerable DeserializeAsync(Stream stream, [EnumeratorC while (!buffer.IsEmpty && TryParseJson(ref buffer, out var jsonDocument)) { - yield return jsonDocument.Deserialize(_options); + yield return jsonDocument!.Deserialize(_options)!; } if (result.IsCompleted) @@ -83,7 +83,7 @@ public async IAsyncEnumerable DeserializeAsync(Stream stream, [EnumeratorC await reader.CompleteAsync(); } - private static bool TryParseJson(ref ReadOnlySequence buffer, out JsonDocument jsonDocument) + private static bool TryParseJson(ref ReadOnlySequence buffer, out JsonDocument? jsonDocument) { var reader = new Utf8JsonReader(buffer, isFinalBlock: false, default); diff --git a/src/Docker.DotNet/QueryString.cs b/src/Docker.DotNet/QueryString.cs index f7b6e72d..f13a4c45 100644 --- a/src/Docker.DotNet/QueryString.cs +++ b/src/Docker.DotNet/QueryString.cs @@ -4,7 +4,7 @@ internal class QueryString : IQueryString where T : class { private T Object { get; } - private Tuple[] AttributedPublicProperties { get; } + private Dictionary AttributedPublicProperties { get; } private IQueryStringConverterInstanceFactory QueryStringConverterInstanceFactory { get; } @@ -25,8 +25,8 @@ public IDictionary GetKeyValuePairs() var queryParameters = new Dictionary(); foreach (var pair in AttributedPublicProperties) { - var property = pair.Item1; - var attribute = pair.Item2; + var property = pair.Key; + var attribute = pair.Value; var value = property.GetValue(Object, null); // 'Required' check @@ -43,12 +43,12 @@ public IDictionary GetKeyValuePairs() string[] valueStr; if (attribute.ConverterType == null) { - valueStr = new[] { value.ToString() }; + valueStr = [value!.ToString()!]; } else { var converter = QueryStringConverterInstanceFactory.GetConverterInstance(attribute.ConverterType); - valueStr = ConvertValue(converter, value); + valueStr = ConvertValue(converter, value!); if (valueStr == null) { @@ -76,7 +76,7 @@ public string GetQueryString() v => $"{Uri.EscapeDataString(pair.Key)}={Uri.EscapeDataString(v)}")))); } - private string[] ConvertValue(IQueryStringConverter converter, object value) + private static string[] ConvertValue(IQueryStringConverter converter, object value) { if (!converter.CanConvert(value.GetType())) { @@ -86,27 +86,30 @@ private string[] ConvertValue(IQueryStringConverter converter, object value) return converter.Convert(value); } - private Tuple[] FindAttributedPublicProperties() where TAttribType : Attribute + private static Dictionary FindAttributedPublicProperties() where TAttribType : Attribute { var t = typeof(TValue); - var ofAttributeType = typeof(TAttribType); + Dictionary? attributedPublicProperties = null; - var properties = t.GetProperties(); - var publicProperties = properties.Where(p => p.GetGetMethod(false).IsPublic); - if (!publicProperties.Any()) + foreach (var prop in t.GetProperties()) { - throw new InvalidOperationException($"No public property getters found on type {t.FullName}."); + if (prop.GetGetMethod(false)?.IsPublic == true) + { + var attribute = prop.GetCustomAttribute(); + if (attribute != null) + { + attributedPublicProperties ??= new Dictionary(); + attributedPublicProperties.Add(prop, attribute); + } + } } - var attributedPublicProperties = properties.Where(p => p.GetCustomAttribute() != null).ToArray(); - if (!attributedPublicProperties.Any()) + if (attributedPublicProperties == null) { - throw new InvalidOperationException( - $"No public properties attributed with [{ofAttributeType.FullName}] found on type {t.FullName}."); + throw new InvalidOperationException($"No public properties attributed with [{typeof(TAttribType).FullName}] found on type {t.FullName}."); } - return attributedPublicProperties.Select(pi => - new Tuple(pi, pi.GetCustomAttribute())).ToArray(); + return attributedPublicProperties; } private static bool IsDefaultOfType(object? o) diff --git a/src/Microsoft.Net.Http.Client/HttpConnection.cs b/src/Microsoft.Net.Http.Client/HttpConnection.cs index fb8c1ab2..aec07719 100644 --- a/src/Microsoft.Net.Http.Client/HttpConnection.cs +++ b/src/Microsoft.Net.Http.Client/HttpConnection.cs @@ -126,7 +126,7 @@ private async Task> ReadResponseLinesAsync(CancellationToken cancel break; } - lines.Add(line); + lines.Add(line!); } while (true); diff --git a/src/Microsoft.Net.Http.Client/Microsoft.Net.Http.Client.csproj b/src/Microsoft.Net.Http.Client/Microsoft.Net.Http.Client.csproj index 648162b9..86a18f11 100644 --- a/src/Microsoft.Net.Http.Client/Microsoft.Net.Http.Client.csproj +++ b/src/Microsoft.Net.Http.Client/Microsoft.Net.Http.Client.csproj @@ -2,9 +2,6 @@ false - - enable -