¿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

Respuestas:


254

La siguiente sintaxis lo arregla por usted:

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

¿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

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

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.


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
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.