Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Posting raw image data as multipart/form-data in curl

I am trying to post an image with cURL in PHP using multipart/form-data header since API that I am sending to is expecting image to be sent as multi-part form.

I don't have problems talking to the API with other requests; only posting an image is an issue.

I am using this form on client side:

<form action="http://myServerURL" method="POST" enctype="multipart/form-data">     <input type="file" name="file" />     <input type="Submit"> </form> 

and this is the server I am posting to (here I am trying to post this data forward to an API):

$ch = curl_init($url); curl_setopt ($ch, CURLOPT_POST, 1); curl_setopt ($ch, CURLOPT_POSTFIELDS, $imgRawData); // <-- raw data here hm? curl_setopt( $ch, CURLOPT_FOLLOWLOCATION, 1); curl_setopt ($ch, CURLOPT_COOKIEFILE, $cookieJar); curl_setopt( $ch, CURLOPT_HEADER, 1); curl_setopt($ch, CURLINFO_HEADER_OUT, 1); <-- using this as I wanted to check if HTTPHEADER is set curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: multipart/form-data')); <-- setting content-type header? curl_setopt( $ch, CURLOPT_RETURNTRANSFER, 1);  // i get response from the server $response = curl_exec( $ch );  // with this I can check what kind of content type the last request had? $requestContentType = curl_getinfo($ch,CURLINFO_CONTENT_TYPE); echo "<br>request Content Type was:".$requestContentType."<br>";      curl_close($ch);  echo "<br><b>SERVER POST IMAGE RESPONSE:</b><br>"; echo $response; 

With the code below I am able to see my request headers:

curl_setopt($ch, CURLOPT_HEADER, 1); curl_setopt($ch, CURLINFO_HEADER_OUT, true);  var_dump(curl_getinfo($ch)); 

The content-type in request-headers is shown correctly now. But it seems the image is not send correctly as API would expect. Unfortunately I don't have access to the API...

Any help appreciated, thank you

like image 572
trainoasis Avatar asked Feb 20 '14 11:02

trainoasis


People also ask

How do you send a multipart file in curl?

With curl, you add each separate multipart with one -F (or --form ) flag and you then continue and add one -F for every input field in the form that you want to send. The above small example form has two parts, one named 'person' that is a plain text field and one named 'secret' that is a file.

How do I post form data using curl?

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.

When should I use multipart form data?

Multipart/form-data should be used for submitting forms that contain large files, non-ASCII data, and large binary data. Moreover, multipart/form-data can be used for forms that are presented using representations like spreadsheets, Portable Document Format, etc. i.e other than HTML.

What is multipart form data format?

Multipart form data: The ENCTYPE attribute of <form> tag specifies the method of encoding for the form data. It is one of the two ways of encoding the HTML form. It is specifically used when file uploading is required in HTML form. It sends the form data to server in multiple parts because of large size of file.


2 Answers

As of PHP 5.6 @$filePath will not work in CURLOPT_POSTFIELDS without CURLOPT_SAFE_UPLOAD being set and it is completely removed in PHP 7. You will need to use a CurlFile object, RFC here.

$fields = [     'name' => new \CurlFile($filePath, 'image/png', 'filename.png') ]; curl_setopt($resource, CURLOPT_POSTFIELDS, $fields); 
like image 57
b3n Avatar answered Oct 09 '22 03:10

b3n


In case anyone had the same problem: check this as @PravinS suggested. I used the exact same code as shown there and it worked for me perfectly.

This is the relevant part of the server code that helped:

if (isset($_POST['btnUpload'])) { $url = "URL_PATH of upload.php"; // e.g. http://localhost/myuploader/upload.php // request URL $filename = $_FILES['file']['name']; $filedata = $_FILES['file']['tmp_name']; $filesize = $_FILES['file']['size']; if ($filedata != '') {     $headers = array("Content-Type:multipart/form-data"); // cURL headers for file uploading     $postfields = array("filedata" => "@$filedata", "filename" => $filename);     $ch = curl_init();     $options = array(         CURLOPT_URL => $url,         CURLOPT_HEADER => true,         CURLOPT_POST => 1,         CURLOPT_HTTPHEADER => $headers,         CURLOPT_POSTFIELDS => $postfields,         CURLOPT_INFILESIZE => $filesize,         CURLOPT_RETURNTRANSFER => true     ); // cURL options     curl_setopt_array($ch, $options);     curl_exec($ch);     if(!curl_errno($ch))     {         $info = curl_getinfo($ch);         if ($info['http_code'] == 200)             $errmsg = "File uploaded successfully";     }     else     {         $errmsg = curl_error($ch);     }     curl_close($ch); } else {     $errmsg = "Please select the file"; } } 

html form should look something like:

<form action="uploadpost.php" method="post" name="frmUpload" enctype="multipart/form-data"> <tr>   <td>Upload</td>   <td align="center">:</td>   <td><input name="file" type="file" id="file"/></td> </tr> <tr>   <td>&nbsp;</td>   <td align="center">&nbsp;</td>   <td><input name="btnUpload" type="submit" value="Upload" /></td> </tr> 

like image 43
trainoasis Avatar answered Oct 09 '22 02:10

trainoasis