diff --git a/controller/documentcontroller.php b/controller/documentcontroller.php index ae671ec8..dd2cc69a 100644 --- a/controller/documentcontroller.php +++ b/controller/documentcontroller.php @@ -21,8 +21,10 @@ use \OCA\Documents\Db; use \OCA\Documents\Helper; use \OCA\Documents\Storage; use \OCA\Documents\Download; +use \OCA\Documents\DownloadResponse; use \OCA\Documents\File; use OCA\Documents\Genesis; +use \OCA\Documents\View; class DocumentController extends Controller{ @@ -84,8 +86,7 @@ class DocumentController extends Controller{ $session->load($esId); $filename = $session->getGenesisUrl() ? $session->getGenesisUrl() : ''; - $download = new Download($session->getOwner(), $filename); - $download->sendResponse(); + return new DownloadResponse($this->request, $session->getOwner(), $filename); } /** @@ -101,11 +102,12 @@ class DocumentController extends Controller{ } else { $fullPath = '/files' . $path; } - $download = new Download($this->uid, $fullPath); - $download->sendResponse(); + + return new DownloadResponse($this->request, $this->uid, $fullPath); } } + /** * @NoAdminRequired */ diff --git a/lib/download.php b/lib/download.php deleted file mode 100644 index 255591d4..00000000 --- a/lib/download.php +++ /dev/null @@ -1,113 +0,0 @@ -filepath = $filepath; - - if (isset($_SERVER['HTTP_RANGE'])) { - $this->instance = new Download\Range($owner, $filepath); - } else { - $this->instance = new Download\Simple($owner, $filepath); - } - - $this->view = $this->getView($owner); - } - - protected function getView($owner){ - return new View('/' . $owner); - } - - /** - * Send the requested content - */ - public function sendResponse(){ - \OCP\Response::disableCaching(); - - if (!$this->fileExists()){ - $this->sendNotFound(); - } - - $this->instance->sendResponse(); - exit(); - } - - /** - * Get the name of the requested file - * @return String - */ - protected function getFilename(){ - return basename($this->filepath); - } - - /** - * Get the size of the requested file - */ - protected function getFilesize(){ - return $this->view->filesize($this->filepath); - } - - /** - * Get the mimetype of the requested file - * @return string - */ - protected function getMimeType(){ - return $this->view->getMimeType($this->filepath); - } - - /** - * Check if the requested file exists - * @return bool - */ - protected function fileExists(){ - return $this->view->file_exists($this->filepath); - } - - /** - * Send 404 Response - */ - protected function sendNotFound(){ - header("HTTP/1.0 404 Not Found"); - $tmpl = new \OCP\Template('', '404', 'guest'); - $tmpl->assign('file', $this->filepath); - $tmpl->printPage(); - exit; - } -} diff --git a/lib/download/range.php b/lib/download/range.php deleted file mode 100644 index 8344a531..00000000 --- a/lib/download/range.php +++ /dev/null @@ -1,92 +0,0 @@ -view = $this->getView($owner); - $this->filepath = $filepath; - } - - /** - * Send the requested parts of the file - */ - public function sendResponse(){ - if (!preg_match('/^bytes=\d*-\d*(,\d*-\d*)*$/', $_SERVER['HTTP_RANGE'])){ - $this->sendNotSatisfiable(); - } - - $mimetype = $this->getMimeType(); - $content = $this->view->file_get_contents($this->filepath); - $data = \OCA\Documents\Filter::read($content, $mimetype); - $size = strlen($data['content']); - - $ranges = explode(',', substr($_SERVER['HTTP_RANGE'], 6)); - foreach ($ranges as $range){ - $parts = explode('-', $range); - - if ($parts[0]==='' && $parts[1]=='') { - $this->sendNotSatisfiable(); - } - if ($parts[0]==='') { - $start = $size - $parts[1]; - $end = $size - 1; - } - else { - $start = $parts[0]; - $end = ($parts[1]==='') ? $size - 1 : $parts[1]; - } - - if ($start > $end){ - $this->sendNotSatisfiable(); - } - - $buffer = substr($data['content'], $start, $end - $start); - $md5Sum = md5($buffer); - - // send the headers and data - header("Content-Length: " . ($end - $start)); - header("Content-md5: " . $md5Sum); - header("Accept-Ranges: bytes"); - header('Content-Range: bytes ' . $start . '-' . ($end) . '/' . $size); - header("Connection: close"); - header("Content-type: " . $data['mimetype']); - header('Content-Disposition: attachment; filename=' . $this->getFilename()); - \OC_Util::obEnd(); - echo $buffer; - flush(); - } - } - - /** - * Send 416 if we can't satisfy the requested ranges - */ - protected function sendNotSatisfiable(){ - header('HTTP/1.1 416 Requested Range Not Satisfiable'); - header('Content-Range: bytes */' . $this->getFilesize()); // Required in 416. - exit; - } -} diff --git a/lib/download/simple.php b/lib/download/simple.php deleted file mode 100644 index 916249e7..00000000 --- a/lib/download/simple.php +++ /dev/null @@ -1,50 +0,0 @@ -view = $this->getView($owner); - $this->filepath = $filepath; - } - - /** - * Send the whole file content as a response - */ - public function sendResponse(){ - $mimetype = $this->getMimeType(); - $content = $this->view->file_get_contents($this->filepath); - $data = \OCA\Documents\Filter::read($content, $mimetype); - - header( 'Content-Type:' . $data['mimetype'] ); - - $encodedName = rawurlencode($this->getFilename()); - if (preg_match("/MSIE/", $_SERVER["HTTP_USER_AGENT"])){ - header( - 'Content-Disposition: attachment; filepath="' . $encodedName . '"' - ); - } else { - header('Content-Disposition: attachment; filepath*=UTF-8\'\'' . $encodedName - . '; filepath="' . $encodedName . '"'); - } - - header('Content-Length: ' . strlen($data['content'])); - - \OC_Util::obEnd(); - - echo $data['content']; - } -} diff --git a/lib/downloadresponse.php b/lib/downloadresponse.php new file mode 100644 index 00000000..618aea9f --- /dev/null +++ b/lib/downloadresponse.php @@ -0,0 +1,115 @@ +request = $request; + $this->user = $user; + $this->path = $path; + $this->view = new View('/' . $user); + if (!$this->view->file_exists($path)){ + $this->setStatus(Http::STATUS_NOT_FOUND); + } + } + + public function render(){ + if ($this->status === Http::STATUS_NOT_FOUND){ + return ''; + } + + $info = $this->view->getFileInfo($this->path); + $this->ETag = $info['etag']; + + $content = $this->view->file_get_contents($this->path); + $data = \OCA\Documents\Filter::read($content, $info['mimetype']); + $size = strlen($data['content']); + + + if (!is_null($this->request->server['HTTP_RANGE'])){ + $isValidRange = preg_match('/^bytes=\d*-\d*(,\d*-\d*)*$/', $this->request->server['HTTP_RANGE']); + if (!$isValidRange){ + return $this->sendRangeNotSatisfiable($size); + } + + $ranges = explode(',', substr($this->request->server['HTTP_RANGE'], 6)); + foreach ($ranges as $range){ + $parts = explode('-', $range); + + if ($parts[0]==='' && $parts[1]=='') { + $this->sendNotSatisfiable($size); + } + if ($parts[0]==='') { + $start = $size - $parts[1]; + $end = $size - 1; + } else { + $start = $parts[0]; + $end = ($parts[1]==='') ? $size - 1 : $parts[1]; + } + + if ($start > $end){ + $this->sendNotSatisfiable($size); + } + + $buffer = substr($data['content'], $start, $end - $start); + $md5Sum = md5($buffer); + + // send the headers and data + $this->addHeader('Content-Length', $end - $start); + $this->addHeader('Content-md5', $md5Sum); + $this->addHeader('Accept-Ranges', 'bytes'); + $this->addHeader('Content-Range', 'bytes ' . $start . '-' . ($end) . '/' . $size); + $this->addHeader('Connection', 'close'); + $this->addHeader('Content-Type', $data['mimetype']); + $this->addContentDispositionHeader(); + return $buffer; + } + } + + $this->addHeader('Content-Type', $data['mimetype']); + $this->addContentDispositionHeader(); + $this->addHeader('Content-Length', $size); + + return $data['content']; + } + + /** + * Send 416 if we can't satisfy the requested ranges + */ + protected function sendRangeNotSatisfiable($filesize){ + $this->setStatus(Http::STATUS_REQUEST_RANGE_NOT_SATISFIABLE); + $this->addHeader('Content-Range', 'bytes */' . $filesize); // Required in 416. + return ''; + } + + protected function addContentDispositionHeader(){ + $encodedName = rawurlencode(basename($this->path)); + $isIE = preg_match("/MSIE/", $this->request->server["HTTP_USER_AGENT"]); + if ($isIE){ + $this->addHeader( + 'Content-Disposition', + 'attachment; filename="' . $encodedName . '"' + ); + } else { + $this->addHeader( + 'Content-Disposition', + 'attachment; filename*=UTF-8\'\'' . $encodedName . '; filepath="' . $encodedName . '"' + ); + } + } +}