Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PHP Curl File Upload sends Empty Upload

Tags:

php

curl

upload

I'm trying to convert the following CURL:

curl -X POST \
  -H "Content-Type: image/jpeg" \
  --data-binary '@myPicture.jpg' \
  https://api.parse.com/1/files/pic.jpg

To PHP:

$ch = curl_init();
$data = array('myPicture.jpg' => "@myPicture.jpg");
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt ($ch, CURLOPT_POSTFIELDS, $data);

$headers = array();
$headers[] = "Content-Type: image/jpeg";
curl_setopt ($ch, CURLOPT_HTTPHEADER, $headers);

curl_setopt ($ch, CURLOPT_URL, 'https://api.parse.com/1/files/myPicture.jpg');

curl_setopt ($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt ($ch, CURLOPT_VERBOSE, true);

$response = curl_exec($ch);
curl_close($ch);

But my response is false. Here is what I get from print_r(curl_getinfo($ch), true):

Array
(
    [url] => https://api.parse.com/1/files/myPicture.jpg
    [content_type] => 
    [http_code] => 0
    [header_size] => 0
    [request_size] => 0
    [filetime] => -1
    [ssl_verify_result] => 20
    [redirect_count] => 0
    [total_time] => 0.28
    [namelookup_time] => 0.187
    [connect_time] => 0.218
    [pretransfer_time] => 0.28
    [size_upload] => 0
    [size_download] => 0
    [speed_download] => 0
    [speed_upload] => 0
    [download_content_length] => -1
    [upload_content_length] => -1
    [starttransfer_time] => 0
    [redirect_time] => 0
)

Any ideas as to why this isnt working? Thanks!

like image 865
Garrett Avatar asked Jun 19 '12 04:06

Garrett


1 Answers

The ssl_verify_result has the value of 20, which means, according to the documentation:

unable to get local issuer certificate

the issuer certificate of a locally looked up certificate could not be found. This normally means the list of trusted certificates is not complete.

You can try without verifying the peer first:

curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);

If that works, you will have to specify the path of a recent CA bundle. See also: http://curl.haxx.se/docs/sslcerts.html


You should also check whether the file you're trying to upload is in the expected folder. If you specify CURLOPT_VERBOSE = 1 it should warn you about this as well.


Update

After checking the API documentation, the service doesn't expect a regular file upload (i.e. "multipart/form-data"); rather, a raw upload is required.

This can be accomplished by:

curl_setopt($ch, CURLOPT_POSTFIELDS, file_get_contents('myPicture.jpg'));
curl_setopt($ch, CURLOPT_HTTPHEADER, array("Content-Type: image/jpeg"));

Update 2 Passing anything using CURLOPT_POSTFIELDS will implicitly set the request method to POST and Content-Type to application/x-www-form-urlencoded. When you pass an array, the values may start with @ to indicate a file upload (doing so should also implicitly change the Content-Type to multipart/form-data).

The command line curl allows the @ in a few places:

  1. using --data-binary to specify a file containing raw binary data
  2. using --data or --data-ascii to specify a file containing url-encoded data
  3. using --F or --form

The latter behaves the same as passing an array to CURLOPT_POSTFIELDS and using the @ prefix. The other two behave the same as passing a string.

like image 183
Ja͢ck Avatar answered Oct 23 '22 02:10

Ja͢ck