Skip to content

Using Invoke-WebRequest POST to upload a file is broken #23843

@rkeithhill-keysight

Description

@rkeithhill-keysight

Prerequisites

Steps to reproduce

I have a PowerShell module that uploads a zip file of API documentation to a CGI-based website that has been working untouched since 2019. Unfortunately, when I upgraded our build nodes to 7.4.2, it broke the upload to this website. This might be hard to reproduce because I don't know how much of the behavior depends on the CGI website.

  1. Construct the IWR args and call it like so:
$uri = "https://api.is.acme.com/cgi-bin/org/of_apps/apiManager/apiManager.cgi"

$form = [ordered]@{
    USERNAME = $UserName
    API_KEY = $ApiKey
    APPLICATION_NAME = $AppName
    APPLICATION_VERSION = $Version
    APPLICATION_VERSION_ALIAS = $VersionAlias
    DELETE_EXISTING_VERSION = $AllowClobber ? "true" : "false"
    ROBOT = "true"
    UPLOADED_FILE = Get-Item $Path # this is a zip file
}

Invoke-WebRequest -Uri $uri -Method POST -Form $form -SkipCertificateCheck

This silently fails (returns a 200 status code). The file does not get uploaded. When I capture this with Fiddler, this is what I see for the request headers:
image

What is up with the uploaded filename being specified TWICE? And what's with that second funky filename value utf-8''Klm...? I suspect this might be the problem. It's also interesting that curl quotes the field names e.g. "UPLOADED_FILE" whereas 7.4.2 does not. Ditto for the filename value.

Now if I try this with CURL (on Windows) - surprise, it works. :🤦‍♂️

curl --insecure -F USERNAME=$username -F API_KEY=$apiDocsKey -F APPLICATION_NAME="KAL License Management Client API - Cplusplus" -F APPLICATION_VERSION=7.4.0-develop -F APPLICATION_VERSION_ALIAS=LATEST-develop -F UPLOADED_FILE=@C:\Temp\KlmCppReference.zip -F ROBOT=true https://api.is.keysight.com/cgi-bin/org/of_apps/apiManager/apiManager.cgi -x 127.0.0.1:8888

This results in these headers:
image

Expected behavior

I expect that using `$form["UPLOADED_FILE"] = Get-Item $zipPath` should continue to work and produce the correct multi-part form data - particularly the filename.

Actual behavior

The CGI website does not accept the uploaded file ... unless I use `curl`.

Error details

There is no error from Invoke-WebRequest. Even the HTTP status code is 200 in both failed & working cases.  The difference is that when it fails, I get the home HTML as the raw content.  When it works I get the somewhat cryptic content:

1
1
0

🤷‍♂️ I didn't write this CGI website.

Environment data

Name                           Value
----                           -----
PSVersion                      7.4.2
PSEdition                      Core
GitCommitId                    7.4.2
OS                             Microsoft Windows 10.0.22631
Platform                       Win32NT
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0…}
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1
WSManStackVersion              3.0

Visuals

Bad PowerShell POST request headers:
image

Working curl POST request headers:
image

Metadata

Metadata

Assignees

No one assigned

    Labels

    Needs-TriageThe issue is new and needs to be triaged by a work group.Up-for-GrabsUp-for-grabs issues are not high priorities, and may be opportunities for external contributors

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions