Powershell: Invoke-WebRequest multipart form-data fails file upload when field names not quoted

Created on 1 May 2018  Â·  4Comments  Â·  Source: PowerShell/PowerShell

This happens using the new -Form parameter that takes a hashtable of values and creates the multi-part form data.

Steps to reproduce

  1. Find URL to webservice that accepts POST of multi-part form data
  2. Run Fiddler or Wireshark to observe the request body
  3. Execute IWR similar to below:
Invoke-WebRequest -Uri $Uri -Method POST -Form @{
    APPLICATION_NAME = "Name"
    APPLICATION_VERION = "3.0"
    UPLOADED_FILE = Get-Item .\foo.zip
}

Expected behavior

Upload works as it does when using Python script to upload the file. Observe that in this Fiddler trace, that the form-data field values are quoted:

image

Actual behavior

PowerShell fails and after some experimenting it is because the name values are not quoted:

image

With just a few extra quotes e.g.:

Invoke-WebRequest -Uri $Uri -Method POST -Form @{
    '"APPLICATION_NAME"' = "Name"
    '"APPLICATION_VERION"' = "3.0"
    '"UPLOADED_FILE"' = Get-Item .\foo.zip
}

I can get the PowerShell request to quote all the field data values except the file's filename field. And that is enough to break the upload. Besides that, the above workaround is ugly.

As an aside, is there a way to control the filename value? If there was, I could work-around this by supplying the quotes myself. Also, I could see someone wanting to change the filename to something other than the original file's filename.

This also makes me wonder if we could use a new parameter like -RequestFilter that took a scriptblock with a signature like {param($requestText) ... } where you could get the request text just before it is sent. Then you could manipulate it however you needed to and return that text from this scriptblock. With such a feature I might be able to do this:

Invoke-WebRequest -Uri $Uri -Method POST `
    -RequesetFilter {param($r) $r -replace '(?<=filename=)(\S+)','"$1"' } `
    -Form @{
        '"APPLICATION_NAME"' = "Name"
        '"APPLICATION_VERION"' = "3.0"
        '"UPLOADED_FILE"' = Get-Item .\foo.zip
    }

Environment data

> $PSVersionTable
Name                           Value
----                           -----
PSVersion                      6.1.0-preview.2
PSEdition                      Core
GitCommitId                    v6.1.0-preview.2
OS                             Microsoft Windows 10.0.16299
Platform                       Win32NT
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0...}
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1
WSManStackVersion              3.0
Area-Cmdlets-Utility Resolution-Fixed

Most helpful comment

@rkeithhill Would you be so kind as to try using one of these artifacts https://ci.appveyor.com/project/PowerShell/powershell/build/v6.1.0-preview.9234/artifacts to test against your API and let me know if it works?

All 4 comments

As an aside, is there a way to control the filename value? If there was, I could work-around this by supplying the quotes myself. Also, I could see someone wanting to change the filename to something other than the original file's filename.

For the -Form way, no. This was intentionally simplistic. For customization, users can create their own MultipartFormDataContent objects and pass them to -Body.

I'm not a fan of the -RequestFilter Idea, but, I would consider accepting an HttpRequestMessage. The cmdlets do not send a raw request, so there is no way to really do what you are wanting, The Cmdlets use HttpClient and creates a HttpRequestMessage so we could consider allowing the user to supply their own.

Re: the issue at hand.

I did some research and the major browsers and curl all enclose the filename value and the field names in quotes. It seems that .NET is the only thing not doing that. I'll have a PR soon to correct this.

@rkeithhill Would you be so kind as to try using one of these artifacts https://ci.appveyor.com/project/PowerShell/powershell/build/v6.1.0-preview.9234/artifacts to test against your API and let me know if it works?

It works!! Thanks Mark!

-Keith

Sent from Mailhttps://go.microsoft.com/fwlink/?LinkId=550986 for Windows 10


From: Mark Kraus notifications@github.com
Sent: Tuesday, May 1, 2018 3:25:41 AM
To: PowerShell/PowerShell
Cc: Keith Hill; Mention
Subject: Re: [PowerShell/PowerShell] Invoke-WebRequest multipart form-data fails file upload when field names not quoted (#6780)

@rkeithhillhttps://nam02.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Frkeithhill&data=02%7C01%7C%7C065e5978285242acc85008d5af45828d%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C636607635426145690&sdata=FSQLHzCJpbioidxPGpcsljPdnKoJt9EI5TMWmj9nNi0%3D&reserved=0 Would you be so kind as to try using one of these artifacts https://ci.appveyor.com/project/PowerShell/powershell/build/v6.1.0-preview.9234/artifactshttps://nam02.safelinks.protection.outlook.com/?url=https%3A%2F%2Fci.appveyor.com%2Fproject%2FPowerShell%2Fpowershell%2Fbuild%2Fv6.1.0-preview.9234%2Fartifacts&data=02%7C01%7C%7C065e5978285242acc85008d5af45828d%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C636607635426145690&sdata=yiTa%2BiKawirOnQdkVpuyVQwj6xh5YzkaVaftV6Omreo%3D&reserved=0 to test against your API and let me know if it works?

—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHubhttps://nam02.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2FPowerShell%2FPowerShell%2Fissues%2F6780%23issuecomment-385633094&data=02%7C01%7C%7C065e5978285242acc85008d5af45828d%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C636607635426301940&sdata=bxrEHKCbhzixBmWruAlRHHn5tVN8AGJ8erSwS7LYKy4%3D&reserved=0, or mute the threadhttps://nam02.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fnotifications%2Funsubscribe-auth%2FAE8AqKY4Fdb84D9ieUTS-ekcoDOcKaPNks5tuCoVgaJpZM4TtUfG&data=02%7C01%7C%7C065e5978285242acc85008d5af45828d%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C636607635426301940&sdata=trvx7oIkqRodmGkhIBCrgg6yWQNXtX062k%2BZ51RtSGQ%3D&reserved=0.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

rudolfvesely picture rudolfvesely  Â·  3Comments

alx9r picture alx9r  Â·  3Comments

garegin16 picture garegin16  Â·  3Comments

manofspirit picture manofspirit  Â·  3Comments

JohnLBevan picture JohnLBevan  Â·  3Comments