Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can't send file as form data using cURL

Tags:

php

curl

slim

I am trying to send a cURL request via the command line. Below is my request

curl -i http://localhost/test/index.php 
-X POST 
-F "name=file.png" 
-F "content=@/var/www/html/test/file.png"

The problem I'm having is that the file isn't getting sent with the request. The name is getting sent fine but not the file. Can anyone see if I am doing anything obviously wrong?

I've check the permission on the file as I thought that might be the problem but they are fine

The backend is written using the PHP Slim framework and I'm doing the following $app->request->post('content');

like image 826
Bender Avatar asked Apr 30 '15 23:04

Bender


People also ask

How does curl send form data?

To post form data with Curl, you can use one of two command-line parameters: -F (--form) or -d (--data). The -F command-line parameter sends form data with the multipart/form-data content type, and the -d command-line parameter sends form data with the application/x-www-form-urlencoded content type.

How do I send files with curl?

To post a file with Curl, use the -d or -F command-line options and start the data with the @ symbol followed by the file name. To send multiple files, repeat the -F option several times.

How do you send a file using multipart form data?

Follow this rules when creating a multipart form: Specify enctype="multipart/form-data" attribute on a form tag. Add a name attribute to a single input type="file" tag. DO NOT add a name attribute to any other input, select or textarea tags.

Can curl transfer files?

Uploading files using CURL is pretty straightforward once you've installed it. Several protocols allow CURL file upload including: FILE, FTP, FTPS, HTTP, HTTPS, IMAP, IMAPS, SCP, SFTP, SMB, SMBS, SMTP, SMTPS, and TFTP. Each of these protocols works with CURL differently for uploading data.


1 Answers

If you want to be able to access the file's contents using $app->request->post('content');, your curl request must use a < instead of an @ for the content field,

curl -i http://localhost/test/index.php -X POST -F "name=file.png" \
  -F "content=</var/www/html/test/file.png"

From curl's manpage:

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.

By using @, you marked the field as a file. Technically, this adds a Content-Disposition header to the field (RFC 2388, if you're interested). PHP detects that and automatically stores the field inside $_FILES instead of $_POST, as Raphaël Malié remarked in a comment, which is why you can't access the contents using $app->request->post.

You should consider to switch to using $_FILES in your backend, though, if you want to support uploading using browsers' <input type=file> elements and forms. Those always set a Content-Disposition header.

like image 158
Phillip Avatar answered Sep 20 '22 05:09

Phillip