-
Notifications
You must be signed in to change notification settings - Fork 30
/
Copy pathRead-WebRequest.ps1
67 lines (60 loc) · 2.13 KB
/
Read-WebRequest.ps1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
<#
.SYNOPSIS
Parses an HTTP listener request.
.LINK
https://docs.microsoft.com/dotnet/api/system.net.httplistener
.EXAMPLE
Read-WebRequest.ps1 $httpContext.Request
Parses the request body as a string or byte array.
#>
#Requires -Version 3
[CmdletBinding()] Param(
# The HTTP listener to receive the request through.
[Parameter(Position=0,Mandatory=$true,ValueFromPipelineByPropertyName=$true)][Net.HttpListenerRequest] $Request,
# Forces an encoding for the request body; Byte for binary, others for text.
[ValidateSet('ascii','byte','utf16','utf16BE','utf32','utf32BE','utf7','utf8')][string] $Encoding
)
function Read-BinaryWebRequest
{
if(!$Request.HasEntityBody) {return}
if(!$Request.InputStream.CanRead)
{ Stop-ThrowError.ps1 'Unable to read HTTP request.' -OperationContext $Request }
if($Request.ContentLength64 -lt 1)
{
$read = 0
[byte[]] $data = New-Object byte[] 1KB
do
{
if($read -gt 0) {[array]::Resize([ref]$data,$data.Length*2)}
$read += $Request.InputStream.Read($data,$read,$data.Length - $read)
}
while($read -eq $data.Length)
[array]::Resize([ref]$data,$read)
}
else
{
[byte[]] $data = New-Object byte[] $Request.ContentLength64
if(!$Request.InputStream.Read($data,0,$data.Length))
{ Stop-ThrowError.ps1 'No data read from HTTP request.' -OperationContext $Request}
}
,$data
}
function Read-TextWebRequest([Text.Encoding] $Encoding = $Request.ContentEncoding)
{
$Encoding.GetString((Read-BinaryWebRequest))
}
$Request.Headers |Out-String |Write-Verbose
if($Encoding)
{
if($Encoding -eq 'byte') {Read-BinaryWebRequest}
else {Read-TextWebRequest ([Text.Encoding]::GetEncoding(($Encoding -replace '^utf','utf-')))}
}
else
{
#TODO: multipart/alternative, multipart/parallel, multipart/related, multipart/form-data, multipart/*
# https://stackoverflow.com/a/21689347/54323
# https://docs.microsoft.com/dotnet/api/system.net.http.streamcontent
$texty = '\A(?:(?:text|message)/.*|application/(?:json|(?:.*\+)xml))\z'
if(([Net.Mime.ContentType]$Request.ContentType).MediaType -match $texty) {Read-TextWebRequest}
else {Read-BinaryWebRequest}
}