0

I have a build step in TeamCity which sends an HTTP request, like this:

$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']"

It works perfectly when %BRANCH_NAME% actually contains simple branch names, like ' master', 'beta', 'dev'.

But it works not so good when %BRANCH_NAME% is release%2F2019-DEC (URL encoded value of release/2019-DEC)

I tried the same script on local Powershell, and it worked flawlessly, but when I run it as TeamCity build step I receive the following error:

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/']

I tried to escape the percent sign using the extra % sign as in Using the percent sign in TeamCity build scripts, but unfortunately, it returns the same error.

Any ideas?

2
  • 1
    Imho you should convert this other way around. Instead of using extra % sign, you should convert %2F to /. But this is just a hunch. Also you could check this solution: stackoverflow.com/a/43135803/7225096 Commented Dec 11, 2019 at 14:40
  • @Peska, thanks for your comment. The thing is that without URL encoding the target URI will be host/app/branches/release/2019-DEC, which will return 404 as there is no such resource. If you curl host/app/branches/release%2F2019-DEC it would work, the tricky thing is that it doesn't work in TeamCity. Thanks for the link, I'll take a look. Commented Dec 11, 2019 at 15:12

1 Answer 1

0

Solved:

Seemingly issue was caused by the old version of PowerShell on Agent, which caused the behavior described in Team City build step with Powershell Invoke-RestMethod fails if URI contains URL encoded value

That means that no extra percent signs are actually needed, we can URL encode value inside the script.

So the final version will look like:

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

Special thanks to @Peska

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.