using curl for multipart/form-data with a file upload

18,317

Solution 1

curl -X POST  -F [email protected]  http://myapi.com/

or

-X POST is implied by -F (per comment), quotes are optional

curl -F "[email protected]"  http://myapi.com/

Solution 2

For more complex requests:

curl
 -X POST "YOUR_API_URL"
 -H "Authorization: Bearer YOUR_TOKEN"
 -H "Accept: application/json"
 -H "Content-Type: multipart/form-data"
 -F "meta={\"YOUR_ATTRIBUTE\": \"YOUR_DATA\"};type=application/json"
 -F "text=PATH_TO_FILE;type=text/plain"

You can set several chunks together into one request. For more, check out: https://docs.microsoft.com/en-us/azure/digital-twins/how-to-add-blobs!

Share:
18,317
Stephen
Author by

Stephen

Almost completely self-taught. Always trying to reduce complex problems to simple ones.

Updated on July 08, 2022

Comments

  • Stephen
    Stephen almost 2 years

    I have a server API that I have developed against the format used by Fiddler to do HTTP posts of files, which is a multipart/form-data post. I'm trying to get curl to do something similar (so I can stop using Fiddler for testing and instead have a separate program call out to curl programmatically).

    Here is how it's set up in Fiddler, which is what I need to replicate. The file being uploaded is myfile.html:

    ---------------------------acebdf13572468
    Content-Disposition: form-data; name="fieldNameHere"; filename="myfile.html"
    Content-Type: text/html
    
    <@INCLUDE *C:\myfiles\myfile.html*@>
    ---------------------------acebdf13572468--
    

    So what I need is for curl to produce something similar: in particular the name= part, followed by the file content at the bottom of this part. I've tried this with:

    curl -F "fieldNameHere=myfile.html" http://myapi.com/
    

    When I do that it seems to totally ignore my file though. Here's the verbose output if I add -v:

    POST / HTTP/1.1
    User-Agent: curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.27.1 zlib/1.2.3 libidn/1.18 libssh2/1.4.2
    Host: perl-h4.factset.io
    Accept: */*
    Content-Length: 166
    Expect: 100-continue
    Content-Type: multipart/form-data; boundary=----------------------------981301fdaeb3
    

    There's no file content at all (it's a large HTML file). So I think there might be something fundamental I'm missing here. Any pointers would be quite welcome.

    Also, I have checked other StackOverflow questions like this: What is the right way to POST multipart/form-data using curl?

    But they are basically saying to do something like what I'm doing here. So maybe the problem is not my syntax, but some other reason it doesn't want to read the file.

  • Daniel Stenberg
    Daniel Stenberg over 6 years
    but no bonus points with the superfluous -X POST present there... =)
  • Stephen
    Stephen over 6 years
    Oh wow, so the problem is just that I was missing an @ sign. Amazing... thanks. I guess that tells curl that this is the name of an actual file?
  • Scriptonomy
    Scriptonomy over 6 years
    Yes pretty much.