Fix dropbox storage to not store the whole file in memory

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.
This commit is contained in:
Vincent Petry 2016-03-15 17:22:16 +01:00
parent 5ca10cf6f8
commit 443d72ee87
2 changed files with 29 additions and 7 deletions

View File

@ -196,7 +196,7 @@ class Dropbox_OAuth_Curl extends Dropbox_OAuth {
* @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

View File

@ -39,6 +39,7 @@ class Dropbox extends \OC\Files\Storage\Common {
private $root;
private $id;
private $metaData = array();
private $oauth;
private static $tempFiles = array();
@ -51,10 +52,10 @@ class Dropbox extends \OC\Files\Storage\Common {
) {
$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');
}
@ -248,10 +249,31 @@ class Dropbox extends \OC\Files\Storage\Common {
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);