Merge and Sort BasicHtmlWebResponseObject and ContentHelper (#5720)

* Merge and Sort BasicHtmlWebResponseObject

* Merge and sort ContentHelper
This commit is contained in:
Mark Kraus 2018-01-17 18:47:50 -06:00 committed by Aditya Patwardhan
parent c6be7bd863
commit bb8d5562c5
2 changed files with 174 additions and 187 deletions

View file

@ -3,22 +3,58 @@ Copyright (c) Microsoft Corporation. All rights reserved.
--********************************************************************/
using System;
using System.Management.Automation;
using System.Net;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Management.Automation;
using System.Net;
using System.Net.Http;
using System.Text;
using System.Text.RegularExpressions;
namespace Microsoft.PowerShell.Commands
{
/// <summary>
/// Response object for html content without DOM parsing
/// </summary>
public partial class BasicHtmlWebResponseObject : WebResponseObject
public class BasicHtmlWebResponseObject : WebResponseObject
{
#region Private Fields
private static Regex s_attribNameValueRegex;
private static Regex s_attribsRegex;
private static Regex s_imageRegex;
private static Regex s_inputFieldRegex;
private static Regex s_linkRegex;
private static Regex s_tagRegex;
#endregion Private Fields
#region Constructors
/// <summary>
/// Constructor for BasicHtmlWebResponseObject
/// </summary>
/// <param name="response"></param>
public BasicHtmlWebResponseObject(HttpResponseMessage response)
: this(response, null)
{ }
/// <summary>
/// Constructor for HtmlWebResponseObject with memory stream
/// </summary>
/// <param name="response"></param>
/// <param name="contentStream"></param>
public BasicHtmlWebResponseObject(HttpResponseMessage response, Stream contentStream)
: base(response, contentStream)
{
EnsureHtmlParser();
InitializeContent();
InitializeRawContent(response);
}
#endregion Constructors
#region Properties
/// <summary>
@ -117,19 +153,40 @@ namespace Microsoft.PowerShell.Commands
#endregion Properties
#region Private Fields
private static Regex s_tagRegex;
private static Regex s_attribsRegex;
private static Regex s_attribNameValueRegex;
private static Regex s_inputFieldRegex;
private static Regex s_linkRegex;
private static Regex s_imageRegex;
#endregion Private Fields
#region Methods
/// <summary>
/// Reads the response content from the web response.
/// </summary>
protected void InitializeContent()
{
string contentType = ContentHelper.GetContentType(BaseResponse);
if (ContentHelper.IsText(contentType))
{
Encoding encoding = null;
// fill the Content buffer
string characterSet = WebResponseHelper.GetCharacterSet(BaseResponse);
this.Content = StreamHelper.DecodeStream(RawContentStream, characterSet, out encoding);
this.Encoding = encoding;
}
else
{
this.Content = string.Empty;
}
}
private PSObject CreateHtmlObject(string html, string tagName)
{
PSObject elementObject = new PSObject();
elementObject.Properties.Add(new PSNoteProperty("outerHTML", html));
elementObject.Properties.Add(new PSNoteProperty("tagName", tagName));
ParseAttributes(html, elementObject);
return elementObject;
}
private void EnsureHtmlParser()
{
if (s_tagRegex == null)
@ -169,16 +226,11 @@ namespace Microsoft.PowerShell.Commands
}
}
private PSObject CreateHtmlObject(string html, string tagName)
private void InitializeRawContent(HttpResponseMessage baseResponse)
{
PSObject elementObject = new PSObject();
elementObject.Properties.Add(new PSNoteProperty("outerHTML", html));
elementObject.Properties.Add(new PSNoteProperty("tagName", tagName));
ParseAttributes(html, elementObject);
return elementObject;
StringBuilder raw = ContentHelper.GetRawContentHeader(baseResponse);
raw.Append(Content);
this.RawContent = raw.ToString();
}
private void ParseAttributes(string outerHtml, PSObject elementObject)
@ -223,70 +275,6 @@ namespace Microsoft.PowerShell.Commands
}
}
/// <summary>
/// Reads the response content from the web response.
/// </summary>
protected void InitializeContent()
{
string contentType = ContentHelper.GetContentType(BaseResponse);
if (ContentHelper.IsText(contentType))
{
Encoding encoding = null;
// fill the Content buffer
string characterSet = WebResponseHelper.GetCharacterSet(BaseResponse);
this.Content = StreamHelper.DecodeStream(RawContentStream, characterSet, out encoding);
this.Encoding = encoding;
}
else
{
this.Content = string.Empty;
}
}
#endregion Methods
}
// TODO: Merge Partials
// <summary>
/// Response object for html content without DOM parsing
/// </summary>
public partial class BasicHtmlWebResponseObject : WebResponseObject
{
#region Constructors
/// <summary>
/// Constructor for BasicHtmlWebResponseObject
/// </summary>
/// <param name="response"></param>
public BasicHtmlWebResponseObject(HttpResponseMessage response)
: this(response, null)
{ }
/// <summary>
/// Constructor for HtmlWebResponseObject with memory stream
/// </summary>
/// <param name="response"></param>
/// <param name="contentStream"></param>
public BasicHtmlWebResponseObject(HttpResponseMessage response, Stream contentStream)
: base(response, contentStream)
{
EnsureHtmlParser();
InitializeContent();
InitializeRawContent(response);
}
#endregion Constructors
#region Methods
private void InitializeRawContent(HttpResponseMessage baseResponse)
{
StringBuilder raw = ContentHelper.GetRawContentHeader(baseResponse);
raw.Append(Content);
this.RawContent = raw.ToString();
}
#endregion Methods
}
}

View file

@ -3,45 +3,49 @@ Copyright (c) Microsoft Corporation. All rights reserved.
--********************************************************************/
using System;
using System.Management.Automation;
using System.Text;
using Microsoft.Win32;
using System.Linq;
using System.Management.Automation;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using Microsoft.Win32;
namespace Microsoft.PowerShell.Commands
{
internal static partial class ContentHelper
internal static class ContentHelper
{
#region Constants
// used to split contentType arguments
private static readonly char[] s_contentTypeParamSeparator = { ';' };
// default codepage encoding for web content. See RFC 2616.
private const string _defaultCodePage = "ISO-8859-1";
#endregion Constants
#region Fields
// used to split contentType arguments
private static readonly char[] s_contentTypeParamSeparator = { ';' };
#endregion Fields
#region Internal Methods
internal static bool IsText(string contentType)
internal static string GetContentType(HttpResponseMessage response)
{
contentType = GetContentTypeSignature(contentType);
return CheckIsText(contentType);
// ContentType may not exist in response header. Return null if not.
return response.Content.Headers.ContentType?.MediaType;
}
internal static bool IsXml(string contentType)
internal static Encoding GetDefaultEncoding()
{
contentType = GetContentTypeSignature(contentType);
return CheckIsXml(contentType);
return GetEncodingOrDefault((string)null);
}
internal static bool IsJson(string contentType)
internal static Encoding GetEncoding(HttpResponseMessage response)
{
contentType = GetContentTypeSignature(contentType);
return CheckIsJson(contentType);
// ContentType may not exist in response header.
string charSet = response.Content.Headers.ContentType?.CharSet;
return GetEncodingOrDefault(charSet);
}
internal static Encoding GetEncodingOrDefault(string characterSet)
@ -63,22 +67,87 @@ namespace Microsoft.PowerShell.Commands
return encoding;
}
internal static Encoding GetDefaultEncoding()
internal static StringBuilder GetRawContentHeader(HttpResponseMessage response)
{
return GetEncodingOrDefault((string)null);
StringBuilder raw = new StringBuilder();
string protocol = WebResponseHelper.GetProtocol(response);
if (!string.IsNullOrEmpty(protocol))
{
int statusCode = WebResponseHelper.GetStatusCode(response);
string statusDescription = WebResponseHelper.GetStatusDescription(response);
raw.AppendFormat("{0} {1} {2}", protocol, statusCode, statusDescription);
raw.AppendLine();
}
HttpHeaders[] headerCollections =
{
response.Headers,
response.Content == null ? null : response.Content.Headers
};
foreach (var headerCollection in headerCollections)
{
if (headerCollection == null)
{
continue;
}
foreach (var header in headerCollection)
{
// Headers may have multiple entries with different values
foreach (var headerValue in header.Value)
{
raw.Append(header.Key);
raw.Append(": ");
raw.Append(headerValue);
raw.AppendLine();
}
}
}
raw.AppendLine();
return raw;
}
internal static bool IsJson(string contentType)
{
contentType = GetContentTypeSignature(contentType);
return CheckIsJson(contentType);
}
internal static bool IsText(string contentType)
{
contentType = GetContentTypeSignature(contentType);
return CheckIsText(contentType);
}
internal static bool IsXml(string contentType)
{
contentType = GetContentTypeSignature(contentType);
return CheckIsXml(contentType);
}
#endregion Internal Methods
#region Private Helper Methods
private static string GetContentTypeSignature(string contentType)
private static bool CheckIsJson(string contentType)
{
if (String.IsNullOrEmpty(contentType))
return null;
return false;
string sig = contentType.Split(s_contentTypeParamSeparator, 2)[0].ToUpperInvariant();
return (sig);
// the correct type for JSON content, as specified in RFC 4627
bool isJson = contentType.Equals("application/json", StringComparison.OrdinalIgnoreCase);
// add in these other "javascript" related types that
// sometimes get sent down as the mime type for JSON content
isJson |= contentType.Equals("text/json", StringComparison.OrdinalIgnoreCase)
|| contentType.Equals("application/x-javascript", StringComparison.OrdinalIgnoreCase)
|| contentType.Equals("text/x-javascript", StringComparison.OrdinalIgnoreCase)
|| contentType.Equals("application/javascript", StringComparison.OrdinalIgnoreCase)
|| contentType.Equals("text/javascript", StringComparison.OrdinalIgnoreCase);
return (isJson);
}
private static bool CheckIsText(string contentType)
@ -132,85 +201,15 @@ namespace Microsoft.PowerShell.Commands
return (isXml);
}
private static bool CheckIsJson(string contentType)
private static string GetContentTypeSignature(string contentType)
{
if (String.IsNullOrEmpty(contentType))
return false;
return null;
// the correct type for JSON content, as specified in RFC 4627
bool isJson = contentType.Equals("application/json", StringComparison.OrdinalIgnoreCase);
// add in these other "javascript" related types that
// sometimes get sent down as the mime type for JSON content
isJson |= contentType.Equals("text/json", StringComparison.OrdinalIgnoreCase)
|| contentType.Equals("application/x-javascript", StringComparison.OrdinalIgnoreCase)
|| contentType.Equals("text/x-javascript", StringComparison.OrdinalIgnoreCase)
|| contentType.Equals("application/javascript", StringComparison.OrdinalIgnoreCase)
|| contentType.Equals("text/javascript", StringComparison.OrdinalIgnoreCase);
return (isJson);
string sig = contentType.Split(s_contentTypeParamSeparator, 2)[0].ToUpperInvariant();
return (sig);
}
#endregion Internal Helper Methods
}
// TODO: merge Partials
internal static partial class ContentHelper
{
internal static Encoding GetEncoding(HttpResponseMessage response)
{
// ContentType may not exist in response header.
string charSet = response.Content.Headers.ContentType?.CharSet;
return GetEncodingOrDefault(charSet);
}
internal static string GetContentType(HttpResponseMessage response)
{
// ContentType may not exist in response header. Return null if not.
return response.Content.Headers.ContentType?.MediaType;
}
internal static StringBuilder GetRawContentHeader(HttpResponseMessage response)
{
StringBuilder raw = new StringBuilder();
string protocol = WebResponseHelper.GetProtocol(response);
if (!string.IsNullOrEmpty(protocol))
{
int statusCode = WebResponseHelper.GetStatusCode(response);
string statusDescription = WebResponseHelper.GetStatusDescription(response);
raw.AppendFormat("{0} {1} {2}", protocol, statusCode, statusDescription);
raw.AppendLine();
}
HttpHeaders[] headerCollections =
{
response.Headers,
response.Content == null ? null : response.Content.Headers
};
foreach (var headerCollection in headerCollections)
{
if (headerCollection == null)
{
continue;
}
foreach (var header in headerCollection)
{
// Headers may have multiple entries with different values
foreach (var headerValue in header.Value)
{
raw.Append(header.Key);
raw.Append(": ");
raw.Append(headerValue);
raw.AppendLine();
}
}
}
raw.AppendLine();
return raw;
}
#endregion Private Helper Methods
}
}