Rework SetRequestContent in WebCmdlets (#18964)

This commit is contained in:
CarloToso authored and GitHub committed 2023-02-01 21:56:49 +05:00
1 parent dd406b512a
commit c87f2a48fd
1 file changed
+47 -82
@@ -1089,9 +1089,6 @@ namespace Microsoft.PowerShell.Commands
if (Form is not null)
{
// Content headers will be set by MultipartFormDataContent which will throw unless we clear them first
WebSession.ContentHeaders.Clear();
var formData = new MultipartFormDataContent();
foreach (DictionaryEntry formEntry in Form)
{
@@ -1101,55 +1098,48 @@ namespace Microsoft.PowerShell.Commands
SetRequestContent(request, formData);
}
// coerce body into a usable form
else if (Body is not null)
{
// Coerce body into a usable form
object content = Body;
// make sure we're using the base object of the body, not the PSObject wrapper
PSObject psBody = Body as PSObject;
if (psBody is not null)
// Make sure we're using the base object of the body, not the PSObject wrapper
if (Body is PSObject psBody)
{
content = psBody.BaseObject;
}
if (content is FormObject form)
switch (content)
{
SetRequestContent(request, form.Fields);
}
else if (content is IDictionary dictionary && request.Method != HttpMethod.Get)
{
SetRequestContent(request, dictionary);
}
else if (content is XmlNode xmlNode)
{
SetRequestContent(request, xmlNode);
}
else if (content is Stream stream)
{
SetRequestContent(request, stream);
}
else if (content is byte[] bytes)
{
SetRequestContent(request, bytes);
}
else if (content is MultipartFormDataContent multipartFormDataContent)
{
WebSession.ContentHeaders.Clear();
SetRequestContent(request, multipartFormDataContent);
}
else
{
SetRequestContent(
request,
(string)LanguagePrimitives.ConvertTo(content, typeof(string), CultureInfo.InvariantCulture));
case FormObject form:
SetRequestContent(request, form.Fields);
break;
case IDictionary dictionary when request.Method != HttpMethod.Get:
SetRequestContent(request, dictionary);
break;
case XmlNode xmlNode:
SetRequestContent(request, xmlNode);
break;
case Stream stream:
SetRequestContent(request, stream);
break;
case byte[] bytes:
SetRequestContent(request, bytes);
break;
case MultipartFormDataContent multipartFormDataContent:
SetRequestContent(request, multipartFormDataContent);
break;
default:
SetRequestContent(request, (string)LanguagePrimitives.ConvertTo(content, typeof(string), CultureInfo.InvariantCulture));
break;
}
}
else if (InFile is not null) // copy InFile data
else if (InFile is not null)
{
// Copy InFile data
try
{
// open the input file
// Open the input file
SetRequestContent(request, new FileStream(InFile, FileMode.Open, FileAccess.Read, FileShare.Read));
}
catch (UnauthorizedAccessException)
@@ -1574,24 +1564,17 @@ namespace Microsoft.PowerShell.Commands
/// </summary>
/// <param name="request">The WebRequest who's content is to be set.</param>
/// <param name="content">A byte array containing the content data.</param>
/// <returns>The number of bytes written to the requests RequestStream (and the new value of the request's ContentLength property.</returns>
/// <remarks>
/// Because this function sets the request's ContentLength property and writes content data into the requests's stream,
/// it should be called one time maximum on a given request.
/// </remarks>
internal long SetRequestContent(HttpRequestMessage request, byte[] content)
internal void SetRequestContent(HttpRequestMessage request, byte[] content)
{
ArgumentNullException.ThrowIfNull(request);
ArgumentNullException.ThrowIfNull(content);
if (content is null)
{
return 0;
}
var byteArrayContent = new ByteArrayContent(content);
ByteArrayContent byteArrayContent = new(content);
request.Content = byteArrayContent;
return byteArrayContent.Headers.ContentLength.Value;
}
/// <summary>
@@ -1599,19 +1582,14 @@ namespace Microsoft.PowerShell.Commands
/// </summary>
/// <param name="request">The WebRequest who's content is to be set.</param>
/// <param name="content">A String object containing the content data.</param>
/// <returns>The number of bytes written to the requests RequestStream (and the new value of the request's ContentLength property.</returns>
/// <remarks>
/// Because this function sets the request's ContentLength property and writes content data into the requests's stream,
/// it should be called one time maximum on a given request.
/// </remarks>
internal long SetRequestContent(HttpRequestMessage request, string content)
internal void SetRequestContent(HttpRequestMessage request, string content)
{
ArgumentNullException.ThrowIfNull(request);
if (content is null)
{
return 0;
}
ArgumentNullException.ThrowIfNull(content);
Encoding encoding = null;
if (ContentType is not null)
@@ -1631,7 +1609,7 @@ namespace Microsoft.PowerShell.Commands
{
if (!SkipHeaderValidation)
{
var outerEx = new ValidationMetadataException(WebCmdletStrings.ContentTypeException, ex);
ValidationMetadataException outerEx = new(WebCmdletStrings.ContentTypeException, ex);
ErrorRecord er = new(outerEx, "WebCmdletContentTypeException", ErrorCategory.InvalidArgument, ContentType);
ThrowTerminatingError(er);
}
@@ -1639,20 +1617,14 @@ namespace Microsoft.PowerShell.Commands
}
byte[] bytes = StreamHelper.EncodeToBytes(content, encoding);
var byteArrayContent = new ByteArrayContent(bytes);
ByteArrayContent byteArrayContent = new(bytes);
request.Content = byteArrayContent;
return byteArrayContent.Headers.ContentLength.Value;
}
internal long SetRequestContent(HttpRequestMessage request, XmlNode xmlNode)
internal void SetRequestContent(HttpRequestMessage request, XmlNode xmlNode)
{
ArgumentNullException.ThrowIfNull(request);
if (xmlNode is null)
{
return 0;
}
ArgumentNullException.ThrowIfNull(xmlNode);
byte[] bytes = null;
XmlDocument doc = xmlNode as XmlDocument;
@@ -1667,10 +1639,9 @@ namespace Microsoft.PowerShell.Commands
bytes = StreamHelper.EncodeToBytes(xmlNode.OuterXml, encoding: null);
}
var byteArrayContent = new ByteArrayContent(bytes);
request.Content = byteArrayContent;
ByteArrayContent byteArrayContent = new(bytes);
return byteArrayContent.Headers.ContentLength.Value;
request.Content = byteArrayContent;
}
/// <summary>
@@ -1678,21 +1649,17 @@ namespace Microsoft.PowerShell.Commands
/// </summary>
/// <param name="request">The WebRequest who's content is to be set.</param>
/// <param name="contentStream">A Stream object containing the content data.</param>
/// <returns>The number of bytes written to the requests RequestStream (and the new value of the request's ContentLength property.</returns>
/// <remarks>
/// Because this function sets the request's ContentLength property and writes content data into the requests's stream,
/// it should be called one time maximum on a given request.
/// </remarks>
internal long SetRequestContent(HttpRequestMessage request, Stream contentStream)
internal void SetRequestContent(HttpRequestMessage request, Stream contentStream)
{
ArgumentNullException.ThrowIfNull(request);
ArgumentNullException.ThrowIfNull(contentStream);
var streamContent = new StreamContent(contentStream);
StreamContent streamContent = new(contentStream);
request.Content = streamContent;
return streamContent.Headers.ContentLength.Value;
}
/// <summary>
@@ -1700,30 +1667,28 @@ namespace Microsoft.PowerShell.Commands
/// </summary>
/// <param name="request">The WebRequest who's content is to be set.</param>
/// <param name="multipartContent">A MultipartFormDataContent object containing multipart/form-data content.</param>
/// <returns>The number of bytes written to the requests RequestStream (and the new value of the request's ContentLength property.</returns>
/// <remarks>
/// Because this function sets the request's ContentLength property and writes content data into the requests's stream,
/// it should be called one time maximum on a given request.
/// </remarks>
internal long SetRequestContent(HttpRequestMessage request, MultipartFormDataContent multipartContent)
internal void SetRequestContent(HttpRequestMessage request, MultipartFormDataContent multipartContent)
{
ArgumentNullException.ThrowIfNull(request);
ArgumentNullException.ThrowIfNull(multipartContent);
// Content headers will be set by MultipartFormDataContent which will throw unless we clear them first
WebSession.ContentHeaders.Clear();
request.Content = multipartContent;
return multipartContent.Headers.ContentLength.Value;
}
internal long SetRequestContent(HttpRequestMessage request, IDictionary content)
internal void SetRequestContent(HttpRequestMessage request, IDictionary content)
{
ArgumentNullException.ThrowIfNull(request);
ArgumentNullException.ThrowIfNull(content);
string body = FormatDictionary(content);
return SetRequestContent(request, body);
SetRequestContent(request, body);
}
internal void ParseLinkHeader(HttpResponseMessage response, System.Uri requestUri)