21

I've been posting a file with this curl command:

curl -i -F file=@./File.xlsm -F name=file -X POST http://example.com/new_file/

Now I want to send some information about the file (as JSON) along with the file.

curl -i -H "Content-Type: application/json" -d '{"metadata": {"comment": "Submitting a new data set.", "current": false }, "sheet": 1, "row": 7 }' -F file=@./File.xlsm -F name=file http://example.com/new_file/

Curl is very grumpy about being used in this completely incorrect way, and in this case it says "You can only select one HTTP request!" OK, fair enough, so how do I get the file attachment and those POST variables into a single curl HTTP request?

nbrooks
  • 18,126
  • 5
  • 54
  • 66
Jason Champion
  • 2,670
  • 4
  • 35
  • 55
  • 4
    Sounds like curl already told you the answer...your HTTP request has a content type of json, not multipart/form-data--it can't include a file AFAIK. If you're sending metadata about the file, that should probably be sent as HTTP request headers. – nbrooks Feb 22 '14 at 02:24
  • Would like to accept this as the answer, but you can't do that on comments. – Jason Champion Jul 02 '14 at 18:05

4 Answers4

19

I've had success developing similar endpoints that accept multiple files along with their metadata in JSON format.

curl -i -X POST -H "Content-Type: multipart/mixed" -F "blob=@/Users/username/Documents/bio.jpg" -F "metadata={\"edipi\":123456789,\"firstName\":\"John\",\"lastName\":\"Smith\",\"email\":\"john.smith@gmail.com\"};type=application/json" http://localhost:8080/api/v1/user/

Notice the addition of ;type=application/json at the end of the metadata request part. When uploading multiple files of different types, you can define the mime type at the end of the -F value.

I have confirmed that this works for Spring MVC 4.3.7 using @RequestPart. The key in that instance is to not provide the consumes value on the @RequestMapping annotation.

Dayel Ostraco
  • 1,753
  • 1
  • 13
  • 15
  • Thanks - the addition of `;type=application/json` worked for me. Any idea how that would be done via PHP cURL? :) – Peter Oct 08 '20 at 11:39
7

You could just add another form field:

curl -X POST http://someurl/someresource -F upload=@/path/to/some/file -F data="{\"test\":\"test\"}"

Note: due to the content type, this does not really equate to sending json to the web service.

siyb
  • 2,837
  • 2
  • 21
  • 18
2

This worked for me:

curl -v -H "Content-Type:multipart/form-data" -F "meta-data=@C:\Users\saurabh.sharma\Desktop\test.json;type=application/json" -F "file-data=@C:\Users\saurabh.sharma\Pictures\Saved Pictures\windows_70-wallpaper.jpg" http://localhost:7002/test/upload

test.json has the json data I want to send.

swan8060
  • 95
  • 8
0

From @nbrooks comment, adding an additional header HTTP header works fine as shown below by using several -H or --header flags to your curl command:


curl -H "comment: Submitting a new data set." -H  "current: false" -H "sheet: 1" -H "row: 7" -F file=@./File.xlsm -F name=file http://example.com/new_file/

comment and current can be combined into "metadata" in the request.headers processing part on the flask web server.

aspiring1
  • 344
  • 1
  • 13
  • 32