Reputation:
I'm using Invoke-Restmethod to try upload a png file to rapidshare, the filesize on the server is correct but if I download the file it's not even an image, this is definitely an encoding issue but I have no clue what I'm doing wrong?
$FreeUploadServer = Invoke-RestMethod -Uri "http://api.rapidshare.com/cgi-bin/rsapi.cgi?sub=nextuploadserver"
$url = "http://rs$FreeUploadServer.rapidshare.com/cgi-bin/rsapi.cgi"
$fields = @{sub='upload';login='username';password='pass';filename='2he1re.png';filecontent=$(Get-Content C:\libs\test.png -Raw)}
Invoke-RestMethod -Uri $url -Body $fields -Method Post -ContentType "image/png"
I have tried all kinds of stuff, anyone have any idea what I'm doing wrong?
Upvotes: 3
Views: 457
Reputation: 201832
Reading the file content using the -Raw
parameter is still returning a string
object and this is probably going to be problematic for a binary file like a PNG. I think the RapidShare API is expecting URL-encoded form post data. Try this:
## !! It would be nice if this worked, but it does not - see update below !!
Add-Type -AssemblyName System.Web
$fields = @{sub='upload';login='username';password='pass';filename='2he1re.png';
filecontent=Get-Content C:\libs\test.png -Enc Byte -Raw}
BTW I think you might want to ditch setting the ContentType
. The content type should be application/x-www-form-urlencoded
- I think.
I found this post useful on the difference between HtmlEncode and UrlEncode.
Update: it appears the Invoke-RestMethod
is URL encoding the body for a POST when the body is in the form of a hashtable. That's nice. However it doesn't appear to accept byte arrays. It is expecting every value in the hashtable to be a string or representable as a string i.e. it invokes ToString() on each value. This makes it challenging to get the binary data encoded properly. I have question into the PowerShell team on this.
OK, figured out a reasonable workaround. Remember how I mentioned before, that passing the Body as a string was the equivalent to passing in a hashtable? Well, turns out there is one important difference. :-) When you pass in a string, the cmdlet doesn't Url encode it. So if we pass in a string, we can bypass what I consider to be a limitation of this cmdlet (not supporting byte[] values in a hashtable). Try this:
Add-Type -AssemblyName System.Web
$png = [Web.HttpUtility]::UrlEncode((Get-Content C:\libs\test.png -Enc Byte -Raw))
$body = "sub=upload&login=username&password=pass&filename=2he1re.png&filecontent=$png"
Invoke-RestMethod -Uri $url -Body $body -Method Post
Upvotes: 2