如果URI包含URL编码值,使用Powershell Invoke-RestMethod进行团队建设的步骤将失败

问题描述 投票:0回答:1

我在TeamCity中有一个构建步骤,该步骤发送HTTP请求,如下所示:

$headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
$headers.Add("Token", "%TOKEN%")
$uri = 'https://host/apps/branches/%BRANCH_NAME%/builds'
$response = Invoke-RestMethod $uri -Method 'GET' -Headers $headers
Write-Host "##teamcity[setParameter name='url' value='$uri']"

%BRANCH_NAME%实际上包含简单的分支名称,例如' master', 'beta', 'dev'时,它可以很好地工作。

但是当%BRANCH_NAME%release%2F2019-DEC(URL编码为release/2019-DEC时,效果不佳]

我在本地Powershell上尝试了相同的脚本,并且可以完美地工作,但是当我将其作为TeamCity构建步骤运行时,收到以下错误:

Invoke-RestMethod : The remote server returned an error: (404) Not Found.
At C:\TeamCityBuildAgent4\temp\buildTmp\powershell7367326510068615884.ps1:5 char:13
+ $response = Invoke-RestMethod $uri -Method 'GET' -Headers $headers
+             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-RestMethod], WebExc 
   eption
    + FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeRestMethodCommand

##teamcity[setParameter name='url' value='https://host/app/branches/release%2F2019-DEC/']

我尝试像Using the percent sign in TeamCity build scripts中那样使用额外的%符号对百分比符号进行转义,但不幸的是,它返回了相同的错误。

有什么想法吗?

powershell teamcity
1个回答
0
投票

已解决:

看似问题是由旧版本的Agent上的PowerShell引起的,该问题导致Team City build step with Powershell Invoke-RestMethod fails if URI contains URL encoded value中描述的行为

这意味着实际上不需要多余的百分号,我们可以在脚本内对值进行URL编码。

因此最终版本将如下所示:

function fixuri($uri){
  $UnEscapeDotsAndSlashes = 0x2000000;
  $SimpleUserSyntax = 0x20000;
  $type = $uri.GetType();
  $fieldInfo = $type.GetField("m_Syntax", ([System.Reflection.BindingFlags]::Instance -bor [System.Reflection.BindingFlags]::NonPublic));
  $uriParser = $fieldInfo.GetValue($uri);
  $typeUriParser = $uriParser.GetType().BaseType;
$fieldInfo = $typeUriParser.GetField("m_Flags", ([System.Reflection.BindingFlags]::Instance -bor [System.Reflection.BindingFlags]::NonPublic -bor [System.Reflection.BindingFlags]::FlattenHierarchy));
$uriSyntaxFlags = $fieldInfo.GetValue($uriParser);
$uriSyntaxFlags = $uriSyntaxFlags -band (-bnot $UnEscapeDotsAndSlashes);
$uriSyntaxFlags = $uriSyntaxFlags -band (-bnot $SimpleUserSyntax);
$fieldInfo.SetValue($uriParser, $uriSyntaxFlags);
}
$headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
$headers.Add("X-API-Token", "%TOKEN%")
$branch = [System.Web.HttpUtility]::UrlEncode('release/2019-DEC1')
$uri = New-Object System.Uri -ArgumentList ("https://host/apps/branches/$branch")
fixuri $uri
$response = Invoke-RestMethod $uri -Method 'GET' -Headers $headers

特别感谢@Peska

© www.soinside.com 2019 - 2024. All rights reserved.