0

This question follows on from my previous question on the same subject. Simple file uploads are, well, simple.

 $headers = array("Authorization: Bearer dropbox_token",
                  'Content-Type: application/octet-stream',
                'Dropbox-API-Arg: {"path":"/path/file.ext",
                "mode":"add"}');

 $data = "I love Stackoverflow";
 $ch = curl_init('https://content.dropboxapi.com/2/files/upload/');
 curl_setopt($ch,CURLOPT_HTTPHEADER,$headers);

 curl_setopt($ch,CURLOPT_POST,true);
 curl_setopt($ch,CURLOPT_POSTFIELDS,$data);
 curl_setopt($ch,CURLOPT_RETURNTRANSFER,true);
 $response = curl_exec($ch);
 curl_close($ch);
 echo $response;

However, this is not a viable option when the file data to be save run into 10s of megabytes. I thought I would simply use the new(ish) PHP curl_file_create.

$headers = array("Authorization: Bearer Dropbox token",
              'Content-Type: application/octet-stream',
              'Dropbox-API-Arg: {"path":"/path/bigfile.txt",
                                 "mode":"add"}');

$ch = curl_init('https://content.dropboxapi.com/2/files/upload/');
curl_setopt($ch,CURLOPT_HTTPHEADER,$headers);
$args['file'] = curl_file_create('/path/to/bigfile.txt');

curl_setopt($ch,CURLOPT_POST,true);
curl_setopt($ch,CURLOPT_POSTFIELDS,$args);
curl_setopt($ch,CURLOPT_RETURNTRANSFER,true);
$response = curl_exec($ch);
curl_close($ch);
echo $response;

However, this does not work. The Dropbox API returns the message

Error in call to API function "files/upload": Bad HTTP "Content-Type" header: "application/octet-stream; boundary=--... Expecting one of "application/octet-stream", "text/plain; charset=dropbox-cors-hack

I would be most grateful to anyone who could tell me where I might be going wrong here.

Community
  • 1
  • 1
DroidOS
  • 8,530
  • 16
  • 99
  • 171

2 Answers2

2

It looks like curl_file_create encodes a file as a multipart form upload, which isn't what you want when talking to the Dropbox API.

If I understand correctly, the issue you're trying to address is that you don't want to load the entire file contents into memory. Is that right?

If so, please give the following a try. (Apologies that I haven't tested it at all, so it may contain mistakes.)

$headers = array('Authorization: Bearer Dropbox token',
                 'Content-Type: application/octet-stream',
                 'Dropbox-API-Arg: {"path":"/path/bigfile.txt",
                                    "mode":"add"}');

$ch = curl_init('https://content.dropboxapi.com/2/files/upload');
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_POST, true);

$path = '/path/to/bigfile.txt';
$fp = fopen($path, 'rb');
curl_setopt($ch, CURLOPT_INFILE, $fp);
curl_setopt($ch, CURLOPT_INFILESIZE, filesize($path));

curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);

curl_close($ch);
fclose($fp);

echo $response;

Note that you may also want to consider /files/upload_session_start, etc. if you're uploading large files. That lets you upload in chunks, and it supports files bigger than 150MB (which /files/upload does not).

DroidOS
  • 8,530
  • 16
  • 99
  • 171
user94559
  • 59,196
  • 6
  • 103
  • 103
1

If anyone interested a quick fix on Dropbox API v2 which CURLOPT_INFILE is not working, go to this link Dropbox PHP v2 upload issue

Greg explain and suggested to used this code curl_setopt($ch, CURLOPT_POSTFIELDS, fread($fp, $filesize)) instead of curl_setopt($ch, CURLOPT_INFILE, $fp);

Community
  • 1
  • 1
Eggy
  • 103
  • 1
  • 2
  • 13
  • Nevermind, I posted a better answer here: https://stackoverflow.com/questions/34200164/dropbox-php-v2-upload-issue/34213000#34213000 – Greg Dec 10 '15 at 22:37