Qual é a maneira correta de POST multipart / form-data usando curl?


164

Eu usei essa sintaxe para postar um arquivo junto com alguns parâmetros:

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

O arquivo tem cerca de 500 K de tamanho. Primeiro de tudo, vejo o comprimento do conteúdo em 254 no lado da transmissão. Mais tarde, o tamanho do conteúdo da resposta do servidor é 0. Onde estou errado?

Aqui está o rastreamento completo do comando.

* 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

Respostas:


254

A sintaxe a seguir corrige isso para você:

curl -v -F key1=value1 -F upload=@localfilename URL

o que acontece com o Windows e o curl.exe?
Piotr

1
que tal vários anexos?
Hellboy

8
Funciona exatamente da mesma maneira no Windows e suporta vários "anexos" / arquivos: basta adicionar mais instâncias -F!
Daniel Stenberg

Esta resposta tem um bom exemplo de upload de vários arquivos. stackoverflow.com/questions/11599957/…
bmoran

Isso funciona. no curl, não precisamos adicionar algo parecido com isto: #-H 'content-type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW'
Emily

19

para carregar um arquivo usando curl no Windows, descobri que o caminho requer aspas duplas de escape

por exemplo

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

1
Essa resposta me ajudou muito. Embora no meu caso eu não deva escapar ", no meu caso no Mac devo enviá-lo como curl -X POST -F key1=value1 -F 'image=@"/Users/ivkremer/Downloads/file name.jpg"';
Ivkremer 31/05/19

no meu caso - tive uma transferência bem-sucedida sem aspas: curl -v -F file=@/Users/path/to/file/testq.jpg 192.168.0.101:8080/upload-image
chatlanin

No meu caso no Windows, eu não podia usar aspas simples e tinha que usar aspas duplas como estacurl -F "filename=@\"C:\temp\file.jpg\"" https://someurl.com
Beems

5

Isto é o que funcionou para mim

curl -F file=@filename URL

1

Foi difícil enviar uma solicitação HTTP PUT de várias partes curlpara um back-end Java. Eu simplesmente tentei

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

e o conteúdo do arquivo foi

-----------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--

mas sempre recebia um erro informando que o limite estava incorreto. Após alguma depuração de back-end do Java, descobri que a implementação do Java estava adicionando um\r\n-- como prefixo ao limite, portanto, depois de alterar meu arquivo de entrada para

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

tudo funciona bem!

tl; dr

Adicionar uma nova linha (CRLF \r\n ) no início do conteúdo do limite de várias partes e --no início dos limites e tente novamente.

Talvez você esteja enviando uma solicitação para um back-end Java que precisa dessas alterações no limite.


Ao copiar dados do POST com o console da web do Firefox, também notei que ele estava usando em \nvez de \r\n. Até a cópia mitmproxy como cURL estava usando, \nentão tive que copiar a solicitação bruta com mitmproxy. Eu vi no hexdump que ele estava usando código hexadecimal em 0Avez de 0D 0A.
baptx

o \r\né necessária. Veja tools.ietf.org/html/rfc2046#section-5.1.1 página 19.
Adam Zahran

0

No Windows 10, enrolar 7.28.1 no PowerShell, achei o seguinte para trabalhar para mim:

$filePath = "c:\temp\dir with spaces\myfile.wav"
$curlPath = ("myfilename=@" + $filePath)
curl -v -F $curlPath URL
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.