Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
3c1221f
content helper nullable
CarloToso Mar 16, 2023
e59425b
webresponseobject nullable
CarloToso Mar 16, 2023
68fc544
stream helper nullable
CarloToso Mar 16, 2023
d727763
webproxy nullable
CarloToso Mar 16, 2023
8b558e3
fixes
CarloToso Mar 16, 2023
e8fefea
nullable headernames
CarloToso Mar 16, 2023
a4b1103
nullable invokerestmethod
CarloToso Mar 16, 2023
07f1104
nullable webcmdletelementcollection
CarloToso Mar 16, 2023
fe375e8
fixes
CarloToso Mar 17, 2023
815e673
psuseragent nullable
CarloToso Mar 17, 2023
19016a7
webresponseobjectfactory nullable
CarloToso Mar 17, 2023
cf1790c
formobject nullable
CarloToso Mar 17, 2023
522c630
formobjectcollection nullable
CarloToso Mar 17, 2023
ea74629
small changes
CarloToso Mar 17, 2023
ec5af71
basichtmlresponseobject nullable WIP
CarloToso Mar 17, 2023
c329321
!TryGetEncoding(characterSet, out encoding);
CarloToso Mar 17, 2023
1328a0f
Merge branch 'master' into nullable-webcmdlets
CarloToso Mar 18, 2023
cfcd17f
Update src/Microsoft.PowerShell.Commands.Utility/commands/utility/Web…
CarloToso Mar 18, 2023
6a0846d
Update src/Microsoft.PowerShell.Commands.Utility/commands/utility/Web…
CarloToso Mar 18, 2023
39668e2
[MemberNotNull]; [NotNullWhen]
CarloToso Mar 18, 2023
5df97cc
add back BasicHtmlWebResponseObject and WebResponseObject
CarloToso Mar 18, 2023
02539dd
[NotNullWhen(true)]
CarloToso Mar 19, 2023
55be121
Merge branch 'master' into nullable-webcmdlets
CarloToso Mar 20, 2023
ba590b9
[NotNullWhen(true)]
CarloToso Mar 20, 2023
1d2d715
revert
CarloToso Mar 20, 2023
91dccf8
[SuppressMessage]
CarloToso Mar 20, 2023
6414309
InvokeWebRequestCommand
CarloToso Mar 20, 2023
48ae8df
Update src/Microsoft.PowerShell.Commands.Utility/commands/utility/Web…
CarloToso Mar 21, 2023
af1add5
merge
CarloToso Mar 21, 2023
c7e4b73
merge
CarloToso Mar 24, 2023
279abf6
Merge branch 'PowerShell:master' into nullable-webcmdlets
CarloToso Mar 24, 2023
027bb41
add formobject
CarloToso Mar 29, 2023
5ee0696
new syntax
CarloToso Mar 29, 2023
1062864
[NotNullWhen(true)]
CarloToso Mar 29, 2023
8652eaf
follow suggestions
CarloToso Mar 29, 2023
585d7e0
WebResponseHelper.CoreClr nullable enable
CarloToso Mar 29, 2023
64af5c8
remove ArgumentException.ThrowIfNullOrEmpty(characterSet);
CarloToso Mar 31, 2023
b33f28a
Encoding.GetEncoding(characterSet!)
CarloToso Apr 1, 2023
0070ddc
fix
CarloToso Apr 1, 2023
d6abd7d
Merge branch 'master' into nullable-webcmdlets
CarloToso Apr 4, 2023
2705e66
Merge branch 'PowerShell:master' into nullable-webcmdlets
CarloToso Apr 23, 2023
0546067
fix codefactor
CarloToso Apr 23, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

#nullable enable

using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Management.Automation;
using System.Net.Http;
Expand Down Expand Up @@ -33,7 +36,7 @@ public BasicHtmlWebResponseObject(HttpResponseMessage response, CancellationToke
/// <param name="response">The response.</param>
/// <param name="contentStream">The content stream associated with the response.</param>
/// <param name="cancellationToken">Cancellation token.</param>
public BasicHtmlWebResponseObject(HttpResponseMessage response, Stream contentStream, CancellationToken cancellationToken) : base(response, contentStream, cancellationToken)
public BasicHtmlWebResponseObject(HttpResponseMessage response, Stream? contentStream, CancellationToken cancellationToken) : base(response, contentStream, cancellationToken)
{
InitializeContent(cancellationToken);
InitializeRawContent(response);
Expand All @@ -60,9 +63,9 @@ public BasicHtmlWebResponseObject(HttpResponseMessage response, Stream contentSt
/// Encoding of the response body from the <c>Content-Type</c> header,
/// or <see langword="null"/> if the encoding could not be determined.
/// </value>
public Encoding Encoding { get; private set; }
public Encoding? Encoding { get; private set; }

private WebCmdletElementCollection _inputFields;
private WebCmdletElementCollection? _inputFields;

/// <summary>
/// Gets the HTML input field elements parsed from <see cref="Content"/>.
Expand All @@ -87,7 +90,7 @@ public WebCmdletElementCollection InputFields
}
}

private WebCmdletElementCollection _links;
private WebCmdletElementCollection? _links;

/// <summary>
/// Gets the HTML a link elements parsed from <see cref="Content"/>.
Expand All @@ -112,7 +115,7 @@ public WebCmdletElementCollection Links
}
}

private WebCmdletElementCollection _images;
private WebCmdletElementCollection? _images;

/// <summary>
/// Gets the HTML img elements parsed from <see cref="Content"/>.
Expand Down Expand Up @@ -145,13 +148,14 @@ public WebCmdletElementCollection Images
/// Reads the response content from the web response.
/// </summary>
/// <param name="cancellationToken">The cancellation token.</param>
[MemberNotNull(nameof(Content))]
protected void InitializeContent(CancellationToken cancellationToken)
{
string contentType = ContentHelper.GetContentType(BaseResponse);
string? contentType = ContentHelper.GetContentType(BaseResponse);
if (ContentHelper.IsText(contentType))
{
// Fill the Content buffer
string characterSet = WebResponseHelper.GetCharacterSet(BaseResponse);
string? characterSet = WebResponseHelper.GetCharacterSet(BaseResponse);

Content = StreamHelper.DecodeStream(RawContentStream, characterSet, out Encoding encoding, cancellationToken);
Encoding = encoding;
Expand Down Expand Up @@ -204,7 +208,7 @@ private static void ParseAttributes(string outerHtml, PSObject elementObject)
string name = nvMatches.Groups[1].Value;

// The value (if any) is captured by group #2, #3, or #4, depending on quoting or lack thereof
string value = null;
string? value = null;
if (nvMatches.Groups[2].Success)
{
value = nvMatches.Groups[2].Value;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

#nullable enable

using System;
using System.Diagnostics.CodeAnalysis;
using System.Management.Automation;
using System.Net.Http;
using System.Net.Http.Headers;
Expand All @@ -16,7 +19,7 @@ internal static class ContentHelper
#region Internal Methods

// ContentType may not exist in response header. Return null if not.
internal static string GetContentType(HttpResponseMessage response) => response.Content.Headers.ContentType?.MediaType;
internal static string? GetContentType(HttpResponseMessage response) => response.Content.Headers.ContentType?.MediaType;

internal static Encoding GetDefaultEncoding() => Encoding.UTF8;

Expand All @@ -35,7 +38,7 @@ internal static StringBuilder GetRawContentHeader(HttpResponseMessage response)
HttpHeaders[] headerCollections =
{
response.Headers,
response.Content?.Headers
response.Content.Headers
};

foreach (var headerCollection in headerCollections)
Expand All @@ -59,7 +62,7 @@ internal static StringBuilder GetRawContentHeader(HttpResponseMessage response)
return raw;
}

internal static bool IsJson(string contentType)
internal static bool IsJson([NotNullWhen(true)] string? contentType)
{
if (string.IsNullOrEmpty(contentType))
{
Expand All @@ -80,7 +83,7 @@ internal static bool IsJson(string contentType)
return isJson;
}

internal static bool IsText(string contentType)
internal static bool IsText([NotNullWhen(true)] string? contentType)
{
if (string.IsNullOrEmpty(contentType))
{
Expand All @@ -96,19 +99,18 @@ internal static bool IsText(string contentType)
if (Platform.IsWindows && !isText)
{
// Media types registered with Windows as having a perceived type of text, are text
using (RegistryKey contentTypeKey = Registry.ClassesRoot.OpenSubKey(@"MIME\Database\Content Type\" + contentType))
using (RegistryKey? contentTypeKey = Registry.ClassesRoot.OpenSubKey(@"MIME\Database\Content Type\" + contentType))
{
if (contentTypeKey != null)
{
string extension = contentTypeKey.GetValue("Extension") as string;
if (extension != null)
if (contentTypeKey.GetValue("Extension") is string extension)
{
using (RegistryKey extensionKey = Registry.ClassesRoot.OpenSubKey(extension))
using (RegistryKey? extensionKey = Registry.ClassesRoot.OpenSubKey(extension))
{
if (extensionKey != null)
{
string perceivedType = extensionKey.GetValue("PerceivedType") as string;
isText = (perceivedType == "text");
string? perceivedType = extensionKey.GetValue("PerceivedType") as string;
isText = perceivedType == "text";
}
}
}
Expand All @@ -119,7 +121,7 @@ internal static bool IsText(string contentType)
return isText;
}

internal static bool IsXml(string contentType)
internal static bool IsXml([NotNullWhen(true)] string? contentType)
{
if (string.IsNullOrEmpty(contentType))
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

#nullable enable

using System;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Management.Automation;
using System.Net.Http;
Expand Down Expand Up @@ -56,13 +59,13 @@ public int MaximumFollowRelLink
/// </summary>
[Parameter]
[Alias("RHV")]
public string ResponseHeadersVariable { get; set; }
public string? ResponseHeadersVariable { get; set; }

/// <summary>
/// Gets or sets the variable name to use for storing the status code from the response.
/// </summary>
[Parameter]
public string StatusCodeVariable { get; set; }
public string? StatusCodeVariable { get; set; }

#endregion Parameters

Expand Down Expand Up @@ -95,12 +98,12 @@ internal override void ProcessResponse(HttpResponseMessage response)
RestReturnType returnType = CheckReturnType(response);

// Try to get the response encoding from the ContentType header.
string charSet = WebResponseHelper.GetCharacterSet(response);
string? characterSet = WebResponseHelper.GetCharacterSet(response);

string str = StreamHelper.DecodeStream(responseStream, charSet, out Encoding encoding, _cancelToken.Token);
string str = StreamHelper.DecodeStream(responseStream, characterSet, out Encoding encoding, _cancelToken.Token);

object obj = null;
Exception ex = null;
object? obj = null;
Exception? ex = null;

string encodingVerboseName;
try
Expand Down Expand Up @@ -167,7 +170,7 @@ private static RestReturnType CheckReturnType(HttpResponseMessage response)
ArgumentNullException.ThrowIfNull(response);

RestReturnType rt = RestReturnType.Detect;
string contentType = ContentHelper.GetContentType(response);
string? contentType = ContentHelper.GetContentType(response);
if (string.IsNullOrEmpty(contentType))
{
rt = RestReturnType.Detect;
Expand Down Expand Up @@ -223,7 +226,7 @@ private bool TryProcessFeedStream(Stream responseStream)
)
{
// This one will do reader.Read() internally
XmlNode result = workingDocument.ReadNode(reader);
XmlNode? result = workingDocument.ReadNode(reader);
WriteObject(result);
}
else
Expand Down Expand Up @@ -262,7 +265,7 @@ private static XmlReaderSettings GetSecureXmlReaderSettings()
return xrs;
}

private static bool TryConvertToXml(string xml, out object doc, ref Exception exRef)
private static bool TryConvertToXml(string xml, [NotNullWhen(true)] out object? doc, ref Exception? exRef)
{
try
{
Expand All @@ -284,13 +287,12 @@ private static bool TryConvertToXml(string xml, out object doc, ref Exception ex
return doc != null;
}

private static bool TryConvertToJson(string json, out object obj, ref Exception exRef)
private static bool TryConvertToJson(string json, [NotNullWhen(true)] out object? obj, ref Exception? exRef)
{
bool converted = false;
try
{
ErrorRecord error;
obj = JsonObject.ConvertFromJson(json, out error);
obj = JsonObject.ConvertFromJson(json, out ErrorRecord error);

if (obj == null)
{
Expand Down Expand Up @@ -340,7 +342,7 @@ public enum RestReturnType
/// <summary>
/// Json return type.
/// </summary>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly")]
[SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly")]
Json,

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

#nullable enable

using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
Expand All @@ -26,22 +28,22 @@ public class WebResponseObject
/// <summary>
/// Gets or protected sets the response body content.
/// </summary>
public byte[] Content { get; protected set; }
public byte[]? Content { get; protected set; }

/// <summary>
/// Gets the Headers property.
/// </summary>
public Dictionary<string, IEnumerable<string>> Headers => _headers ??= WebResponseHelper.GetHeadersDictionary(BaseResponse);

private Dictionary<string, IEnumerable<string>> _headers = null;
private Dictionary<string, IEnumerable<string>>? _headers;

/// <summary>
/// Gets or protected sets the full response content.
/// </summary>
/// <value>
/// Full response content, including the HTTP status line, headers, and body.
/// </value>
public string RawContent { get; protected set; }
public string? RawContent { get; protected set; }

/// <summary>
/// Gets the length (in bytes) of <see cref="RawContentStream"/>.
Expand All @@ -56,7 +58,7 @@ public class WebResponseObject
/// <summary>
/// Gets the RelationLink property.
/// </summary>
public Dictionary<string, string> RelationLink { get; internal set; }
public Dictionary<string, string>? RelationLink { get; internal set; }

/// <summary>
/// Gets the response status code.
Expand All @@ -77,8 +79,7 @@ public class WebResponseObject
/// </summary>
/// <param name="response">The Http response.</param>
/// <param name="cancellationToken">The cancellation token.</param>
public WebResponseObject(HttpResponseMessage response, CancellationToken cancellationToken) : this(response, null, cancellationToken)
{ }
public WebResponseObject(HttpResponseMessage response, CancellationToken cancellationToken) : this(response, null, cancellationToken) { }

/// <summary>
/// Initializes a new instance of the <see cref="WebResponseObject"/> class
Expand All @@ -87,7 +88,7 @@ public WebResponseObject(HttpResponseMessage response, CancellationToken cancell
/// <param name="response">Http response.</param>
/// <param name="contentStream">The http content stream.</param>
/// <param name="cancellationToken">The cancellation token.</param>
public WebResponseObject(HttpResponseMessage response, Stream contentStream, CancellationToken cancellationToken)
public WebResponseObject(HttpResponseMessage response, Stream? contentStream, CancellationToken cancellationToken)
{
SetResponse(response, contentStream, cancellationToken);
InitializeContent();
Expand All @@ -111,9 +112,9 @@ private void InitializeRawContent(HttpResponseMessage baseResponse)
StringBuilder raw = ContentHelper.GetRawContentHeader(baseResponse);

// Use ASCII encoding for the RawContent visual view of the content.
if (Content.Length > 0)
if (Content?.Length > 0)
{
raw.Append(this.ToString());
raw.Append(ToString());
}

RawContent = raw.ToString();
Expand All @@ -125,26 +126,23 @@ private static bool IsPrintable(char c) => char.IsLetterOrDigit(c)
|| char.IsSymbol(c)
|| char.IsWhiteSpace(c);

private void SetResponse(HttpResponseMessage response, Stream contentStream, CancellationToken cancellationToken)
[MemberNotNull(nameof(RawContentStream))]
[MemberNotNull(nameof(BaseResponse))]
private void SetResponse(HttpResponseMessage response, Stream? contentStream, CancellationToken cancellationToken)
{
ArgumentNullException.ThrowIfNull(response);

BaseResponse = response;

MemoryStream ms = contentStream as MemoryStream;
if (ms is not null)
if (contentStream is MemoryStream ms)
{
RawContentStream = ms;
}
else
{
Stream st = contentStream;
if (contentStream is null)
{
st = StreamHelper.GetResponseStream(response, cancellationToken);
}
Stream st = contentStream ?? StreamHelper.GetResponseStream(response, cancellationToken);

long contentLength = response.Content.Headers.ContentLength.Value;
long contentLength = response.Content.Headers.ContentLength.GetValueOrDefault();
if (contentLength <= 0)
{
contentLength = StreamHelper.DefaultReadBuffer;
Expand All @@ -164,7 +162,12 @@ private void SetResponse(HttpResponseMessage response, Stream contentStream, Can
/// <returns>The string representation of this web response.</returns>
public sealed override string ToString()
{
char[] stringContent = System.Text.Encoding.ASCII.GetChars(Content);
if (Content is null)
{
return string.Empty;
}

char[] stringContent = Encoding.ASCII.GetChars(Content);
for (int counter = 0; counter < stringContent.Length; counter++)
{
if (!IsPrintable(stringContent[counter]))
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

#nullable enable

using System;
using System.Collections.Generic;

Expand Down
Loading