Trouble with Powershell script to call HTTP POST with multipart/form-data

戏子无情 提交于 2019-12-12 06:46:58

问题


I am developing a powershell script that should invoke a REST API using the HTTP POST method. The REST API is used to restore an application specific backup resource from external backup file. the KeyName for backup file in the form data must be "backupFile". The content type is multipart/form-data. Here is what i am doing:

function invoke-rest {
param([string]$uri)
[System.Net.ServicePointManager]::ServerCertificateValidationCallback = {$true}
#$enc = [system.Text.Encoding]::UTF8
$request = [System.Net.HttpWebRequest]::Create($uri)
$request.Credentials = New-Object system.net.networkcredential("user","password")
$request.CookieContainer = New-Object System.Net.CookieContainer
$request.AllowWriteStreamBuffering = $true;
$boundary = "--------------"+(get-date -format yyyymmddhhmmss).ToString()
$header = "--"+$boundary
$body = $header + "`r`n" +"Content-Disposition: form-data; name='backupFile'; filename='somefile.sql.gz'"+"`r`n" + "Content-Type: multipart/form-data"+"`r`n`r`n"

$body = $body + [System.Text.Encoding]::UTF8.GetString($(Get-Content 'somefile.sql.gz' -Encoding byte)) + "`r`n"
$footer = $header+"--"
$body = $body + $footer

$bytes = [System.Text.Encoding]::UTF8.GetBytes($body)
$request.ContentType = "multipart/form-data; boundary="+$boundary
$request.Method = "Post"
$request.keepAlive = $true
$request.ContentLength = $bytes.Length

$requestStream = $request.GetRequestStream()
$requestStream.Write($bytes,0,$bytes.length);
$requestStream.Flush();
$requestStream.Close();

$response = $request.GetResponse()
$responseStream = $response.GetResponseStream()
$stream = new-object System.IO.StreamReader $responseStream
$xmlDump = $stream.ReadToEnd()
$output = [xml]$xmlDump
$response.close()
return $output
}
$uri = "http://localhost/rest/backups"
invoke-rest $uri

The error being thrown: REST request failed, A data form must exist with the name backupFile, returning: Bad Request (400)

What am i doing wrong here?


回答1:


In this scenario, the 400 probably means something was incorrect in generating the

Is the file the only parameter you need to submit on the request? If so, you may be able to use the WebClient.UploadFile API and let it handle generating the bulk of the request.

$client = New-Object System.Net.WebClient
$client.Credentials = $creds
$client.UploadFile('http://localhost/rest/backups', 'c:\temp\somefile.sql.gz')

If you do need to submit multiple parameters in a mime multipart request, then you're looking at a world of pain. I've had to do this through powershell myself and it's not fun at all, particularly when you start involving binary data. After much frustration & headbanging, I ended up with the following to convert a hashtable of values and outputs a multipart. Sorry I can't spot exactly what's wrong with your code, but perhaps this can will either work outright for you, or lead you to identify what your issue is.

function ConvertTo-MimeMultiPartBody
{
    param(
        [Parameter(Mandatory=$true)]
        [string]$Boundary,
        [Parameter(Mandatory=$true)]
        [hashtable]$Data
    )

    $body = '';

    $Data.GetEnumerator() |% {
        $name = $_.Key
        $value = $_.Value

        $body += "--$Boundary`r`n"
        $body += "Content-Disposition: form-data; name=`"$name`""
        if ($value -is [byte[]]) {
            $fileName = $Data['FileName']
            if(!$fileName) {
                $fileName = $name
            }
            $body += "; filename=`"$fileName`"`r`n"
            $body += 'Content-Type: application/octet-stream'
            #ISO-8859-1 is only encoding where byte value == code point value
            $value = [System.Text.Encoding]::GetEncoding("ISO-8859-1").GetString($value)
        }
        $body += "`r`n`r`n"
        $body += $value
        $body += "`r`n"
    }
    $body += "--$boundary--"
    return $body
}


来源:https://stackoverflow.com/questions/25469118/trouble-with-powershell-script-to-call-http-post-with-multipart-form-data

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!