无法使用Powershell脚本调用包含multipart/form-data的HTTP POST [英] Trouble with Powershell script to call HTTP POST with multipart/form-data

查看:215
本文介绍了无法使用Powershell脚本调用包含multipart/form-data的HTTP POST的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发一个Powershell脚本,该脚本应使用HTTP POST方法调用REST API. REST API用于从外部备份文件还原应用程序特定的备份资源.表单数据中备份文件的KeyName必须为"backupFile". 内容类型是multipart/form-data.这是我在做什么:

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

抛出错误: REST请求失败,必须存在一个名称为backupFile的数据表单,返回:错误的请求(400)

我在这里做错什么了?

推荐答案

在这种情况下,400可能表示生成

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

文件是您需要提交的唯一参数吗?如果是这样,您也许可以使用WebClient.UploadFile API并让其处理生成大量请求.

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')

如果您确实需要在mime multipart请求中提交多个参数,那么您将面临很多麻烦.我必须自己通过Powershell来执行此操作,这一点都不好玩,尤其是当您开始涉及二进制数据时.经过许多挫败感爆炸,我最终得到以下结果来转换值的哈希表并输出一个多部分.抱歉,我无法确切发现您的代码出了什么问题,但这也许可以完全为您解决,也可以使您确定问题所在.

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
}

这篇关于无法使用Powershell脚本调用包含multipart/form-data的HTTP POST的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆