300

I used this syntax to post a file along with some parameters:

curl -v -include --form "key1=value1" --form upload=localfilename URL 

The file is around 500K in size. First of all, I see content length to be 254 on the transmit side. Later the server response's content length is 0. Where am I going wrong?

Here is the complete trace of the command.

* Couldn't find host xxx.xxx.xxx.xxx in the _netrc file; using defaults * About to connect() to xxx.xxx.xxx.xxx port yyyy (#0) * Trying xxx.xxx.xxx.xxx... * Adding handle: conn: 0x4b96a0 * Adding handle: send: 0 * Adding handle: recv: 0 * Curl_addHandleToPipeline: length: 1 * - Conn 0 (0x4b96a0) send_pipe: 1, recv_pipe: 0 * Connected to xxx.xxx.xxx.xxx (xxx.xxx.xxx.xxx) port yyyy (#0) * POST /zzzzzz/UploadFile HTTP/1.1 * User-Agent: curl/7.32.0 * Host: xxx.xxx.xxx.xxx:yyyy * Accept: */* * Content-Length: 254 * Expect: 100-continue * Content-Type: multipart/form-data; boundary=------------------------948a6137eef50079 * * HTTP/1.1 100 Continue * HTTP/1.1 100 Continue * HTTP/1.1 200 OK * HTTP/1.1 200 OK * Server Apache-Coyote/1.1 is not blacklisted * Server: Apache-Coyote/1.1 * Server: Apache-Coyote/1.1 * Added cookie JSESSIONID="C1D7DD042E250211D9DEA82688876F88" for domain xxx.xxx.xxx.xxx, path /zzzzz/, expire 0 * Set-Cookie: JSESSIONID=C1D7DD042E250211D9DEA82688876F88; Path=/zzzzzz/; * HttpOnly * Set-Cookie: JSESSIONID=C1D7DD042E250211D9DEA82688876F88; Path=/zzzzzz/; HttpOnly * Content-Type: text/html;charset=ISO-8859-1 Content-Type: text/html;charset=ISO-8859-1 * Content-Length: 0 * Content-Length: 0 * Date: Tue, 01 Oct 2013 11:54:24 GMT * Date: Tue, 01 Oct 2013 11:54:24 GMT * Connection #0 to host xxx.xxx.xxx.xxx left intact 
1

7 Answers 7

433

The following syntax fixes it for you:

curl -v -F key1=value1 -F upload=@localfilename URL 
Sign up to request clarification or add additional context in comments.

9 Comments

what about Windows & curl.exe ?
what about multiple attachments?
It works exactly the same on Windows and.it supports multiple "attachments"/files: just add more -F instances!
This answer has a good example of uploading multiple files. stackoverflow.com/questions/11599957/…
This works. on curl we do not need to add something like this: -H 'content-type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW'
|
48

This is what worked for me

curl --form file='@filename' URL 

Firstly, the only mistake the OP made was in not using the @ symbol before the file name. Secondly, my answer which uses file=... only worked for me because the form field I was trying to do the upload for was called file. If your form field is called something else, use that name instead.

Explanation

From the curl manpages; under the description for the option --form it says:

This enables uploading of binary files etc. To force the 'content' part to be a file, prefix the file name with an @ sign. To just get the content part from a file, prefix the file name with the symbol <. The difference between @ and < is then that @ makes a file get attached in the post as a file upload, while the < makes a text field and just get the contents for that text field from a file.

Chances are that if you are trying to do a form upload, you will most likely want to use the @ prefix to upload the file as a binary stream rather than < which uploads the contents of the file as text.

Addendum

Now I must also add that one must be careful with using the < symbol because in most unix shells, < is the input redirection symbol [which coincidentally will also supply the contents of the given file to the standard input of the program before <]. This means that if you do not properly escape that symbol or wrap it in quotes, you may find that your curl command does not behave the way you expect.

On that same note, I will also recommend quoting the @ symbol.


You may also be interested in this other question: application/x-www-form-urlencoded or multipart/form-data?, because curl offers other ways of uploading a file, but they differ in the content-type set in the header. For example the --data option offers a similar mechanism for uploading files as data, but the Content-Type header is set to application/x-www-form-urlencoded whereas with --form, it is set to multipart/form-data.


Anyway, that's all I wanted to say about this answer since it started to get more upvotes. I hope this helps erase any confusions such as the difference between this answer and the accepted answer. There is really none, except for this explanation.

1 Comment

The '@' thing is a top tip! Just saved me, thanks :)
29

To upload a file using curl in Windows, I found that the path requires escaped double quotes.

E.g.,

curl -v -F 'upload=@\"C:/myfile.txt\"' URL 

3 Comments

This answer helped me a lot. Though in my case I should not escape ", that is in my case on Mac I should send it like curl -X POST -F key1=value1 -F 'image=@"/Users/ivkremer/Downloads/file name.jpg"';
in my case - I had a success transfer without any quotes : curl -v -F file=@/Users/path/to/file/testq.jpg 192.168.0.101:8080/upload-image
In my case in Windows, I could not use the single quotes and had to use double quotes like this curl -F "filename=@\"C:\temp\file.jpg\"" https://someurl.com
4

I had a hard time sending a multipart HTTP PUT request with curl to a Java backend. I simply tried

curl -X PUT URL \ --header 'Content-Type: multipart/form-data; boundary=---------BOUNDARY' \ --data-binary @file 

and the content of the file was

-----------BOUNDARY Content-Disposition: form-data; name="name1" Content-Type: application/xml;version=1.0;charset=UTF-8 <xml>content</xml> -----------BOUNDARY Content-Disposition: form-data; name="name2" Content-Type: text/plain content -----------BOUNDARY-- 

but I always got an error that the boundary was incorrect. After some Java backend debugging I found out that the Java implementation was adding a \r\n-- as a prefix to the boundary, so after changing my input file to

 <-- here's the CRLF -------------BOUNDARY <-- added '--' at the beginning ... -------------BOUNDARY <-- added '--' at the beginning ... -------------BOUNDARY-- <-- added '--' at the beginning 

everything works fine!

tl;dr

Add a newline (CRLF \r\n) at the beginning of the multipart boundary content and -- at the beginning of the boundaries and try again.

Maybe you are sending a request to a Java backend that needs this changes in the boundary.

4 Comments

When copying POST data with Firefox web console, I also noticed that it was using \n instead of \r\n. Even mitmproxy copy as cURL was using \n so I had to copy the raw request with mitmproxy. I saw with hexdump that it was using hex code 0A instead of 0D 0A.
the \r\n is required. Look at tools.ietf.org/html/rfc2046#section-5.1.1 page 19.
1. What Java backend framework was that backend based on? 2. Can you please paste the full working curl command?
the curl command doesn't change, just the multipart input file where I added the \r\n--. Framework was Spring Surf
1

On Windows 10, curl 7.28.1 within powershell, I found the following to work for me:

$filePath = "c:\temp\dir with spaces\myfile.wav" $curlPath = ("myfilename=@" + $filePath) curl -v -F $curlPath URL 

Comments

0

With Smartbear Zephyr Scale, server version, you would attach a file to a Test Cycle this way :

curl -H "Authorization: Basic YkskfdygyzghhMg==" -X POST -H "Content-Type: multipart/form-data" https://jira/jira/rest/atm/1.0/testrun/TDLT-C32/attachments --form file="@file2.txt" 

(returns {"id":7099})

where in file2.txt : Test Cycle has also a link to a test plan, and a link to an issue.

{ "projectKey": "TDD", "testPlanKey": "TDD-P1", "name": "Bonjour chez vous, Le Prisonnier", "issueKey": "TDLT-999" } 

I'm posting this since unable to find that out from official documentation :)

Comments

-4

Maybe this form work

curl -X POST -d 'key1=value1&key2=value2' http://URL -H "Content-Type: application/x-www-form-urlencoded" 

1 Comment

clearly the OP is asking for multipart form data, not application urlencoded

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.