Skip to content

Invoke-WebRequest multipart form-data fails file upload when field names not quoted #6780

@rkeithhill

Description

@rkeithhill

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

Metadata

Metadata

Assignees

Labels

Resolution-FixedThe issue is fixed.WG-Cmdlets-Utilitycmdlets in the Microsoft.PowerShell.Utility module

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions