2

I am currently implementing an upload mechanism for files on my webserver into my Dropbox app directory.

As stated on the API docs, there is the /upload endpoint (https://www.dropbox.com/developers/documentation/http/documentation#files-upload) which accepts files up to 150MB in size. However I‘m dealing with images and videos with a potential size of up to 2GB.

Therefore I need to use the upload_session endpoints. There is an endpoint to start the session (https://www.dropbox.com/developers/documentation/http/documentation#files-upload_session-start), to append data and to finish the session.

What currently is unclear to me is how to exactly use these endpoints. Do I have to split my file on my server into 150MB chunks (how would I do that with a video file?) and then upload the first chunk with /start, the next chunks with /append and the last one with /finish? Or can I just specify the file and the API somehow (??) does the splitting for me? Obviously not, but I somehow can‘t get my head around on how I should calculate, split and store the chunks on my webserver and not lose the session inbetween...

Any advice or further leading links are greatly appreciated. Thank you!

2
  • You have to do the splitting yourself - otherwise there would be no point in providing this mechanism. Maybe you can find or create a wrapper on your server to abstract the splitting from your "move to dropbox" function Commented Jul 7, 2019 at 10:39
  • 2
    The above comment is correct; you need to split up the file into pieces yourself, of whatever size you want. (Up to 150 MB is technically supported, but you generally should use something smaller in practice, such as 8 MB.) Here's an example using the official Dropbox API v2 .NET SDK that shows the logic, as well as how one might read off the arbitrary chunk size. Commented Jul 8, 2019 at 23:15

2 Answers 2

4

As Greg mentioned in the comments, you decide how to manage the "chunks" of the files. In addition to his .NET example, Dropbox has a good upload session implementation in the JavaScript upload example of the Dropbox API v2 JavaScript SDK.

At a high-level, you're splitting up the file into smaller sizes (aka "chunks") and passing those to the upload_session mechanism in a specific order. The upload mechanism has a few parts that need to be used in the following order:

  1. Call /files/upload_session/start. Use the resulting session_id as a parameter in the following methods so Dropbox knows which session you're interacting with.
  2. Incrementally pass each "chunk" of the file to /files/upload_session/append_v2. A couple things to be aware of:

    • The first call will return a cursor, which is used to iterate over the file's chunks in a specific order. It gets passed as a parameter in each consecutive call to this method (with the cursor being updated on every response).
    • The final call must include the property "close": true, which closes the session so it can be uploaded.
  3. Pass the final cursor (and commit info) to /files/upload_session/finish. If you see the new file metadata in the response, then you did it!!

Sign up to request clarification or add additional context in comments.

2 Comments

Just a small hint on your description: I did spare the final chunk to upload it with the /finish method, instead of calling /append and closing the cursor. Otherwise this answer perfectly sums up how I could solve my problem - thank you a lot!
This example is exactly what I was looking for, thank you!
2

I know this is an old post, but here is a fully functional solution for your problem. Maybe anyone else finds it usefull. :)

<?php

$backup_folder = glob('/var/www/test_folder/*.{sql,gz,rar,zip}', GLOB_BRACE); // Accepted file types (sql,gz,rar,zip)
$token = '<ACCESS TOKEN>'; // Dropbox Access Token;
$append_url = 'https://content.dropboxapi.com/2/files/upload_session/append_v2';
$start_url = 'https://content.dropboxapi.com/2/files/upload_session/start';
$finish_url = 'https://content.dropboxapi.com/2/files/upload_session/finish';
if (!empty($backup_folder)) {
foreach ($backup_folder as $single_folder_file) {
    $file_name= basename($single_folder_file); // File name
    $destination_folder = 'destination_folder'; // Dropbox destination folder
    $info_array = array();
    $info_array["close"] = false;
    $headers = array(
        'Authorization: Bearer ' . $token,
        'Content-Type: application/octet-stream',
        'Dropbox-API-Arg: '.json_encode($info_array)
        );
    $chunk_size = 50000000; // 50mb

    $fp = fopen($single_folder_file, 'rb');
    $fileSize = filesize($single_folder_file); // File size
    $tosend = $fileSize;
    $first = $tosend > $chunk_size ? $chunk_size : $tosend;

    $ch = curl_init($start_url);
    curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_POSTFIELDS, fread($fp, $first));
    curl_setopt($ch,CURLOPT_RETURNTRANSFER,true);
    $response = curl_exec($ch);
    $tosend -= $first;

    $resp = explode('"',$response);

    $sesion = $resp[3];
    $position = $first;

    $info_array["cursor"] = array();
    $info_array["cursor"]["session_id"] = $sesion;

    while ($tosend > $chunk_size)
    {
        $info_array["cursor"]["offset"] = $position;
        $headers[2] = 'Dropbox-API-Arg: '.json_encode($info_array);

        curl_setopt($ch, CURLOPT_URL, $append_url);
        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
        curl_setopt($ch, CURLOPT_POSTFIELDS, fread($fp, $chunk_size));
        curl_exec($ch);

        $tosend -= $chunk_size;
        $position += $chunk_size;
    }
    unset($info_array["close"]);
    $info_array["cursor"]["offset"] = $position;
    $info_array["commit"] = array();
    $info_array["commit"]["path"] = '/'. $destination_folder . '/' . $file_name;
    $info_array["commit"]["mode"] = array();
    $info_array["commit"]["mode"][".tag"] = "overwrite";
    $info_array["commit"]["autorename"] = true;
    $info_array["commit"]["mute"] = false;
    $info_array["commit"]["strict_conflict"] = false;
    $headers[2] = 'Dropbox-API-Arg: '. json_encode($info_array);

    curl_setopt($ch, CURLOPT_URL, $finish_url);
    curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $tosend > 0 ? fread($fp, $tosend) : null);
    curl_exec($ch);
    curl_close($ch);
    fclose($fp);
    unlink($single_folder_file); // Remove files from server folder
    }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.