¿Cuál es la forma correcta de PUBLICAR datos multiparte / formulario utilizando curl?

164

Usé esta sintaxis para publicar un archivo junto con algunos parámetros:

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

El archivo tiene alrededor de 500K de tamaño. En primer lugar, veo que la longitud del contenido es de 254 en el lado de transmisión. Más tarde, la longitud del contenido de la respuesta del servidor es 0. ¿Dónde me estoy equivocando?

Aquí está el rastro completo del 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
Kamalakshi
fuente
posible duplicado de Usar curl para cargar datos POST con archivos
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功

Respuestas:

254

La siguiente sintaxis lo arregla por usted:

curl -v -F key1=value1 -F upload=@localfilename URL
Kamalakshi
fuente
¿Qué pasa con Windows y curl.exe?
Piotr
1
¿Qué pasa con los archivos adjuntos múltiples?
hellboy
8
Funciona exactamente igual en Windows y es compatible con múltiples "archivos adjuntos" / archivos: ¡simplemente agregue más instancias -F!
Daniel Stenberg
Esta respuesta tiene un buen ejemplo de carga de múltiples archivos. stackoverflow.com/questions/11599957/…
bmoran
Esto funciona. el rizo no es necesario añadir algo como esto:-H 'content-type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW'
Emily
19

para cargar un archivo usando curl en Windows descubrí que la ruta requiere comillas dobles escapadas

p.ej

curl -v -F 'upload=@\"C:/myfile.txt\"' URL
Logan Scott
fuente
1
Esta respuesta me ayudó mucho. Aunque en mi caso no debería escapar ", eso es en mi caso en Mac, debería enviarlo como curl -X POST -F key1=value1 -F 'image=@"/Users/ivkremer/Downloads/file name.jpg"';
ivkremer
en mi caso, tuve una transferencia exitosa sin ninguna cita: curl -v -F file=@/Users/path/to/file/testq.jpg 192.168.0.101:8080/upload-image
chatlanin
En mi caso en Windows, no pude usar comillas simples y tuve que usar comillas dobles como estacurl -F "filename=@\"C:\temp\file.jpg\"" https://someurl.com
Beems
5

Esto es lo que funcionó para mí.

curl -F file=@filename URL
smac89
fuente
1

Me costó enviar una solicitud PUT HTTP multiparte curla un backend de Java. Simplemente intenté

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

y el contenido del archivo era

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

pero siempre recibí un error de que el límite era incorrecto. Después de la depuración del backend de Java, descubrí que la implementación de Java estaba agregando un \r\n--como prefijo al límite, así que después de cambiar mi archivo de entrada a

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

todo funciona bien!

tl; dr

Agregue una nueva línea (CRLF \r\n) al comienzo del contenido del límite multiparte y --al comienzo de los límites e intente nuevamente.

Tal vez está enviando una solicitud a un servidor Java que necesita estos cambios en el límite.

Lusk116
fuente
Al copiar datos POST con la consola web de Firefox, también noté que estaba usando en \nlugar de \r\n. Incluso mitmproxy copy como cURL estaba usando, \nasí que tuve que copiar la solicitud sin procesar con mitmproxy. Vi con hexdump que estaba usando código hexadecimal en 0Alugar de 0D 0A.
baptx
el \r\nse requiere. Mire tools.ietf.org/html/rfc2046#section-5.1.1 página 19.
Adam Zahran
0

En Windows 10, curl 7.28.1 dentro de powershell, encontré que lo siguiente funciona para mí:

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