Skip to content

Commit

Permalink
Fix dropbox storage to not store the whole file in memory
Browse files Browse the repository at this point in the history
Since the library can only store the full response in memory on
download, we use an alternate client lib and set the correct headers to
be able to stream the content to a temp file.
  • Loading branch information
Vincent Petry committed Mar 15, 2016
1 parent ad9a080 commit ab50ba7
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 7 deletions.
2 changes: 1 addition & 1 deletion apps/files_external/3rdparty/Dropbox/OAuth/Curl.php
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,7 @@ private function getOAuthBaseParams() {
* @return array Array for request's headers section like
* array('Authorization' => 'OAuth ...');
*/
private function getOAuthHeader($uri, $params, $method = 'GET', $oAuthParams = null) {
public function getOAuthHeader($uri, $params, $method = 'GET', $oAuthParams = null) {
$oAuthParams = $oAuthParams ? $oAuthParams : $this->getOAuthBaseParams();

// create baseString to encode for the sent parameters
Expand Down
34 changes: 28 additions & 6 deletions apps/files_external/lib/dropbox.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ class Dropbox extends \OC\Files\Storage\Common {
private $root;
private $id;
private $metaData = array();
private $oauth;

private static $tempFiles = array();

Expand All @@ -51,10 +52,10 @@ public function __construct($params) {
) {
$this->root = isset($params['root']) ? $params['root'] : '';
$this->id = 'dropbox::'.$params['app_key'] . $params['token']. '/' . $this->root;
$oauth = new \Dropbox_OAuth_Curl($params['app_key'], $params['app_secret']);
$oauth->setToken($params['token'], $params['token_secret']);
$this->oauth = new \Dropbox_OAuth_Curl($params['app_key'], $params['app_secret']);
$this->oauth->setToken($params['token'], $params['token_secret']);
// note: Dropbox_API connection is lazy
$this->dropbox = new \Dropbox_API($oauth, 'auto');
$this->dropbox = new \Dropbox_API($this->oauth, 'auto');
} else {
throw new \Exception('Creating \OC\Files\Storage\Dropbox storage failed');
}
Expand Down Expand Up @@ -248,10 +249,31 @@ public function fopen($path, $mode) {
switch ($mode) {
case 'r':
case 'rb':
$tmpFile = \OCP\Files::tmpFile();
try {
$data = $this->dropbox->getFile($path);
file_put_contents($tmpFile, $data);
// slashes need to stay
$encodedPath = str_replace('%2F', '/', rawurlencode(trim($path, '/')));
$downloadUrl = 'https://api-content.dropbox.com/1/files/auto/' . $encodedPath;
$headers = $this->oauth->getOAuthHeader($downloadUrl, [], 'GET');

$client = \OC::$server->getHTTPClientService()->newClient();
try {
$tmpFile = \OC::$server->getTempManager()->getTemporaryFile();
$client->get($downloadUrl, [
'headers' => $headers,
'save_to' => $tmpFile,
]);
} catch (RequestException $e) {
if (!is_null($e->getResponse())) {
if ($e->getResponse()->getStatusCode() === 404) {
return false;
} else {
throw $e;
}
} else {
throw $e;
}
}

return fopen($tmpFile, 'r');
} catch (\Exception $exception) {
\OCP\Util::writeLog('files_external', $exception->getMessage(), \OCP\Util::ERROR);
Expand Down

0 comments on commit ab50ba7

Please sign in to comment.