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 contributorsWG-Cmdletsgeneral cmdlet issues

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions