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