Friday, October 18, 2013

Invoke-RestMethod and Invoke-WebRequest Header and Other Problems

I'm working on a script that copies the contents of a Rackspace Cloud Files container to another container.  I'm leveraging Rackspace's PowerShell library from GitHub and adding what features it currently does not possess.  One such feature is a function to copy a Cloud Files Object.  The API documentation for this specifies 2 ways to do it.  So here's my story:

  1. I first went the path of using the "COPY" method.  This effort was quickly thwarted when it became obvious that Invoke-WebRequest's -Method does not support Copy for a value.  On to #2.
  2. I began working on the "PUT" method.  This approach requires you to specify the size of the file being copied in the header as the "Content-Length".  So I added "Content-Length" to the headers and it gives me this error:
    This header must be modified using the appropriate property or method.
    Parameter name: name

    So, there's no way to add content-length to the Invoke-WebRequest or Invoke-RestMethod functions...  What now?
  3. I rolled the dice on Google for a while until I came across this Microsoft Connect bug.  Taking a quick look at the workarounds, Ch15Murray suggests tapping into some .NET features.  Here's what it looks like:

    $webRequest = [System.Net.WebRequest]::Create( $url )
    $webRequest.PreAuthenticate = $true
    $webRequest.Method = "POST"
    $webRequest.Headers.Add('Authorization', "Basic $token")
    $webRequest.Accept = 'application/*+xml;version=5.1'
    $webRequest.GetResponse()
    
I noticed that I can change the method property here without any validation, so I could use "Copy".  This takes me back to my first attempt which seems much easier.  Now I have a nice little approach to taking on the copy of a Rackspace Cloud Files object.  Here's my final code:
    $webRequest = [System.Net.WebRequest]::Create($rackspaceSourceUrl)
    $webRequest.PreAuthenticate = $true
    $webRequest.Method = "COPY"
    $webRequest.Headers.Add("Destination", $destinationPath)
    $webRequest.Headers.Add("X-Auth-Token", $token)
    $webRequest.GetResponse()

No comments:

Post a Comment