Private/New-ConfluenceMultipartBody.ps1
|
function New-ConfluenceMultipartBody { <# .SYNOPSIS Builds a multipart/form-data request body for a Confluence attachment upload. .DESCRIPTION Returns an object with Bytes (the body) and ContentType (multipart/form-data with the boundary). The file is sent in the "file" part; -Comment and minorEdit are sent as text parts. Works on Windows PowerShell 5.1, which has no -Form parameter on Invoke-WebRequest. #> [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseShouldProcessForStateChangingFunctions', '', Justification = 'Only builds a request body in memory; nothing outside the session is changed.')] [CmdletBinding()] [OutputType([pscustomobject])] param ( [Parameter(Mandatory)] [string]$FileName, [Parameter(Mandatory)] [AllowEmptyCollection()] [byte[]]$FileBytes, [string]$Comment, [bool]$MinorEdit = $true ) $boundary = '----tcsconfluence' + [guid]::NewGuid().ToString('N') $utf8 = New-Object -TypeName System.Text.UTF8Encoding -ArgumentList $false $stream = New-Object -TypeName System.IO.MemoryStream try { $writeText = { param([string]$Text) $bytes = $utf8.GetBytes($Text) $stream.Write($bytes, 0, $bytes.Length) } $safeName = $FileName.Replace('"', '%22').Replace("`r", '').Replace("`n", '') & $writeText ("--$boundary`r`nContent-Disposition: form-data; name=`"file`"; filename=`"$safeName`"`r`nContent-Type: application/octet-stream`r`n`r`n") if ($FileBytes.Length -gt 0) { $stream.Write($FileBytes, 0, $FileBytes.Length) } & $writeText "`r`n" if ($Comment) { & $writeText ("--$boundary`r`nContent-Disposition: form-data; name=`"comment`"`r`nContent-Type: text/plain; charset=utf-8`r`n`r`n$Comment`r`n") } $minorEditValue = if ($MinorEdit) { 'true' } else { 'false' } & $writeText ("--$boundary`r`nContent-Disposition: form-data; name=`"minorEdit`"`r`n`r`n$minorEditValue`r`n") & $writeText "--$boundary--`r`n" return [pscustomobject]@{ Bytes = $stream.ToArray() ContentType = "multipart/form-data; boundary=$boundary" } } finally { $stream.Dispose() } } |