Skip to content

Commit c3ac21b

Browse files
markekrausTravisEz13
authored andcommitted
Combine Web Cmdlet Partial Class Files (#5612)
Reference #5610 This moves the partial class into a single file each. This code is purposely not sorted and the formatting is left alone to make this easier to review. There are cleanup actions planned in the referenced Issue.
1 parent 25617f1 commit c3ac21b

10 files changed

Lines changed: 1195 additions & 1236 deletions

src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/BasicHtmlWebResponseObject.Common.cs

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
using System.Text.RegularExpressions;
1111
using System.Collections.Generic;
1212
using System.Diagnostics;
13+
using System.Net.Http;
1314

1415
namespace Microsoft.PowerShell.Commands
1516
{
@@ -244,4 +245,48 @@ protected void InitializeContent()
244245

245246
#endregion Methods
246247
}
248+
249+
// TODO: Merge Partials
250+
251+
// <summary>
252+
/// Response object for html content without DOM parsing
253+
/// </summary>
254+
public partial class BasicHtmlWebResponseObject : WebResponseObject
255+
{
256+
#region Constructors
257+
258+
/// <summary>
259+
/// Constructor for BasicHtmlWebResponseObject
260+
/// </summary>
261+
/// <param name="response"></param>
262+
public BasicHtmlWebResponseObject(HttpResponseMessage response)
263+
: this(response, null)
264+
{ }
265+
266+
/// <summary>
267+
/// Constructor for HtmlWebResponseObject with memory stream
268+
/// </summary>
269+
/// <param name="response"></param>
270+
/// <param name="contentStream"></param>
271+
public BasicHtmlWebResponseObject(HttpResponseMessage response, Stream contentStream)
272+
: base(response, contentStream)
273+
{
274+
EnsureHtmlParser();
275+
InitializeContent();
276+
InitializeRawContent(response);
277+
}
278+
279+
#endregion Constructors
280+
281+
#region Methods
282+
283+
private void InitializeRawContent(HttpResponseMessage baseResponse)
284+
{
285+
StringBuilder raw = ContentHelper.GetRawContentHeader(baseResponse);
286+
raw.Append(Content);
287+
this.RawContent = raw.ToString();
288+
}
289+
290+
#endregion Methods
291+
}
247292
}

src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/ContentHelper.Common.cs

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@
66
using System.Management.Automation;
77
using System.Text;
88
using Microsoft.Win32;
9+
using System.Linq;
10+
using System.Net.Http;
11+
using System.Net.Http.Headers;
912

1013
namespace Microsoft.PowerShell.Commands
1114
{
@@ -150,4 +153,64 @@ private static bool CheckIsJson(string contentType)
150153

151154
#endregion Internal Helper Methods
152155
}
156+
157+
// TODO: merge Partials
158+
159+
internal static partial class ContentHelper
160+
{
161+
internal static Encoding GetEncoding(HttpResponseMessage response)
162+
{
163+
// ContentType may not exist in response header.
164+
string charSet = response.Content.Headers.ContentType?.CharSet;
165+
return GetEncodingOrDefault(charSet);
166+
}
167+
168+
internal static string GetContentType(HttpResponseMessage response)
169+
{
170+
// ContentType may not exist in response header. Return null if not.
171+
return response.Content.Headers.ContentType?.MediaType;
172+
}
173+
174+
internal static StringBuilder GetRawContentHeader(HttpResponseMessage response)
175+
{
176+
StringBuilder raw = new StringBuilder();
177+
178+
string protocol = WebResponseHelper.GetProtocol(response);
179+
if (!string.IsNullOrEmpty(protocol))
180+
{
181+
int statusCode = WebResponseHelper.GetStatusCode(response);
182+
string statusDescription = WebResponseHelper.GetStatusDescription(response);
183+
raw.AppendFormat("{0} {1} {2}", protocol, statusCode, statusDescription);
184+
raw.AppendLine();
185+
}
186+
187+
HttpHeaders[] headerCollections =
188+
{
189+
response.Headers,
190+
response.Content == null ? null : response.Content.Headers
191+
};
192+
193+
foreach (var headerCollection in headerCollections)
194+
{
195+
if (headerCollection == null)
196+
{
197+
continue;
198+
}
199+
foreach (var header in headerCollection)
200+
{
201+
// Headers may have multiple entries with different values
202+
foreach (var headerValue in header.Value)
203+
{
204+
raw.Append(header.Key);
205+
raw.Append(": ");
206+
raw.Append(headerValue);
207+
raw.AppendLine();
208+
}
209+
}
210+
}
211+
212+
raw.AppendLine();
213+
return raw;
214+
}
215+
}
153216
}

src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/InvokeRestMethodCommand.Common.cs

Lines changed: 125 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
using System.Xml;
99
using Newtonsoft.Json;
1010
using Newtonsoft.Json.Linq;
11+
using System.Net.Http;
12+
using System.Text;
1113

1214
namespace Microsoft.PowerShell.Commands
1315
{
@@ -343,4 +345,126 @@ public override void Write(byte[] buffer, int offset, int count)
343345
}
344346
}
345347
}
346-
}
348+
349+
// TODO: Merge Partials
350+
351+
/// <summary>
352+
/// The Invoke-RestMethod command
353+
/// This command makes an HTTP or HTTPS request to a web service,
354+
/// and returns the response in an appropriate way.
355+
/// Intended to work against the wide spectrum of "RESTful" web services
356+
/// currently deployed across the web.
357+
/// </summary>
358+
[Cmdlet(VerbsLifecycle.Invoke, "RestMethod", HelpUri = "https://go.microsoft.com/fwlink/?LinkID=217034", DefaultParameterSetName = "StandardMethod")]
359+
public partial class InvokeRestMethodCommand : WebRequestPSCmdlet
360+
{
361+
#region Virtual Method Overrides
362+
363+
/// <summary>
364+
/// Process the web response and output corresponding objects.
365+
/// </summary>
366+
/// <param name="response"></param>
367+
internal override void ProcessResponse(HttpResponseMessage response)
368+
{
369+
if (null == response) { throw new ArgumentNullException("response"); }
370+
371+
using (BufferingStreamReader responseStream = new BufferingStreamReader(StreamHelper.GetResponseStream(response)))
372+
{
373+
if (ShouldWriteToPipeline)
374+
{
375+
// First see if it is an RSS / ATOM feed, in which case we can
376+
// stream it - unless the user has overridden it with a return type of "XML"
377+
if (TryProcessFeedStream(responseStream))
378+
{
379+
// Do nothing, content has been processed.
380+
}
381+
else
382+
{
383+
// determine the response type
384+
RestReturnType returnType = CheckReturnType(response);
385+
386+
// Try to get the response encoding from the ContentType header.
387+
Encoding encoding = null;
388+
string charSet = response.Content.Headers.ContentType?.CharSet;
389+
if (!string.IsNullOrEmpty(charSet))
390+
{
391+
// NOTE: Don't use ContentHelper.GetEncoding; it returns a
392+
// default which bypasses checking for a meta charset value.
393+
StreamHelper.TryGetEncoding(charSet, out encoding);
394+
}
395+
396+
object obj = null;
397+
Exception ex = null;
398+
399+
string str = StreamHelper.DecodeStream(responseStream, ref encoding);
400+
// NOTE: Tests use this verbose output to verify the encoding.
401+
WriteVerbose(string.Format
402+
(
403+
System.Globalization.CultureInfo.InvariantCulture,
404+
"Content encoding: {0}",
405+
string.IsNullOrEmpty(encoding.HeaderName) ? encoding.EncodingName : encoding.HeaderName)
406+
);
407+
bool convertSuccess = false;
408+
409+
if (returnType == RestReturnType.Json)
410+
{
411+
convertSuccess = TryConvertToJson(str, out obj, ref ex) || TryConvertToXml(str, out obj, ref ex);
412+
}
413+
// default to try xml first since it's more common
414+
else
415+
{
416+
convertSuccess = TryConvertToXml(str, out obj, ref ex) || TryConvertToJson(str, out obj, ref ex);
417+
}
418+
419+
if (!convertSuccess)
420+
{
421+
// fallback to string
422+
obj = str;
423+
}
424+
425+
WriteObject(obj);
426+
}
427+
}
428+
429+
if (ShouldSaveToOutFile)
430+
{
431+
StreamHelper.SaveStreamToFile(responseStream, QualifiedOutFile, this);
432+
}
433+
434+
if (!String.IsNullOrEmpty(ResponseHeadersVariable))
435+
{
436+
PSVariableIntrinsics vi = SessionState.PSVariable;
437+
vi.Set(ResponseHeadersVariable, WebResponseHelper.GetHeadersDictionary(response));
438+
}
439+
}
440+
}
441+
442+
#endregion Virtual Method Overrides
443+
444+
#region Helper Methods
445+
446+
private RestReturnType CheckReturnType(HttpResponseMessage response)
447+
{
448+
if (null == response) { throw new ArgumentNullException("response"); }
449+
450+
RestReturnType rt = RestReturnType.Detect;
451+
string contentType = ContentHelper.GetContentType(response);
452+
if (string.IsNullOrEmpty(contentType))
453+
{
454+
rt = RestReturnType.Detect;
455+
}
456+
else if (ContentHelper.IsJson(contentType))
457+
{
458+
rt = RestReturnType.Json;
459+
}
460+
else if (ContentHelper.IsXml(contentType))
461+
{
462+
rt = RestReturnType.Xml;
463+
}
464+
465+
return (rt);
466+
}
467+
468+
#endregion Helper Methods
469+
}
470+
}

0 commit comments

Comments
 (0)