From f3d346e15b8b8707e827d1e0d1f57e1263294524 Mon Sep 17 00:00:00 2001 From: CarloToso <105941898+CarloToso@users.noreply.github.com> Date: Thu, 16 Feb 2023 02:36:11 +0100 Subject: [PATCH 01/40] nullable comments WebRequestPSCmdlet --- .../Common/WebRequestPSCmdlet.Common.cs | 134 +++++++++--------- 1 file changed, 68 insertions(+), 66 deletions(-) diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs index 567a98ebfb9..179b4c7f919 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs @@ -25,6 +25,7 @@ namespace Microsoft.PowerShell.Commands { +#nullable enable /// /// The valid values for the -Authentication parameter for Invoke-RestMethod and Invoke-WebRequest. /// @@ -95,7 +96,7 @@ public abstract class WebRequestPSCmdlet : PSCmdlet /// /// Cancellation token source. /// - internal CancellationTokenSource _cancelToken = null; + internal CancellationTokenSource? _cancelToken = null; /// /// Automatically follow Rel Links. @@ -115,7 +116,7 @@ public abstract class WebRequestPSCmdlet : PSCmdlet /// /// Automatically follow Rel Links. /// - internal Dictionary _relationLink = null; + internal Dictionary? _relationLink = null; /// /// The current size of the local file being resumed. @@ -144,7 +145,7 @@ public abstract class WebRequestPSCmdlet : PSCmdlet /// [Parameter(Position = 0, Mandatory = true)] [ValidateNotNullOrEmpty] - public virtual Uri Uri { get; set; } + public virtual Uri? Uri { get; set; } #endregion URI @@ -156,7 +157,7 @@ public abstract class WebRequestPSCmdlet : PSCmdlet [Parameter] [ArgumentToVersionTransformation] [HttpVersionCompletions] - public virtual Version HttpVersion { get; set; } + public virtual Version? HttpVersion { get; set; } #endregion HTTP Version @@ -165,14 +166,14 @@ public abstract class WebRequestPSCmdlet : PSCmdlet /// Gets or sets the Session property. /// [Parameter] - public virtual WebRequestSession WebSession { get; set; } + public virtual WebRequestSession? WebSession { get; set; } /// /// Gets or sets the SessionVariable property. /// [Parameter] [Alias("SV")] - public virtual string SessionVariable { get; set; } + public virtual string? SessionVariable { get; set; } #endregion Session @@ -199,7 +200,7 @@ public abstract class WebRequestPSCmdlet : PSCmdlet /// [Parameter] [Credential] - public virtual PSCredential Credential { get; set; } + public virtual PSCredential? Credential { get; set; } /// /// Gets or sets the UseDefaultCredentials property. @@ -212,14 +213,14 @@ public abstract class WebRequestPSCmdlet : PSCmdlet /// [Parameter] [ValidateNotNullOrEmpty] - public virtual string CertificateThumbprint { get; set; } + public virtual string? CertificateThumbprint { get; set; } /// /// Gets or sets the Certificate property. /// [Parameter] [ValidateNotNull] - public virtual X509Certificate Certificate { get; set; } + public virtual X509Certificate? Certificate { get; set; } /// /// Gets or sets the SkipCertificateCheck property. @@ -237,7 +238,7 @@ public abstract class WebRequestPSCmdlet : PSCmdlet /// Gets or sets the Token property. Token is required by Authentication OAuth and Bearer. /// [Parameter] - public virtual SecureString Token { get; set; } + public virtual SecureString? Token { get; set; } #endregion Authorization and Credentials @@ -247,7 +248,7 @@ public abstract class WebRequestPSCmdlet : PSCmdlet /// Gets or sets the UserAgent property. /// [Parameter] - public virtual string UserAgent { get; set; } + public virtual string? UserAgent { get; set; } /// /// Gets or sets the DisableKeepAlive property. @@ -267,7 +268,7 @@ public abstract class WebRequestPSCmdlet : PSCmdlet /// [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")] [Parameter] - public virtual IDictionary Headers { get; set; } + public virtual IDictionary? Headers { get; set; } /// /// Gets or sets the SkipHeaderValidation property. @@ -342,14 +343,14 @@ public abstract class WebRequestPSCmdlet : PSCmdlet [Parameter(Mandatory = true, ParameterSetName = "CustomMethodNoProxy")] [Alias("CM")] [ValidateNotNullOrEmpty] - public virtual string CustomMethod + public virtual string? CustomMethod { get => _custommethod; - set => _custommethod = value.ToUpperInvariant(); + set => _custommethod = value!.ToUpperInvariant(); } - private string _custommethod; + private string? _custommethod; /// /// Gets or sets the PreserveHttpMethodOnRedirect property. @@ -377,7 +378,7 @@ public virtual string CustomMethod /// [Parameter(ParameterSetName = "StandardMethod")] [Parameter(ParameterSetName = "CustomMethod")] - public virtual Uri Proxy { get; set; } + public virtual Uri? Proxy { get; set; } /// /// Gets or sets the ProxyCredential property. @@ -385,7 +386,7 @@ public virtual string CustomMethod [Parameter(ParameterSetName = "StandardMethod")] [Parameter(ParameterSetName = "CustomMethod")] [Credential] - public virtual PSCredential ProxyCredential { get; set; } + public virtual PSCredential? ProxyCredential { get; set; } /// /// Gets or sets the ProxyUseDefaultCredentials property. @@ -402,7 +403,7 @@ public virtual string CustomMethod /// Gets or sets the Body property. /// [Parameter(ValueFromPipeline = true)] - public virtual object Body { get; set; } + public virtual object? Body { get; set; } /// /// Dictionary for use with RFC-7578 multipart/form-data submissions. @@ -410,32 +411,32 @@ public virtual string CustomMethod /// A value may be a collection of form values or single form value. /// [Parameter] - public virtual IDictionary Form { get; set; } + public virtual IDictionary? Form { get; set; } /// /// Gets or sets the ContentType property. /// [Parameter] - public virtual string ContentType { get; set; } + public virtual string? ContentType { get; set; } /// /// Gets or sets the TransferEncoding property. /// [Parameter] [ValidateSet("chunked", "compress", "deflate", "gzip", "identity", IgnoreCase = true)] - public virtual string TransferEncoding { get; set; } + public virtual string? TransferEncoding { get; set; } /// /// Gets or sets the InFile property. /// [Parameter] [ValidateNotNullOrEmpty] - public virtual string InFile { get; set; } + public virtual string? InFile { get; set; } /// /// Keep the original file path after the resolved provider path is assigned to InFile. /// - private string _originalFilePath; + private string? _originalFilePath; #endregion Input @@ -446,7 +447,7 @@ public virtual string CustomMethod /// [Parameter] [ValidateNotNullOrEmpty] - public virtual string OutFile { get; set; } + public virtual string? OutFile { get; set; } /// /// Gets or sets the PassThrough property. @@ -472,7 +473,7 @@ public virtual string CustomMethod #region Helper Properties - internal string QualifiedOutFile => QualifyFilePath(OutFile); + internal string QualifiedOutFile => QualifyFilePath(OutFile!); internal bool ShouldCheckHttpStatus => !SkipHttpErrorCheck; @@ -513,14 +514,14 @@ protected override void ProcessRecord() // If the request contains an authorization header and PreserveAuthorizationOnRedirect is not set, // it needs to be stripped on the first redirect. bool keepAuthorizationOnRedirect = PreserveAuthorizationOnRedirect.IsPresent - && WebSession.Headers.ContainsKey(HttpKnownHeaderNames.Authorization); + && WebSession!.Headers.ContainsKey(HttpKnownHeaderNames.Authorization); bool handleRedirect = keepAuthorizationOnRedirect || AllowInsecureRedirect || PreserveHttpMethodOnRedirect; using (HttpClient client = GetHttpClient(handleRedirect)) { int followedRelLink = 0; - Uri uri = Uri; + Uri uri = Uri!; do { if (followedRelLink > 0) @@ -538,7 +539,7 @@ protected override void ProcessRecord() FillRequestStream(request); try { - long requestContentLength = request.Content is null ? 0 : request.Content.Headers.ContentLength.Value; + long requestContentLength = request.Content is null ? 0 : request.Content.Headers.ContentLength!.Value; string reqVerboseMsg = string.Format( CultureInfo.CurrentCulture, @@ -566,7 +567,7 @@ protected override void ProcessRecord() // This happens when the local file is the same size as the remote file. if (Resume.IsPresent && response.StatusCode == HttpStatusCode.RequestedRangeNotSatisfiable - && response.Content.Headers.ContentRange.HasLength + && response.Content.Headers.ContentRange!.HasLength && response.Content.Headers.ContentRange.Length == _resumeFileSize) { _isSuccess = true; @@ -580,7 +581,7 @@ protected override void ProcessRecord() } // Detect insecure redirection - if (!AllowInsecureRedirect && response.RequestMessage.RequestUri.Scheme == "https" && response.Headers.Location?.Scheme == "http") + if (!AllowInsecureRedirect && response.RequestMessage?.RequestUri?.Scheme == "https" && response.Headers.Location?.Scheme == "http") { ErrorRecord er = new(new InvalidOperationException(), "InsecureRedirection", ErrorCategory.InvalidOperation, request); er.ErrorDetails = new ErrorDetails(WebCmdletStrings.InsecureRedirection); @@ -598,7 +599,7 @@ protected override void ProcessRecord() HttpResponseException httpEx = new(message, response); ErrorRecord er = new(httpEx, "WebCmdletWebResponseException", ErrorCategory.InvalidOperation, request); string detailMsg = string.Empty; - StreamReader reader = null; + StreamReader? reader = null; try { reader = new StreamReader(StreamHelper.GetResponseStream(response)); @@ -633,7 +634,7 @@ protected override void ProcessRecord() // Errors with redirection counts of greater than 0 are handled automatically by .NET, but are // impossible to detect programmatically when we hit this limit. By handling this ourselves // (and still writing out the result), users can debug actual HTTP redirect problems. - if (WebSession.MaximumRedirection == 0 && IsRedirectCode(response.StatusCode)) + if (WebSession!.MaximumRedirection == 0 && IsRedirectCode(response.StatusCode)) { ErrorRecord er = new(new InvalidOperationException(), "MaximumRedirectExceeded", ErrorCategory.InvalidOperation, request); er.ErrorDetails = new ErrorDetails(WebCmdletStrings.MaximumRedirectionCountExceeded); @@ -653,7 +654,7 @@ protected override void ProcessRecord() if (_followRelLink) { - if (!_relationLink.ContainsKey("next")) + if (!_relationLink!.ContainsKey("next")) { return; } @@ -721,7 +722,7 @@ internal virtual void ValidateParameters() ThrowTerminatingError(error); } - if (!AllowUnencryptedAuthentication && (Authentication != WebAuthenticationType.None || Credential is not null || UseDefaultCredentials) && Uri.Scheme != "https") + if (!AllowUnencryptedAuthentication && (Authentication != WebAuthenticationType.None || Credential is not null || UseDefaultCredentials) && Uri!.Scheme != "https") { ErrorRecord error = GetValidationError(WebCmdletStrings.AllowUnencryptedAuthenticationRequired, "WebCmdletAllowUnencryptedAuthenticationRequiredException"); ThrowTerminatingError(error); @@ -768,7 +769,7 @@ internal virtual void ValidateParameters() // Validate InFile path if (InFile is not null) { - ErrorRecord errorRecord = null; + ErrorRecord? errorRecord = null; try { @@ -923,7 +924,7 @@ internal virtual void PrepareSession() { foreach (string key in Headers.Keys) { - object value = Headers[key]; + object? value = Headers[key]; // null is not valid value for header. // We silently ignore header if value is null. @@ -947,7 +948,7 @@ internal virtual void PrepareSession() internal virtual HttpClient GetHttpClient(bool handleRedirect) { HttpClientHandler handler = new(); - handler.CookieContainer = WebSession.Cookies; + handler.CookieContainer = WebSession!.Cookies; handler.AutomaticDecompression = DecompressionMethods.All; // Set the credentials used by this request @@ -1015,7 +1016,7 @@ internal virtual HttpRequestMessage GetRequest(Uri uri) } // Pull in session data - if (WebSession.Headers.Count > 0) + if (WebSession!.Headers.Count > 0) { WebSession.ContentHeaders.Clear(); foreach (var entry in WebSession.Headers) @@ -1045,7 +1046,7 @@ internal virtual HttpRequestMessage GetRequest(Uri uri) } // Set 'User-Agent' if WebSession.Headers doesn't already contain it - if (WebSession.Headers.TryGetValue(HttpKnownHeaderNames.UserAgent, out string userAgent)) + if (WebSession.Headers.TryGetValue(HttpKnownHeaderNames.UserAgent, out string? userAgent)) { WebSession.UserAgent = userAgent; } @@ -1104,12 +1105,12 @@ internal virtual void FillRequestStream(HttpRequestMessage request) // Set the request content type if (ContentType is not null) { - WebSession.ContentHeaders[HttpKnownHeaderNames.ContentType] = ContentType; + WebSession!.ContentHeaders[HttpKnownHeaderNames.ContentType] = ContentType; } else if (request.Method == HttpMethod.Post) { // Win8:545310 Invoke-WebRequest does not properly set MIME type for POST - WebSession.ContentHeaders.TryGetValue(HttpKnownHeaderNames.ContentType, out string contentType); + WebSession!.ContentHeaders.TryGetValue(HttpKnownHeaderNames.ContentType, out string? contentType); if (string.IsNullOrEmpty(contentType)) { WebSession.ContentHeaders[HttpKnownHeaderNames.ContentType] = "application/x-www-form-urlencoded"; @@ -1122,7 +1123,7 @@ internal virtual void FillRequestStream(HttpRequestMessage request) foreach (DictionaryEntry formEntry in Form) { // AddMultipartContent will handle PSObject unwrapping, Object type determination and enumerateing top level IEnumerables. - AddMultipartContent(fieldName: formEntry.Key, fieldValue: formEntry.Value, formData: formData, enumerate: true); + AddMultipartContent(fieldName: formEntry.Key, fieldValue: formEntry.Value!, formData: formData, enumerate: true); } SetRequestContent(request, formData); @@ -1187,7 +1188,7 @@ internal virtual void FillRequestStream(HttpRequestMessage request) request.Content.Headers.Clear(); } - foreach (KeyValuePair entry in WebSession.ContentHeaders) + foreach (KeyValuePair entry in WebSession!.ContentHeaders) { if (!string.IsNullOrWhiteSpace(entry.Value)) { @@ -1218,14 +1219,14 @@ internal virtual HttpResponseMessage GetResponse(HttpClient client, HttpRequestM ArgumentNullException.ThrowIfNull(request); // Add 1 to account for the first request. - int totalRequests = WebSession.MaximumRetryCount + 1; + int totalRequests = WebSession!.MaximumRetryCount + 1; HttpRequestMessage currentRequest = request; - HttpResponseMessage response = null; + HttpResponseMessage? response = null; do { // Track the current URI being used by various requests and re-requests. - Uri currentUri = currentRequest.RequestUri; + Uri currentUri = currentRequest.RequestUri!; _cancelToken = new CancellationTokenSource(); response = client.SendAsync(currentRequest, HttpCompletionOption.ResponseHeadersRead, _cancelToken.Token).GetAwaiter().GetResult(); @@ -1251,7 +1252,7 @@ internal virtual HttpResponseMessage GetResponse(HttpClient client, HttpRequestM CustomMethod = string.Empty; } - currentUri = new Uri(request.RequestUri, response.Headers.Location); + currentUri = new Uri(request.RequestUri!, response.Headers.Location); // Continue to handle redirection using HttpRequestMessage redirectRequest = GetRequest(currentUri); @@ -1264,10 +1265,10 @@ internal virtual HttpResponseMessage GetResponse(HttpClient client, HttpRequestM // If the size of the remote file is the same as the local file, there is nothing to resume. if (Resume.IsPresent && response.StatusCode == HttpStatusCode.RequestedRangeNotSatisfiable - && (response.Content.Headers.ContentRange.HasLength + && (response.Content.Headers.ContentRange!.HasLength && response.Content.Headers.ContentRange.Length != _resumeFileSize)) { - _cancelToken.Cancel(); + _cancelToken?.Cancel(); WriteVerbose(WebCmdletStrings.WebMethodResumeFailedVerboseMsg); @@ -1279,7 +1280,7 @@ internal virtual HttpResponseMessage GetResponse(HttpClient client, HttpRequestM { FillRequestStream(requestWithoutRange); - long requestContentLength = requestWithoutRange.Content is null ? 0 : requestWithoutRange.Content.Headers.ContentLength.Value; + long requestContentLength = requestWithoutRange.Content is null ? 0 : requestWithoutRange.Content.Headers.ContentLength!.Value; string reqVerboseMsg = string.Format( CultureInfo.CurrentCulture, @@ -1304,7 +1305,7 @@ internal virtual HttpResponseMessage GetResponse(HttpClient client, HttpRequestM // If the status code is 429 get the retry interval from the Headers. // Ignore broken header and its value. - if (response.StatusCode is HttpStatusCode.Conflict && response.Headers.TryGetValues(HttpKnownHeaderNames.RetryAfter, out IEnumerable retryAfter)) + if (response.StatusCode is HttpStatusCode.Conflict && response.Headers.TryGetValues(HttpKnownHeaderNames.RetryAfter, out IEnumerable? retryAfter)) { try { @@ -1402,11 +1403,11 @@ private static string FormatDictionary(IDictionary content) bodyBuilder.Append('&'); } - object value = content[key]; + object? value = content[key]; // URLEncode the key and value string encodedKey = WebUtility.UrlEncode(key); - string encodedValue = value is null ? string.Empty : WebUtility.UrlEncode(value.ToString()); + string encodedValue = value is null ? string.Empty : WebUtility.UrlEncode(value.ToString()!); bodyBuilder.Append($"{encodedKey}={encodedValue}"); } @@ -1429,7 +1430,7 @@ private ErrorRecord GetValidationError(string msg, string errorId, params object private string GetBasicAuthorizationHeader() { - string password = new NetworkCredential(string.Empty, Credential.Password).Password; + string password = new NetworkCredential(string.Empty, Credential!.Password).Password; string unencoded = string.Create(CultureInfo.InvariantCulture, $"{Credential.UserName}:{password}"); byte[] bytes = Encoding.UTF8.GetBytes(unencoded); return string.Create(CultureInfo.InvariantCulture, $"Basic {Convert.ToBase64String(bytes)}"); @@ -1444,11 +1445,11 @@ private void ProcessAuthentication() { if (Authentication == WebAuthenticationType.Basic) { - WebSession.Headers["Authorization"] = GetBasicAuthorizationHeader(); + WebSession!.Headers["Authorization"] = GetBasicAuthorizationHeader(); } else if (Authentication == WebAuthenticationType.Bearer || Authentication == WebAuthenticationType.OAuth) { - WebSession.Headers["Authorization"] = GetBearerAuthorizationHeader(); + WebSession!.Headers["Authorization"] = GetBearerAuthorizationHeader(); } else { @@ -1487,7 +1488,7 @@ internal void SetRequestContent(HttpRequestMessage request, string content) ArgumentNullException.ThrowIfNull(request); ArgumentNullException.ThrowIfNull(content); - Encoding encoding = null; + Encoding? encoding = null; if (ContentType is not null) { // If Content-Type contains the encoding format (as CharSet), use this encoding format @@ -1521,8 +1522,8 @@ internal void SetRequestContent(HttpRequestMessage request, XmlNode xmlNode) ArgumentNullException.ThrowIfNull(request); ArgumentNullException.ThrowIfNull(xmlNode); - byte[] bytes = null; - XmlDocument doc = xmlNode as XmlDocument; + byte[]? bytes = null; + XmlDocument? doc = xmlNode as XmlDocument; if (doc?.FirstChild is XmlDeclaration decl) { Encoding encoding = Encoding.GetEncoding(decl.Encoding); @@ -1568,7 +1569,7 @@ internal void SetRequestContent(HttpRequestMessage request, MultipartFormDataCon ArgumentNullException.ThrowIfNull(multipartContent); // Content headers will be set by MultipartFormDataContent which will throw unless we clear them first - WebSession.ContentHeaders.Clear(); + WebSession!.ContentHeaders.Clear(); request.Content = multipartContent; } @@ -1584,7 +1585,7 @@ internal void SetRequestContent(HttpRequestMessage request, IDictionary content) internal void ParseLinkHeader(HttpResponseMessage response) { - Uri requestUri = response.RequestMessage.RequestUri; + Uri requestUri = response.RequestMessage?.RequestUri!; if (_relationLink is null) { // Must ignore the case of relation links. See RFC 8288 (https://tools.ietf.org/html/rfc8288) @@ -1598,7 +1599,7 @@ internal void ParseLinkHeader(HttpResponseMessage response) // We only support the URL in angle brackets and `rel`, other attributes are ignored // user can still parse it themselves via the Headers property const string Pattern = "<(?.*?)>;\\s*rel=(?\")?(?(?(quoted).*?|[^,;]*))(?(quoted)\")"; - if (response.Headers.TryGetValues("Link", out IEnumerable links)) + if (response.Headers.TryGetValues("Link", out IEnumerable? links)) { foreach (string linkHeader in links) { @@ -1720,14 +1721,14 @@ private static StreamContent GetMultipartFileContent(object fieldName, FileInfo StreamContent result = GetMultipartStreamContent(fieldName: fieldName, stream: new FileStream(file.FullName, FileMode.Open)); // .NET does not enclose field names in quotes, however, modern browsers and curl do. - result.Headers.ContentDisposition.FileName = "\"" + file.Name + "\""; + result.Headers.ContentDisposition!.FileName = "\"" + file.Name + "\""; return result; } private static string FormatErrorMessage(string error, string contentType) { - string formattedError = null; + string? formattedError = null; try { @@ -1756,9 +1757,9 @@ private static string FormatErrorMessage(string error, string contentType) } else if (ContentHelper.IsJson(contentType)) { - JsonNode jsonNode = JsonNode.Parse(error); + JsonNode? jsonNode = JsonNode.Parse(error); JsonSerializerOptions options = new JsonSerializerOptions { WriteIndented = true }; - string jsonString = jsonNode.ToJsonString(options); + string jsonString = jsonNode!.ToJsonString(options); formattedError = Environment.NewLine + jsonString; } @@ -1843,4 +1844,5 @@ public HttpResponseException(string message, HttpResponseMessage response) : bas /// public HttpResponseMessage Response { get; } } +#nullable restore } From c7887d2ee5c4e2640f6a355a7f60b362a9526283 Mon Sep 17 00:00:00 2001 From: CarloToso <105941898+CarloToso@users.noreply.github.com> Date: Fri, 17 Feb 2023 20:44:03 +0100 Subject: [PATCH 02/40] move #nullable enable to the top --- .../utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs index 179b4c7f919..2abb8a0b251 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs @@ -1,6 +1,8 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. +#nullable enable + using System; using System.Collections; using System.Collections.Generic; @@ -25,7 +27,6 @@ namespace Microsoft.PowerShell.Commands { -#nullable enable /// /// The valid values for the -Authentication parameter for Invoke-RestMethod and Invoke-WebRequest. /// @@ -1844,5 +1845,4 @@ public HttpResponseException(string message, HttpResponseMessage response) : bas /// public HttpResponseMessage Response { get; } } -#nullable restore } From 6adf9267d6516f301d3dbc95984f15e4caeee18f Mon Sep 17 00:00:00 2001 From: CarloToso <105941898+CarloToso@users.noreply.github.com> Date: Fri, 17 Feb 2023 23:02:49 +0100 Subject: [PATCH 03/40] Uri? --- .../Common/WebRequestPSCmdlet.Common.cs | 21 +++++++++++-------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs index 2abb8a0b251..92ea846d8dd 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs @@ -522,7 +522,7 @@ protected override void ProcessRecord() using (HttpClient client = GetHttpClient(handleRedirect)) { int followedRelLink = 0; - Uri uri = Uri!; + Uri? uri = Uri; do { if (followedRelLink > 0) @@ -530,7 +530,7 @@ protected override void ProcessRecord() string linkVerboseMsg = string.Format( CultureInfo.CurrentCulture, WebCmdletStrings.FollowingRelLinkVerboseMsg, - uri.AbsoluteUri); + uri?.AbsoluteUri); WriteVerbose(linkVerboseMsg); } @@ -723,7 +723,7 @@ internal virtual void ValidateParameters() ThrowTerminatingError(error); } - if (!AllowUnencryptedAuthentication && (Authentication != WebAuthenticationType.None || Credential is not null || UseDefaultCredentials) && Uri!.Scheme != "https") + if (!AllowUnencryptedAuthentication && (Authentication != WebAuthenticationType.None || Credential is not null || UseDefaultCredentials) && Uri?.Scheme != "https") { ErrorRecord error = GetValidationError(WebCmdletStrings.AllowUnencryptedAuthenticationRequired, "WebCmdletAllowUnencryptedAuthenticationRequiredException"); ThrowTerminatingError(error); @@ -1003,9 +1003,9 @@ internal virtual HttpClient GetHttpClient(bool handleRedirect) return httpClient; } - internal virtual HttpRequestMessage GetRequest(Uri uri) + internal virtual HttpRequestMessage GetRequest(Uri? uri) { - Uri requestUri = PrepareUri(uri); + Uri? requestUri = PrepareUri(uri); HttpMethod httpMethod = string.IsNullOrEmpty(CustomMethod) ? GetHttpMethod(Method) : new HttpMethod(CustomMethod); // Create the base WebRequest object @@ -1227,7 +1227,7 @@ internal virtual HttpResponseMessage GetResponse(HttpClient client, HttpRequestM do { // Track the current URI being used by various requests and re-requests. - Uri currentUri = currentRequest.RequestUri!; + Uri? currentUri = currentRequest.RequestUri; _cancelToken = new CancellationTokenSource(); response = client.SendAsync(currentRequest, HttpCompletionOption.ResponseHeadersRead, _cancelToken.Token).GetAwaiter().GetResult(); @@ -1355,7 +1355,7 @@ internal virtual void UpdateSession(HttpResponseMessage response) #endregion Virtual Methods #region Helper Methods - private Uri PrepareUri(Uri uri) + private Uri PrepareUri(Uri? uri) { uri = CheckProtocol(uri); @@ -1383,7 +1383,7 @@ private Uri PrepareUri(Uri uri) return uri; } - private static Uri CheckProtocol(Uri uri) + private static Uri CheckProtocol(Uri? uri) { ArgumentNullException.ThrowIfNull(uri); @@ -1586,7 +1586,10 @@ internal void SetRequestContent(HttpRequestMessage request, IDictionary content) internal void ParseLinkHeader(HttpResponseMessage response) { - Uri requestUri = response.RequestMessage?.RequestUri!; + Uri? requestUri = response.RequestMessage?.RequestUri; + + ArgumentNullException.ThrowIfNull(requestUri); + if (_relationLink is null) { // Must ignore the case of relation links. See RFC 8288 (https://tools.ietf.org/html/rfc8288) From e88266e66f2a10ac38cfb47618ee7631e3b2db7d Mon Sep 17 00:00:00 2001 From: CarloToso <105941898+CarloToso@users.noreply.github.com> Date: Sat, 18 Feb 2023 21:22:17 +0100 Subject: [PATCH 04/40] requestContentLength --- .../utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs index 92ea846d8dd..8f0b7b237ba 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs @@ -1281,7 +1281,7 @@ internal virtual HttpResponseMessage GetResponse(HttpClient client, HttpRequestM { FillRequestStream(requestWithoutRange); - long requestContentLength = requestWithoutRange.Content is null ? 0 : requestWithoutRange.Content.Headers.ContentLength!.Value; + long? requestContentLength = requestWithoutRange.Content is null ? 0 : requestWithoutRange.Content.Headers.ContentLength; string reqVerboseMsg = string.Format( CultureInfo.CurrentCulture, From d0acf913d407792c4a840f335c7639f660643916 Mon Sep 17 00:00:00 2001 From: CarloToso <105941898+CarloToso@users.noreply.github.com> Date: Sat, 18 Feb 2023 21:23:24 +0100 Subject: [PATCH 05/40] requestContentLength --- .../utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs index 8f0b7b237ba..5e5d650be12 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs @@ -540,7 +540,7 @@ protected override void ProcessRecord() FillRequestStream(request); try { - long requestContentLength = request.Content is null ? 0 : request.Content.Headers.ContentLength!.Value; + long? requestContentLength = request.Content is null ? 0 : request.Content.Headers.ContentLength; string reqVerboseMsg = string.Format( CultureInfo.CurrentCulture, From 56f623553b492a69b3e2a6f10e9751d072796228 Mon Sep 17 00:00:00 2001 From: CarloToso <105941898+CarloToso@users.noreply.github.com> Date: Sat, 18 Feb 2023 21:24:36 +0100 Subject: [PATCH 06/40] QualifyFilePath --- .../utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs index 5e5d650be12..5bde7a44056 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs @@ -1390,7 +1390,7 @@ private static Uri CheckProtocol(Uri? uri) return uri.IsAbsoluteUri ? uri : new Uri("http://" + uri.OriginalString); } - private string QualifyFilePath(string path) => PathUtils.ResolveFilePath(filePath: path, command: this, isLiteralPath: true); + private string QualifyFilePath(string? path) => PathUtils.ResolveFilePath(filePath: path, command: this, isLiteralPath: true); private static string FormatDictionary(IDictionary content) { From bf0df35500715c85a880a3ffa417be04b3a84a72 Mon Sep 17 00:00:00 2001 From: CarloToso <105941898+CarloToso@users.noreply.github.com> Date: Sun, 19 Feb 2023 03:17:22 +0100 Subject: [PATCH 07/40] QualifyFilePath(OutFile) --- .../utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs index 5bde7a44056..68eb8e80010 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs @@ -474,7 +474,7 @@ public virtual string? CustomMethod #region Helper Properties - internal string QualifiedOutFile => QualifyFilePath(OutFile!); + internal string QualifiedOutFile => QualifyFilePath(OutFile); internal bool ShouldCheckHttpStatus => !SkipHttpErrorCheck; From 5ca37a78667914b4c02f2e3a396f86af66285708 Mon Sep 17 00:00:00 2001 From: CarloToso <105941898+CarloToso@users.noreply.github.com> Date: Sun, 19 Feb 2023 03:18:43 +0100 Subject: [PATCH 08/40] response.Content.Headers.ContentRange? --- .../utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs index 68eb8e80010..7865045c2fb 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs @@ -568,8 +568,7 @@ protected override void ProcessRecord() // This happens when the local file is the same size as the remote file. if (Resume.IsPresent && response.StatusCode == HttpStatusCode.RequestedRangeNotSatisfiable - && response.Content.Headers.ContentRange!.HasLength - && response.Content.Headers.ContentRange.Length == _resumeFileSize) + && response.Content.Headers.ContentRange?.Length == _resumeFileSize) { _isSuccess = true; WriteVerbose(string.Format( @@ -1266,8 +1265,7 @@ internal virtual HttpResponseMessage GetResponse(HttpClient client, HttpRequestM // If the size of the remote file is the same as the local file, there is nothing to resume. if (Resume.IsPresent && response.StatusCode == HttpStatusCode.RequestedRangeNotSatisfiable - && (response.Content.Headers.ContentRange!.HasLength - && response.Content.Headers.ContentRange.Length != _resumeFileSize)) + && response.Content.Headers.ContentRange?.Length != _resumeFileSize) { _cancelToken?.Cancel(); From d3a8d0ddc71e6f554f19215c9bdeb68750c6885c Mon Sep 17 00:00:00 2001 From: CarloToso <105941898+CarloToso@users.noreply.github.com> Date: Sun, 19 Feb 2023 03:33:22 +0100 Subject: [PATCH 09/40] object? fieldValue --- .../utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs index 7865045c2fb..c15d2b6765e 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs @@ -1123,7 +1123,7 @@ internal virtual void FillRequestStream(HttpRequestMessage request) foreach (DictionaryEntry formEntry in Form) { // AddMultipartContent will handle PSObject unwrapping, Object type determination and enumerateing top level IEnumerables. - AddMultipartContent(fieldName: formEntry.Key, fieldValue: formEntry.Value!, formData: formData, enumerate: true); + AddMultipartContent(fieldName: formEntry.Key, fieldValue: formEntry.Value, formData: formData, enumerate: true); } SetRequestContent(request, formData); @@ -1630,7 +1630,7 @@ internal void ParseLinkHeader(HttpResponseMessage response) /// The Field Value to use. /// The to update. /// If true, collection types in will be enumerated. If false, collections will be treated as single value. - private void AddMultipartContent(object fieldName, object fieldValue, MultipartFormDataContent formData, bool enumerate) + private void AddMultipartContent(object fieldName, object? fieldValue, MultipartFormDataContent formData, bool enumerate) { ArgumentNullException.ThrowIfNull(formData); @@ -1681,7 +1681,7 @@ private void AddMultipartContent(object fieldName, object fieldValue, MultipartF /// /// The Field Name to use for the /// The Field Value to use for the - private static StringContent GetMultipartStringContent(object fieldName, object fieldValue) + private static StringContent GetMultipartStringContent(object fieldName, object? fieldValue) { ContentDispositionHeaderValue contentDisposition = new("form-data"); From 49d220c5e2cbe89469d5033e7429abddd82631ba Mon Sep 17 00:00:00 2001 From: CarloToso <105941898+CarloToso@users.noreply.github.com> Date: Sun, 19 Feb 2023 03:38:04 +0100 Subject: [PATCH 10/40] encodedValue --- .../utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs index c15d2b6765e..70c472afbb2 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs @@ -1406,7 +1406,7 @@ private static string FormatDictionary(IDictionary content) // URLEncode the key and value string encodedKey = WebUtility.UrlEncode(key); - string encodedValue = value is null ? string.Empty : WebUtility.UrlEncode(value.ToString()!); + string? encodedValue = value is null ? string.Empty : WebUtility.UrlEncode(value.ToString()); bodyBuilder.Append($"{encodedKey}={encodedValue}"); } From fb0ca03bf411138f220454f8f2d3dc1d4945466e Mon Sep 17 00:00:00 2001 From: CarloToso <105941898+CarloToso@users.noreply.github.com> Date: Sun, 19 Feb 2023 03:52:47 +0100 Subject: [PATCH 11/40] jsonNode --- .../utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs index 70c472afbb2..6abe36e302d 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs @@ -1761,7 +1761,9 @@ private static string FormatErrorMessage(string error, string contentType) { JsonNode? jsonNode = JsonNode.Parse(error); JsonSerializerOptions options = new JsonSerializerOptions { WriteIndented = true }; - string jsonString = jsonNode!.ToJsonString(options); + + ArgumentNullException.ThrowIfNull(jsonNode); + string jsonString = jsonNode.ToJsonString(options); formattedError = Environment.NewLine + jsonString; } From 12b3546fa3f3f8b4888167920b33977d63cd5c46 Mon Sep 17 00:00:00 2001 From: CarloToso <105941898+CarloToso@users.noreply.github.com> Date: Sun, 19 Feb 2023 04:08:01 +0100 Subject: [PATCH 12/40] WebSession --- .../Common/WebRequestPSCmdlet.Common.cs | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs index 6abe36e302d..3a13cbc6535 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs @@ -167,7 +167,7 @@ public abstract class WebRequestPSCmdlet : PSCmdlet /// Gets or sets the Session property. /// [Parameter] - public virtual WebRequestSession? WebSession { get; set; } + public virtual WebRequestSession WebSession { get; set; } = new WebRequestSession(); /// /// Gets or sets the SessionVariable property. @@ -515,7 +515,7 @@ protected override void ProcessRecord() // If the request contains an authorization header and PreserveAuthorizationOnRedirect is not set, // it needs to be stripped on the first redirect. bool keepAuthorizationOnRedirect = PreserveAuthorizationOnRedirect.IsPresent - && WebSession!.Headers.ContainsKey(HttpKnownHeaderNames.Authorization); + && WebSession.Headers.ContainsKey(HttpKnownHeaderNames.Authorization); bool handleRedirect = keepAuthorizationOnRedirect || AllowInsecureRedirect || PreserveHttpMethodOnRedirect; @@ -634,7 +634,7 @@ protected override void ProcessRecord() // Errors with redirection counts of greater than 0 are handled automatically by .NET, but are // impossible to detect programmatically when we hit this limit. By handling this ourselves // (and still writing out the result), users can debug actual HTTP redirect problems. - if (WebSession!.MaximumRedirection == 0 && IsRedirectCode(response.StatusCode)) + if (WebSession.MaximumRedirection == 0 && IsRedirectCode(response.StatusCode)) { ErrorRecord er = new(new InvalidOperationException(), "MaximumRedirectExceeded", ErrorCategory.InvalidOperation, request); er.ErrorDetails = new ErrorDetails(WebCmdletStrings.MaximumRedirectionCountExceeded); @@ -838,7 +838,7 @@ internal virtual void ValidateParameters() internal virtual void PrepareSession() { // Make sure we have a valid WebRequestSession object to work with - WebSession ??= new WebRequestSession(); + // WebSession ??= new WebRequestSession(); if (SessionVariable is not null) { @@ -948,7 +948,7 @@ internal virtual void PrepareSession() internal virtual HttpClient GetHttpClient(bool handleRedirect) { HttpClientHandler handler = new(); - handler.CookieContainer = WebSession!.Cookies; + handler.CookieContainer = WebSession.Cookies; handler.AutomaticDecompression = DecompressionMethods.All; // Set the credentials used by this request @@ -1016,7 +1016,7 @@ internal virtual HttpRequestMessage GetRequest(Uri? uri) } // Pull in session data - if (WebSession!.Headers.Count > 0) + if (WebSession.Headers.Count > 0) { WebSession.ContentHeaders.Clear(); foreach (var entry in WebSession.Headers) @@ -1105,12 +1105,12 @@ internal virtual void FillRequestStream(HttpRequestMessage request) // Set the request content type if (ContentType is not null) { - WebSession!.ContentHeaders[HttpKnownHeaderNames.ContentType] = ContentType; + WebSession.ContentHeaders[HttpKnownHeaderNames.ContentType] = ContentType; } else if (request.Method == HttpMethod.Post) { // Win8:545310 Invoke-WebRequest does not properly set MIME type for POST - WebSession!.ContentHeaders.TryGetValue(HttpKnownHeaderNames.ContentType, out string? contentType); + WebSession.ContentHeaders.TryGetValue(HttpKnownHeaderNames.ContentType, out string? contentType); if (string.IsNullOrEmpty(contentType)) { WebSession.ContentHeaders[HttpKnownHeaderNames.ContentType] = "application/x-www-form-urlencoded"; @@ -1188,7 +1188,7 @@ internal virtual void FillRequestStream(HttpRequestMessage request) request.Content.Headers.Clear(); } - foreach (KeyValuePair entry in WebSession!.ContentHeaders) + foreach (KeyValuePair entry in WebSession.ContentHeaders) { if (!string.IsNullOrWhiteSpace(entry.Value)) { @@ -1219,7 +1219,7 @@ internal virtual HttpResponseMessage GetResponse(HttpClient client, HttpRequestM ArgumentNullException.ThrowIfNull(request); // Add 1 to account for the first request. - int totalRequests = WebSession!.MaximumRetryCount + 1; + int totalRequests = WebSession.MaximumRetryCount + 1; HttpRequestMessage currentRequest = request; HttpResponseMessage? response = null; @@ -1444,11 +1444,11 @@ private void ProcessAuthentication() { if (Authentication == WebAuthenticationType.Basic) { - WebSession!.Headers["Authorization"] = GetBasicAuthorizationHeader(); + WebSession.Headers["Authorization"] = GetBasicAuthorizationHeader(); } else if (Authentication == WebAuthenticationType.Bearer || Authentication == WebAuthenticationType.OAuth) { - WebSession!.Headers["Authorization"] = GetBearerAuthorizationHeader(); + WebSession.Headers["Authorization"] = GetBearerAuthorizationHeader(); } else { @@ -1568,7 +1568,7 @@ internal void SetRequestContent(HttpRequestMessage request, MultipartFormDataCon ArgumentNullException.ThrowIfNull(multipartContent); // Content headers will be set by MultipartFormDataContent which will throw unless we clear them first - WebSession!.ContentHeaders.Clear(); + WebSession.ContentHeaders.Clear(); request.Content = multipartContent; } From 9391d50c3b5bd0d4963dfa592464494ba62eb30b Mon Sep 17 00:00:00 2001 From: CarloToso <105941898+CarloToso@users.noreply.github.com> Date: Sun, 19 Feb 2023 04:08:30 +0100 Subject: [PATCH 13/40] credential --- .../utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs index 3a13cbc6535..2cd34165068 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs @@ -1429,8 +1429,8 @@ private ErrorRecord GetValidationError(string msg, string errorId, params object private string GetBasicAuthorizationHeader() { - string password = new NetworkCredential(string.Empty, Credential!.Password).Password; - string unencoded = string.Create(CultureInfo.InvariantCulture, $"{Credential.UserName}:{password}"); + string password = new NetworkCredential(string.Empty, Credential?.Password).Password; + string unencoded = string.Create(CultureInfo.InvariantCulture, $"{Credential?.UserName}:{password}"); byte[] bytes = Encoding.UTF8.GetBytes(unencoded); return string.Create(CultureInfo.InvariantCulture, $"Basic {Convert.ToBase64String(bytes)}"); } From 983a42b97ece19ed843fcbff067433b5fecb3f80 Mon Sep 17 00:00:00 2001 From: CarloToso <105941898+CarloToso@users.noreply.github.com> Date: Sun, 19 Feb 2023 21:21:28 +0100 Subject: [PATCH 14/40] _relationLink --- .../WebCmdlet/Common/WebRequestPSCmdlet.Common.cs | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs index 2cd34165068..fbc814dea01 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs @@ -117,7 +117,7 @@ public abstract class WebRequestPSCmdlet : PSCmdlet /// /// Automatically follow Rel Links. /// - internal Dictionary? _relationLink = null; + internal Dictionary _relationLink = new Dictionary(StringComparer.OrdinalIgnoreCase); /// /// The current size of the local file being resumed. @@ -654,7 +654,7 @@ protected override void ProcessRecord() if (_followRelLink) { - if (!_relationLink!.ContainsKey("next")) + if (!_relationLink.ContainsKey("next")) { return; } @@ -1588,15 +1588,8 @@ internal void ParseLinkHeader(HttpResponseMessage response) ArgumentNullException.ThrowIfNull(requestUri); - if (_relationLink is null) - { - // Must ignore the case of relation links. See RFC 8288 (https://tools.ietf.org/html/rfc8288) - _relationLink = new Dictionary(StringComparer.OrdinalIgnoreCase); - } - else - { - _relationLink.Clear(); - } + // Must ignore the case of relation links. See RFC 8288 (https://tools.ietf.org/html/rfc8288) + _relationLink.Clear(); // We only support the URL in angle brackets and `rel`, other attributes are ignored // user can still parse it themselves via the Headers property From 994af88e4ae02c1a7dac5dbbb41e2de31012138d Mon Sep 17 00:00:00 2001 From: CarloToso <105941898+CarloToso@users.noreply.github.com> Date: Mon, 20 Feb 2023 19:07:35 +0100 Subject: [PATCH 15/40] WebSession --- .../utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs index fbc814dea01..f0f586e532c 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs @@ -167,7 +167,8 @@ public abstract class WebRequestPSCmdlet : PSCmdlet /// Gets or sets the Session property. /// [Parameter] - public virtual WebRequestSession WebSession { get; set; } = new WebRequestSession(); + [System.Diagnostics.CodeAnalysis.AllowNullAttribute] + public virtual WebRequestSession WebSession { get; set; } /// /// Gets or sets the SessionVariable property. @@ -838,7 +839,7 @@ internal virtual void ValidateParameters() internal virtual void PrepareSession() { // Make sure we have a valid WebRequestSession object to work with - // WebSession ??= new WebRequestSession(); + WebSession ??= new WebRequestSession(); if (SessionVariable is not null) { From f8bc141e9173658979020353009decc3d8efec47 Mon Sep 17 00:00:00 2001 From: CarloToso <105941898+CarloToso@users.noreply.github.com> Date: Mon, 20 Feb 2023 19:29:12 +0100 Subject: [PATCH 16/40] _relationLink --- .../Common/WebRequestPSCmdlet.Common.cs | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs index f0f586e532c..0fa7f253f4f 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs @@ -117,7 +117,8 @@ public abstract class WebRequestPSCmdlet : PSCmdlet /// /// Automatically follow Rel Links. /// - internal Dictionary _relationLink = new Dictionary(StringComparer.OrdinalIgnoreCase); + [System.Diagnostics.CodeAnalysis.AllowNullAttribute] + internal Dictionary _relationLink = null; /// /// The current size of the local file being resumed. @@ -945,7 +946,7 @@ internal virtual void PrepareSession() WebSession.RetryIntervalInSeconds = RetryIntervalSec; } } - + internal virtual HttpClient GetHttpClient(bool handleRedirect) { HttpClientHandler handler = new(); @@ -1589,8 +1590,15 @@ internal void ParseLinkHeader(HttpResponseMessage response) ArgumentNullException.ThrowIfNull(requestUri); - // Must ignore the case of relation links. See RFC 8288 (https://tools.ietf.org/html/rfc8288) - _relationLink.Clear(); + if (_relationLink is null) + { + // Must ignore the case of relation links. See RFC 8288 (https://tools.ietf.org/html/rfc8288) + _relationLink = new Dictionary(StringComparer.OrdinalIgnoreCase); + } + else + { + _relationLink.Clear(); + } // We only support the URL in angle brackets and `rel`, other attributes are ignored // user can still parse it themselves via the Headers property From 5e1881972ee7053f54ca01809833706d7edbe194 Mon Sep 17 00:00:00 2001 From: CarloToso <105941898+CarloToso@users.noreply.github.com> Date: Mon, 20 Feb 2023 19:35:43 +0100 Subject: [PATCH 17/40] CustomMethod --- .../utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs index 0fa7f253f4f..f9fbafceff1 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs @@ -346,11 +346,12 @@ public abstract class WebRequestPSCmdlet : PSCmdlet [Parameter(Mandatory = true, ParameterSetName = "CustomMethodNoProxy")] [Alias("CM")] [ValidateNotNullOrEmpty] + [System.Diagnostics.CodeAnalysis.DisallowNullAttribute] public virtual string? CustomMethod { get => _custommethod; - set => _custommethod = value!.ToUpperInvariant(); + set => _custommethod = value.ToUpperInvariant(); } private string? _custommethod; From 92e4eda3db9095993469de720a141e243f1b2781 Mon Sep 17 00:00:00 2001 From: CarloToso <105941898+CarloToso@users.noreply.github.com> Date: Mon, 20 Feb 2023 22:40:52 +0100 Subject: [PATCH 18/40] request.RequestUri --- .../utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs index f9fbafceff1..6efcbdde21a 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs @@ -1255,7 +1255,9 @@ internal virtual HttpResponseMessage GetResponse(HttpClient client, HttpRequestM CustomMethod = string.Empty; } - currentUri = new Uri(request.RequestUri!, response.Headers.Location); + ArgumentNullException.ThrowIfNull(request.RequestUri); + + currentUri = new Uri(request.RequestUri, response.Headers.Location); // Continue to handle redirection using HttpRequestMessage redirectRequest = GetRequest(currentUri); From db5c2e19404d4d04c61ca92b464381db60a10575 Mon Sep 17 00:00:00 2001 From: CarloToso <105941898+CarloToso@users.noreply.github.com> Date: Wed, 22 Feb 2023 02:58:02 +0100 Subject: [PATCH 19/40] remove wrong ArgumentNullException.ThrowIfNull(uri) --- .../utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs index 6efcbdde21a..76fbaddd89c 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs @@ -1388,9 +1388,7 @@ private Uri PrepareUri(Uri? uri) private static Uri CheckProtocol(Uri? uri) { - ArgumentNullException.ThrowIfNull(uri); - - return uri.IsAbsoluteUri ? uri : new Uri("http://" + uri.OriginalString); + return uri is not null && uri.IsAbsoluteUri ? uri : new Uri("http://" + uri?.OriginalString); } private string QualifyFilePath(string? path) => PathUtils.ResolveFilePath(filePath: path, command: this, isLiteralPath: true); From e7142b0b3a4fff3169354015cd41cd770ecffc64 Mon Sep 17 00:00:00 2001 From: CarloToso <105941898+CarloToso@users.noreply.github.com> Date: Wed, 22 Feb 2023 03:11:32 +0100 Subject: [PATCH 20/40] requestUri return if null --- .../utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs index 76fbaddd89c..64cedea1e45 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs @@ -1589,7 +1589,10 @@ internal void ParseLinkHeader(HttpResponseMessage response) { Uri? requestUri = response.RequestMessage?.RequestUri; - ArgumentNullException.ThrowIfNull(requestUri); + if (requestUri is null) + { + return; + } if (_relationLink is null) { From 2cd78c95c487401975f744390c5594eea1d0ed85 Mon Sep 17 00:00:00 2001 From: CarloToso <105941898+CarloToso@users.noreply.github.com> Date: Wed, 22 Feb 2023 03:23:32 +0100 Subject: [PATCH 21/40] fix incorrect behaviour jsonString --- .../utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs index 64cedea1e45..7eb4db42cac 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs @@ -1768,8 +1768,7 @@ private static string FormatErrorMessage(string error, string contentType) JsonNode? jsonNode = JsonNode.Parse(error); JsonSerializerOptions options = new JsonSerializerOptions { WriteIndented = true }; - ArgumentNullException.ThrowIfNull(jsonNode); - string jsonString = jsonNode.ToJsonString(options); + string jsonString = jsonNode?.ToJsonString(options) ?? throw new ArgumentNullException(); formattedError = Environment.NewLine + jsonString; } From 9725f2f39edb46ec13fcbabbbae3520eecf1f66d Mon Sep 17 00:00:00 2001 From: CarloToso <105941898+CarloToso@users.noreply.github.com> Date: Wed, 22 Feb 2023 03:35:19 +0100 Subject: [PATCH 22/40] correct behaviour _relationLink --- .../utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs index 7eb4db42cac..6d6fcfaf20c 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs @@ -117,8 +117,7 @@ public abstract class WebRequestPSCmdlet : PSCmdlet /// /// Automatically follow Rel Links. /// - [System.Diagnostics.CodeAnalysis.AllowNullAttribute] - internal Dictionary _relationLink = null; + internal Dictionary? _relationLink = null; /// /// The current size of the local file being resumed. @@ -655,7 +654,7 @@ protected override void ProcessRecord() ThrowTerminatingError(er); } - if (_followRelLink) + if (_followRelLink && _relationLink is not null) { if (!_relationLink.ContainsKey("next")) { From 8f0c2d0aeceaf052f32f4f95a07f935d493bf7b2 Mon Sep 17 00:00:00 2001 From: CarloToso <105941898+CarloToso@users.noreply.github.com> Date: Wed, 22 Feb 2023 03:41:15 +0100 Subject: [PATCH 23/40] request.RequestUri --- .../utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs index 6d6fcfaf20c..9823bacf5e3 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs @@ -1254,9 +1254,7 @@ internal virtual HttpResponseMessage GetResponse(HttpClient client, HttpRequestM CustomMethod = string.Empty; } - ArgumentNullException.ThrowIfNull(request.RequestUri); - - currentUri = new Uri(request.RequestUri, response.Headers.Location); + currentUri = new Uri(request.RequestUri!, response.Headers.Location); // Continue to handle redirection using HttpRequestMessage redirectRequest = GetRequest(currentUri); From 70df0de60dc1940f72460d8122378df6539dc403 Mon Sep 17 00:00:00 2001 From: CarloToso <105941898+CarloToso@users.noreply.github.com> Date: Wed, 22 Feb 2023 03:45:42 +0100 Subject: [PATCH 24/40] remove empty line --- .../utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs index 9823bacf5e3..126a02c4a1c 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs @@ -1764,7 +1764,6 @@ private static string FormatErrorMessage(string error, string contentType) { JsonNode? jsonNode = JsonNode.Parse(error); JsonSerializerOptions options = new JsonSerializerOptions { WriteIndented = true }; - string jsonString = jsonNode?.ToJsonString(options) ?? throw new ArgumentNullException(); formattedError = Environment.NewLine + jsonString; From 85ced01baaf64b062b44cdea3ba30d7b2eb0798d Mon Sep 17 00:00:00 2001 From: CarloToso <105941898+CarloToso@users.noreply.github.com> Date: Wed, 22 Feb 2023 23:31:30 +0100 Subject: [PATCH 25/40] Follow suggestion WebSession --- .../WebCmdlet/Common/WebRequestPSCmdlet.Common.cs | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs index 126a02c4a1c..f50b8fb0728 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs @@ -167,14 +167,15 @@ public abstract class WebRequestPSCmdlet : PSCmdlet /// Gets or sets the Session property. /// [Parameter] - [System.Diagnostics.CodeAnalysis.AllowNullAttribute] - public virtual WebRequestSession WebSession { get; set; } + [ValidateNotNull] + public virtual WebRequestSession WebSession { get; set; } = new WebRequestSession(); /// /// Gets or sets the SessionVariable property. /// [Parameter] [Alias("SV")] + [ValidateNotNullOrWhiteSpace] public virtual string? SessionVariable { get; set; } #endregion Session @@ -693,7 +694,7 @@ protected override void ProcessRecord() internal virtual void ValidateParameters() { // Sessions - if (WebSession is not null && SessionVariable is not null) + if (MyInvocation.BoundParameters.ContainsKey("WebSession") && SessionVariable is not null) { ErrorRecord error = GetValidationError(WebCmdletStrings.SessionConflict, "WebCmdletSessionConflictException"); ThrowTerminatingError(error); @@ -839,9 +840,6 @@ internal virtual void ValidateParameters() internal virtual void PrepareSession() { - // Make sure we have a valid WebRequestSession object to work with - WebSession ??= new WebRequestSession(); - if (SessionVariable is not null) { // Save the session back to the PS environment if requested From b16d613ac82824939d8d91facaf556d1f0f965b6 Mon Sep 17 00:00:00 2001 From: CarloToso <105941898+CarloToso@users.noreply.github.com> Date: Thu, 23 Feb 2023 09:38:52 +0100 Subject: [PATCH 26/40] follow suggestion sessionvariable --- .../utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs index f50b8fb0728..fb4fff6d9fa 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs @@ -694,7 +694,7 @@ protected override void ProcessRecord() internal virtual void ValidateParameters() { // Sessions - if (MyInvocation.BoundParameters.ContainsKey("WebSession") && SessionVariable is not null) + if (MyInvocation.BoundParameters.ContainsKey("WebSession") && MyInvocation.BoundParameters.ContainsKey("SessionVariable")) { ErrorRecord error = GetValidationError(WebCmdletStrings.SessionConflict, "WebCmdletSessionConflictException"); ThrowTerminatingError(error); From c006dadeb9e7323a1665979938b5fd4cd5172e37 Mon Sep 17 00:00:00 2001 From: CarloToso <105941898+CarloToso@users.noreply.github.com> Date: Thu, 23 Feb 2023 12:35:19 +0100 Subject: [PATCH 27/40] possible solution for currentUri --- .../utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs index fb4fff6d9fa..a61fd375e46 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs @@ -1252,7 +1252,7 @@ internal virtual HttpResponseMessage GetResponse(HttpClient client, HttpRequestM CustomMethod = string.Empty; } - currentUri = new Uri(request.RequestUri!, response.Headers.Location); + currentUri = request.RequestUri is not null ? new Uri(request.RequestUri, response.Headers.Location) : response.Headers.Location; // Continue to handle redirection using HttpRequestMessage redirectRequest = GetRequest(currentUri); From efaa3fc49f233aabd6a603cd66a5af7a7a785b26 Mon Sep 17 00:00:00 2001 From: CarloToso <105941898+CarloToso@users.noreply.github.com> Date: Mon, 27 Feb 2023 19:45:39 +0100 Subject: [PATCH 28/40] use GetValueOrDefault(); reorder --- .../utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs index a61fd375e46..0c19639fbac 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs @@ -543,7 +543,7 @@ protected override void ProcessRecord() FillRequestStream(request); try { - long? requestContentLength = request.Content is null ? 0 : request.Content.Headers.ContentLength; + long? requestContentLength = request.Content?.Headers.ContentLength.GetValueOrDefault(); string reqVerboseMsg = string.Format( CultureInfo.CurrentCulture, @@ -1252,7 +1252,7 @@ internal virtual HttpResponseMessage GetResponse(HttpClient client, HttpRequestM CustomMethod = string.Empty; } - currentUri = request.RequestUri is not null ? new Uri(request.RequestUri, response.Headers.Location) : response.Headers.Location; + currentUri = request.RequestUri is null ? response.Headers.Location : new Uri(request.RequestUri, response.Headers.Location); // Continue to handle redirection using HttpRequestMessage redirectRequest = GetRequest(currentUri); @@ -1279,7 +1279,7 @@ internal virtual HttpResponseMessage GetResponse(HttpClient client, HttpRequestM { FillRequestStream(requestWithoutRange); - long? requestContentLength = requestWithoutRange.Content is null ? 0 : requestWithoutRange.Content.Headers.ContentLength; + long? requestContentLength = requestWithoutRange.Content?.Headers.ContentLength.GetValueOrDefault(); string reqVerboseMsg = string.Format( CultureInfo.CurrentCulture, From f8bb5514a30c67053d1f19e4cccf1f5e48bf5f3b Mon Sep 17 00:00:00 2001 From: CarloToso <105941898+CarloToso@users.noreply.github.com> Date: Tue, 28 Feb 2023 19:06:48 +0100 Subject: [PATCH 29/40] prepre for merge --- .../Common/WebRequestPSCmdlet.Common.cs | 225 +++++++++--------- 1 file changed, 112 insertions(+), 113 deletions(-) diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs index 0c19639fbac..c7d801d8ea8 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs @@ -522,153 +522,152 @@ protected override void ProcessRecord() bool handleRedirect = keepAuthorizationOnRedirect || AllowInsecureRedirect || PreserveHttpMethodOnRedirect; - using (HttpClient client = GetHttpClient(handleRedirect)) + using HttpClient client = GetHttpClient(handleRedirect) + + int followedRelLink = 0; + Uri? uri = Uri; + do { - int followedRelLink = 0; - Uri? uri = Uri; - do + if (followedRelLink > 0) + { + string linkVerboseMsg = string.Format( + CultureInfo.CurrentCulture, + WebCmdletStrings.FollowingRelLinkVerboseMsg, + uri?.AbsoluteUri); + + WriteVerbose(linkVerboseMsg); + } + + using (HttpRequestMessage request = GetRequest(uri)) { - if (followedRelLink > 0) + FillRequestStream(request); + try { - string linkVerboseMsg = string.Format( + long? requestContentLength = request.Content?.Headers.ContentLength.GetValueOrDefault(); + + string reqVerboseMsg = string.Format( CultureInfo.CurrentCulture, - WebCmdletStrings.FollowingRelLinkVerboseMsg, - uri?.AbsoluteUri); + WebCmdletStrings.WebMethodInvocationVerboseMsg, + request.Version, + request.Method, + requestContentLength); - WriteVerbose(linkVerboseMsg); - } + WriteVerbose(reqVerboseMsg); - using (HttpRequestMessage request = GetRequest(uri)) - { - FillRequestStream(request); - try - { - long? requestContentLength = request.Content?.Headers.ContentLength.GetValueOrDefault(); + using HttpResponseMessage response = GetResponse(client, request, handleRedirect); - string reqVerboseMsg = string.Format( - CultureInfo.CurrentCulture, - WebCmdletStrings.WebMethodInvocationVerboseMsg, - request.Version, - request.Method, - requestContentLength); + string contentType = ContentHelper.GetContentType(response); + string respVerboseMsg = string.Format( + CultureInfo.CurrentCulture, + WebCmdletStrings.WebResponseVerboseMsg, + response.Content.Headers.ContentLength, + contentType); - WriteVerbose(reqVerboseMsg); + WriteVerbose(respVerboseMsg); - using HttpResponseMessage response = GetResponse(client, request, handleRedirect); + bool _isSuccess = response.IsSuccessStatusCode; - string contentType = ContentHelper.GetContentType(response); - string respVerboseMsg = string.Format( + // Check if the Resume range was not satisfiable because the file already completed downloading. + // This happens when the local file is the same size as the remote file. + if (Resume.IsPresent + && response.StatusCode == HttpStatusCode.RequestedRangeNotSatisfiable + && response.Content.Headers.ContentRange?.Length == _resumeFileSize) + { + _isSuccess = true; + WriteVerbose(string.Format( CultureInfo.CurrentCulture, - WebCmdletStrings.WebResponseVerboseMsg, - response.Content.Headers.ContentLength, - contentType); + WebCmdletStrings.OutFileWritingSkipped, + OutFile)); - WriteVerbose(respVerboseMsg); + // Disable writing to the OutFile. + OutFile = null; + } - bool _isSuccess = response.IsSuccessStatusCode; + // Detect insecure redirection + if (!AllowInsecureRedirect && response.RequestMessage?.RequestUri?.Scheme == "https" && response.Headers.Location?.Scheme == "http") + { + ErrorRecord er = new(new InvalidOperationException(), "InsecureRedirection", ErrorCategory.InvalidOperation, request); + er.ErrorDetails = new ErrorDetails(WebCmdletStrings.InsecureRedirection); + ThrowTerminatingError(er); + } - // Check if the Resume range was not satisfiable because the file already completed downloading. - // This happens when the local file is the same size as the remote file. - if (Resume.IsPresent - && response.StatusCode == HttpStatusCode.RequestedRangeNotSatisfiable - && response.Content.Headers.ContentRange?.Length == _resumeFileSize) + if (ShouldCheckHttpStatus && !_isSuccess) + { + string message = string.Format( + CultureInfo.CurrentCulture, + WebCmdletStrings.ResponseStatusCodeFailure, + (int)response.StatusCode, + response.ReasonPhrase); + + HttpResponseException httpEx = new(message, response); + ErrorRecord er = new(httpEx, "WebCmdletWebResponseException", ErrorCategory.InvalidOperation, request); + string detailMsg = string.Empty; + StreamReader? reader = null; + try { - _isSuccess = true; - WriteVerbose(string.Format( - CultureInfo.CurrentCulture, - WebCmdletStrings.OutFileWritingSkipped, - OutFile)); - - // Disable writing to the OutFile. - OutFile = null; + reader = new StreamReader(StreamHelper.GetResponseStream(response)); + detailMsg = FormatErrorMessage(reader.ReadToEnd(), contentType); } - - // Detect insecure redirection - if (!AllowInsecureRedirect && response.RequestMessage?.RequestUri?.Scheme == "https" && response.Headers.Location?.Scheme == "http") + catch { - ErrorRecord er = new(new InvalidOperationException(), "InsecureRedirection", ErrorCategory.InvalidOperation, request); - er.ErrorDetails = new ErrorDetails(WebCmdletStrings.InsecureRedirection); - ThrowTerminatingError(er); + // Catch all } - - if (ShouldCheckHttpStatus && !_isSuccess) + finally { - string message = string.Format( - CultureInfo.CurrentCulture, - WebCmdletStrings.ResponseStatusCodeFailure, - (int)response.StatusCode, - response.ReasonPhrase); - - HttpResponseException httpEx = new(message, response); - ErrorRecord er = new(httpEx, "WebCmdletWebResponseException", ErrorCategory.InvalidOperation, request); - string detailMsg = string.Empty; - StreamReader? reader = null; - try - { - reader = new StreamReader(StreamHelper.GetResponseStream(response)); - detailMsg = FormatErrorMessage(reader.ReadToEnd(), contentType); - } - catch - { - // Catch all - } - finally - { - reader?.Dispose(); - } - - if (!string.IsNullOrEmpty(detailMsg)) - { - er.ErrorDetails = new ErrorDetails(detailMsg); - } - - ThrowTerminatingError(er); + reader?.Dispose(); } - if (_parseRelLink || _followRelLink) + if (!string.IsNullOrEmpty(detailMsg)) { - ParseLinkHeader(response); + er.ErrorDetails = new ErrorDetails(detailMsg); } - ProcessResponse(response); - UpdateSession(response); - - // If we hit our maximum redirection count, generate an error. - // Errors with redirection counts of greater than 0 are handled automatically by .NET, but are - // impossible to detect programmatically when we hit this limit. By handling this ourselves - // (and still writing out the result), users can debug actual HTTP redirect problems. - if (WebSession.MaximumRedirection == 0 && IsRedirectCode(response.StatusCode)) - { - ErrorRecord er = new(new InvalidOperationException(), "MaximumRedirectExceeded", ErrorCategory.InvalidOperation, request); - er.ErrorDetails = new ErrorDetails(WebCmdletStrings.MaximumRedirectionCountExceeded); - WriteError(er); - } + ThrowTerminatingError(er); } - catch (HttpRequestException ex) - { - ErrorRecord er = new(ex, "WebCmdletWebResponseException", ErrorCategory.InvalidOperation, request); - if (ex.InnerException is not null) - { - er.ErrorDetails = new ErrorDetails(ex.InnerException.Message); - } - ThrowTerminatingError(er); + if (_parseRelLink || _followRelLink) + { + ParseLinkHeader(response); } - if (_followRelLink && _relationLink is not null) + ProcessResponse(response); + UpdateSession(response); + + // If we hit our maximum redirection count, generate an error. + // Errors with redirection counts of greater than 0 are handled automatically by .NET, but are + // impossible to detect programmatically when we hit this limit. By handling this ourselves + // (and still writing out the result), users can debug actual HTTP redirect problems. + if (WebSession.MaximumRedirection == 0 && IsRedirectCode(response.StatusCode)) { - if (!_relationLink.ContainsKey("next")) - { - return; - } + ErrorRecord er = new(new InvalidOperationException(), "MaximumRedirectExceeded", ErrorCategory.InvalidOperation, request); + er.ErrorDetails = new ErrorDetails(WebCmdletStrings.MaximumRedirectionCountExceeded); + WriteError(er); + } + } + catch (HttpRequestException ex) + { + ErrorRecord er = new(ex, "WebCmdletWebResponseException", ErrorCategory.InvalidOperation, request); + if (ex.InnerException is not null) + { + er.ErrorDetails = new ErrorDetails(ex.InnerException.Message); + } + + ThrowTerminatingError(er); + } - uri = new Uri(_relationLink["next"]); - followedRelLink++; + if (_followRelLink && _relationLink is not null) + { + if (!_relationLink.ContainsKey("next")) + { + return; } + + uri = new Uri(_relationLink["next"]); + followedRelLink++; } } - while (_followRelLink && (followedRelLink < _maximumFollowRelLink)); } + while (_followRelLink && (followedRelLink < _maximumFollowRelLink)); } catch (CryptographicException ex) { From 031cfcebf05a1581dc323f099098b2d2a5d65992 Mon Sep 17 00:00:00 2001 From: CarloToso <105941898+CarloToso@users.noreply.github.com> Date: Tue, 28 Feb 2023 19:27:50 +0100 Subject: [PATCH 30/40] forgot ; --- .../utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs index accf9a8c93f..6801aeab1c3 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs @@ -522,7 +522,7 @@ protected override void ProcessRecord() bool handleRedirect = keepAuthorizationOnRedirect || AllowInsecureRedirect || PreserveHttpMethodOnRedirect; - using HttpClient client = GetHttpClient(handleRedirect) + using HttpClient client = GetHttpClient(handleRedirect); int followedRelLink = 0; Uri? uri = Uri; From f5a46ae20f320178beeb53ea8e3f07d6e637345c Mon Sep 17 00:00:00 2001 From: CarloToso <105941898+CarloToso@users.noreply.github.com> Date: Wed, 1 Mar 2023 00:20:37 +0100 Subject: [PATCH 31/40] Follow suggestions [DisallowNull] --- .../Common/WebRequestPSCmdlet.Common.cs | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs index 6801aeab1c3..71be8430379 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs @@ -146,7 +146,8 @@ public abstract class WebRequestPSCmdlet : PSCmdlet /// [Parameter(Position = 0, Mandatory = true)] [ValidateNotNullOrEmpty] - public virtual Uri? Uri { get; set; } + [System.Diagnostics.CodeAnalysis.DisallowNullAttribute] + public virtual Uri Uri { get; set; } #endregion URI @@ -168,6 +169,7 @@ public abstract class WebRequestPSCmdlet : PSCmdlet /// [Parameter] [ValidateNotNull] + [System.Diagnostics.CodeAnalysis.DisallowNullAttribute] public virtual WebRequestSession WebSession { get; set; } = new WebRequestSession(); /// @@ -525,7 +527,7 @@ protected override void ProcessRecord() using HttpClient client = GetHttpClient(handleRedirect); int followedRelLink = 0; - Uri? uri = Uri; + Uri uri = Uri; do { if (followedRelLink > 0) @@ -533,7 +535,7 @@ protected override void ProcessRecord() string linkVerboseMsg = string.Format( CultureInfo.CurrentCulture, WebCmdletStrings.FollowingRelLinkVerboseMsg, - uri?.AbsoluteUri); + uri.AbsoluteUri); WriteVerbose(linkVerboseMsg); } @@ -1001,9 +1003,9 @@ internal virtual HttpClient GetHttpClient(bool handleRedirect) return httpClient; } - internal virtual HttpRequestMessage GetRequest(Uri? uri) + internal virtual HttpRequestMessage GetRequest(Uri uri) { - Uri? requestUri = PrepareUri(uri); + Uri requestUri = PrepareUri(uri); HttpMethod httpMethod = string.IsNullOrEmpty(CustomMethod) ? GetHttpMethod(Method) : new HttpMethod(CustomMethod); // Create the base WebRequest object @@ -1352,7 +1354,7 @@ internal virtual void UpdateSession(HttpResponseMessage response) #endregion Virtual Methods #region Helper Methods - private Uri PrepareUri(Uri? uri) + private Uri PrepareUri(Uri uri) { uri = CheckProtocol(uri); @@ -1380,9 +1382,9 @@ private Uri PrepareUri(Uri? uri) return uri; } - private static Uri CheckProtocol(Uri? uri) + private static Uri CheckProtocol(Uri uri) { - return uri is not null && uri.IsAbsoluteUri ? uri : new Uri("http://" + uri?.OriginalString); + return uri.IsAbsoluteUri ? uri : new Uri("http://" + uri.OriginalString); } private string QualifyFilePath(string? path) => PathUtils.ResolveFilePath(filePath: path, command: this, isLiteralPath: true); From d3d4f3b9eb3e7c75320a773f96d69eebeb503559 Mon Sep 17 00:00:00 2001 From: CarloToso <105941898+CarloToso@users.noreply.github.com> Date: Wed, 1 Mar 2023 00:29:56 +0100 Subject: [PATCH 32/40] add nameof() --- .../utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs index 71be8430379..06ea0ca0d52 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs @@ -695,7 +695,7 @@ protected override void ProcessRecord() internal virtual void ValidateParameters() { // Sessions - if (MyInvocation.BoundParameters.ContainsKey("WebSession") && MyInvocation.BoundParameters.ContainsKey("SessionVariable")) + if (MyInvocation.BoundParameters.ContainsKey(nameof(WebSession)) && MyInvocation.BoundParameters.ContainsKey(nameof(SessionVariable))) { ErrorRecord error = GetValidationError(WebCmdletStrings.SessionConflict, "WebCmdletSessionConflictException"); ThrowTerminatingError(error); From 433f9fa356566b606b11fce2ef207c3f44bce490 Mon Sep 17 00:00:00 2001 From: CarloToso <105941898+CarloToso@users.noreply.github.com> Date: Wed, 1 Mar 2023 00:48:58 +0100 Subject: [PATCH 33/40] null! --- .../utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs index 06ea0ca0d52..9dcb0323d37 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs @@ -147,7 +147,7 @@ public abstract class WebRequestPSCmdlet : PSCmdlet [Parameter(Position = 0, Mandatory = true)] [ValidateNotNullOrEmpty] [System.Diagnostics.CodeAnalysis.DisallowNullAttribute] - public virtual Uri Uri { get; set; } + public virtual Uri Uri { get; set; } = null!; #endregion URI From 015c70855798b419ca629a96be4111f63ad9abe2 Mon Sep 17 00:00:00 2001 From: CarloToso <105941898+CarloToso@users.noreply.github.com> Date: Wed, 1 Mar 2023 01:19:53 +0100 Subject: [PATCH 34/40] revert some changes --- .../WebCmdlet/Common/WebRequestPSCmdlet.Common.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs index 9dcb0323d37..b963ded185b 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs @@ -1003,9 +1003,9 @@ internal virtual HttpClient GetHttpClient(bool handleRedirect) return httpClient; } - internal virtual HttpRequestMessage GetRequest(Uri uri) + internal virtual HttpRequestMessage GetRequest(Uri? uri) { - Uri requestUri = PrepareUri(uri); + Uri? requestUri = PrepareUri(uri); HttpMethod httpMethod = string.IsNullOrEmpty(CustomMethod) ? GetHttpMethod(Method) : new HttpMethod(CustomMethod); // Create the base WebRequest object @@ -1354,7 +1354,7 @@ internal virtual void UpdateSession(HttpResponseMessage response) #endregion Virtual Methods #region Helper Methods - private Uri PrepareUri(Uri uri) + private Uri PrepareUri(Uri? uri) { uri = CheckProtocol(uri); @@ -1382,9 +1382,9 @@ private Uri PrepareUri(Uri uri) return uri; } - private static Uri CheckProtocol(Uri uri) + private static Uri CheckProtocol(Uri? uri) { - return uri.IsAbsoluteUri ? uri : new Uri("http://" + uri.OriginalString); + return uri is not null && uri.IsAbsoluteUri ? uri : new Uri("http://" + uri?.OriginalString); } private string QualifyFilePath(string? path) => PathUtils.ResolveFilePath(filePath: path, command: this, isLiteralPath: true); From 65af8a6e9de352ff99e4f15a9a62c41e9665ef6e Mon Sep 17 00:00:00 2001 From: CarloToso <105941898+CarloToso@users.noreply.github.com> Date: Tue, 7 Mar 2023 20:12:51 +0100 Subject: [PATCH 35/40] Websession = null! --- .../utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs index 4757ded8cf1..d28193251bd 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs @@ -710,7 +710,7 @@ protected virtual void Dispose(bool disposing) if (disposing && !IsPersistentSession()) { WebSession?.Dispose(); - WebSession = null; + WebSession = null!; } _disposed = true; From 3e342f4b88e9c401b41184373dd751b4cd67734b Mon Sep 17 00:00:00 2001 From: CarloToso <105941898+CarloToso@users.noreply.github.com> Date: Tue, 7 Mar 2023 20:19:03 +0100 Subject: [PATCH 36/40] remove spaces --- .../utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs index d28193251bd..23aa6207e6c 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs @@ -1404,7 +1404,7 @@ private static Uri CheckProtocol(Uri? uri) } private string QualifyFilePath(string? path) => PathUtils.ResolveFilePath(filePath: path, command: this, isLiteralPath: true); - + private static string FormatDictionary(IDictionary content) { ArgumentNullException.ThrowIfNull(content); From e5a92d65783fa87323ee94c4384a4491ede55484 Mon Sep 17 00:00:00 2001 From: CarloToso <105941898+CarloToso@users.noreply.github.com> Date: Mon, 24 Apr 2023 10:18:05 +0200 Subject: [PATCH 37/40] some fixes --- .../utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs | 4 ++-- .../commands/utility/WebCmdlet/StreamHelper.cs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs index 3fbe182cef2..6d3a0ddf474 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs @@ -491,7 +491,7 @@ public virtual string? CustomMethod internal string QualifiedOutFile => QualifyFilePath(OutFile); - internal string _qualifiedOutFile; + internal string? _qualifiedOutFile; internal bool ShouldCheckHttpStatus => !SkipHttpErrorCheck; @@ -572,7 +572,7 @@ protected override void ProcessRecord() using HttpResponseMessage response = GetResponse(client, request, handleRedirect); - string contentType = ContentHelper.GetContentType(response); + string? contentType = ContentHelper.GetContentType(response); long? contentLength = response.Content.Headers.ContentLength; string respVerboseMsg = contentLength is null ? string.Format(CultureInfo.CurrentCulture, WebCmdletStrings.WebResponseNoSizeVerboseMsg, contentType) diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/StreamHelper.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/StreamHelper.cs index 6d217cdc909..532338f3d7c 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/StreamHelper.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/StreamHelper.cs @@ -451,7 +451,7 @@ internal static bool TryGetEncoding(string? characterSet, out Encoding encoding) RegexOptions.Compiled | RegexOptions.Singleline | RegexOptions.ExplicitCapture | RegexOptions.CultureInvariant | RegexOptions.IgnoreCase | RegexOptions.NonBacktracking ); - internal static byte[] EncodeToBytes(string str, Encoding encoding) + internal static byte[] EncodeToBytes(string str, Encoding? encoding) { // Just use the default encoding if one wasn't provided encoding ??= ContentHelper.GetDefaultEncoding(); From cd03c66a3ef794f29480f31650d744d6609e75ed Mon Sep 17 00:00:00 2001 From: CarloToso <105941898+CarloToso@users.noreply.github.com> Date: Mon, 24 Apr 2023 10:19:34 +0200 Subject: [PATCH 38/40] Update src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs Co-authored-by: Ilya --- .../utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs index 6d3a0ddf474..33495bb9a7c 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs @@ -775,7 +775,7 @@ internal virtual void ValidateParameters() ThrowTerminatingError(error); } - if (!AllowUnencryptedAuthentication && (Authentication != WebAuthenticationType.None || Credential is not null || UseDefaultCredentials) && Uri?.Scheme != "https") + if (!AllowUnencryptedAuthentication && (Authentication != WebAuthenticationType.None || Credential is not null || UseDefaultCredentials) && Uri.Scheme != "https") { ErrorRecord error = GetValidationError(WebCmdletStrings.AllowUnencryptedAuthenticationRequired, "WebCmdletAllowUnencryptedAuthenticationRequiredException"); ThrowTerminatingError(error); From 5a9d5727e32aee066fbe1c1549c55d15e833745c Mon Sep 17 00:00:00 2001 From: CarloToso <105941898+CarloToso@users.noreply.github.com> Date: Mon, 24 Apr 2023 10:27:27 +0200 Subject: [PATCH 39/40] more fixes --- .../utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs index 33495bb9a7c..498b7755e01 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs @@ -603,7 +603,7 @@ protected override void ProcessRecord() { // We will skip detection if either of the URIs is relative, because the 'Scheme' property is not supported on a relative URI. // If we have to skip the check, an error may be thrown later if it's actually an insecure https-to-http redirect. - bool originIsHttps = response.RequestMessage.RequestUri.IsAbsoluteUri && response.RequestMessage.RequestUri.Scheme == "https"; + bool originIsHttps = response.RequestMessage?.RequestUri is not null && response.RequestMessage.RequestUri.IsAbsoluteUri && response.RequestMessage.RequestUri.Scheme == "https"; bool destinationIsHttp = response.Headers.Location is not null && response.Headers.Location.IsAbsoluteUri && response.Headers.Location.Scheme == "http"; if (originIsHttps && destinationIsHttp) @@ -1772,7 +1772,7 @@ private static StreamContent GetMultipartFileContent(object fieldName, FileInfo return result; } - private static string FormatErrorMessage(string error, string contentType) + private static string FormatErrorMessage(string error, string? contentType) { string? formattedError = null; From c5e9016453342a26d728cc6b261783bf3b2156fb Mon Sep 17 00:00:00 2001 From: CarloToso <105941898+CarloToso@users.noreply.github.com> Date: Mon, 24 Apr 2023 15:16:41 +0200 Subject: [PATCH 40/40] _qualifiedOutFile [AllowNull] --- .../WebCmdlet/Common/WebRequestPSCmdlet.Common.cs | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs index 498b7755e01..415564ffd21 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs @@ -7,6 +7,7 @@ using System.Collections; using System.Collections.Generic; using System.Collections.ObjectModel; +using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.IO; using System.Management.Automation; @@ -156,7 +157,7 @@ public abstract class WebRequestPSCmdlet : PSCmdlet, IDisposable /// [Parameter(Position = 0, Mandatory = true)] [ValidateNotNullOrEmpty] - [System.Diagnostics.CodeAnalysis.DisallowNullAttribute] + [DisallowNull] public virtual Uri Uri { get; set; } = null!; #endregion URI @@ -179,7 +180,7 @@ public abstract class WebRequestPSCmdlet : PSCmdlet, IDisposable /// [Parameter] [ValidateNotNull] - [System.Diagnostics.CodeAnalysis.DisallowNullAttribute] + [DisallowNull] public virtual WebRequestSession WebSession { get; set; } = new WebRequestSession(); /// @@ -281,7 +282,7 @@ public abstract class WebRequestPSCmdlet : PSCmdlet, IDisposable /// /// Gets or sets the Headers property. /// - [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")] + [SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")] [Parameter] public virtual IDictionary? Headers { get; set; } @@ -358,7 +359,7 @@ public abstract class WebRequestPSCmdlet : PSCmdlet, IDisposable [Parameter(Mandatory = true, ParameterSetName = "CustomMethodNoProxy")] [Alias("CM")] [ValidateNotNullOrEmpty] - [System.Diagnostics.CodeAnalysis.DisallowNullAttribute] + [DisallowNull] public virtual string? CustomMethod { get => _custommethod; @@ -491,7 +492,8 @@ public virtual string? CustomMethod internal string QualifiedOutFile => QualifyFilePath(OutFile); - internal string? _qualifiedOutFile; + [System.Diagnostics.CodeAnalysis.AllowNull] + internal string _qualifiedOutFile; internal bool ShouldCheckHttpStatus => !SkipHttpErrorCheck;