diff --git a/phpBB/phpbb/storage/controller/attachment.php b/phpBB/phpbb/storage/controller/attachment.php index f552f17728..c543898356 100644 --- a/phpBB/phpbb/storage/controller/attachment.php +++ b/phpBB/phpbb/storage/controller/attachment.php @@ -24,6 +24,7 @@ use phpbb\request\request; use phpbb\storage\storage; use phpbb\user; use Symfony\Component\HttpFoundation\RedirectResponse; +use Symfony\Component\HttpFoundation\StreamedResponse; class attachment extends controller { @@ -59,6 +60,7 @@ class attachment extends controller $this->request = $request; $this->storage = $storage; $this->user = $user; + $this->response = new StreamedResponse(); } public function handle($file) @@ -203,13 +205,14 @@ class attachment extends controller if (!empty($redirect)) { - $response = new RedirectResponse($redirect); - $response->send(); + $this->response = new RedirectResponse($redirect); } else { $this->send_file_to_browser($attachment, $display_cat); } + + return $this->response->send(); } /** @@ -231,11 +234,6 @@ class attachment extends controller $attachment['mimetype'] = (strpos(strtolower($this->user->browser), 'msie') !== false || strpos(strtolower($this->user->browser), 'opera') !== false) ? 'application/octetstream' : 'application/octet-stream'; } - if (@ob_get_length()) - { - @ob_end_clean(); - } - // Now send the File Contents to the Browser try { @@ -284,10 +282,10 @@ class attachment extends controller } // Now the tricky part... let's dance - header('Cache-Control: public'); + $this->response->setPublic(); // Send out the Headers. Do not set Content-Disposition to inline please, it is a security measure for users using the Internet Explorer. - header('Content-Type: ' . $attachment['mimetype']); + $this->response->headers->set('Content-Type', $attachment['mimetype']); header('X-Content-Type-Options: nosniff'); @@ -310,7 +308,7 @@ class attachment extends controller { if ($size) { - header("Content-Length: $size"); + $this->response->headers->set('Content-Length', $size); } // Try to deliver in chunks @@ -324,14 +322,15 @@ class attachment extends controller if ($fp !== false) { $output = fopen('php://output', 'w+b'); - stream_copy_to_stream($fp, $output); - fclose($fp); + + $this->response->setCallback(function () use ($fp, $output) { + stream_copy_to_stream($fp, $output); + fclose($fp); + fclose($output); + flush(); + }); } - - flush(); } - - exit; } /** diff --git a/phpBB/phpbb/storage/controller/avatar.php b/phpBB/phpbb/storage/controller/avatar.php index add1047a58..8a817af3f4 100644 --- a/phpBB/phpbb/storage/controller/avatar.php +++ b/phpBB/phpbb/storage/controller/avatar.php @@ -17,6 +17,8 @@ use phpbb\cache\service; use phpbb\config\config; use phpbb\db\driver\driver_interface; use phpbb\storage\storage; +use Symfony\Component\HttpFoundation\ResponseHeaderBag; +use Symfony\Component\HttpFoundation\StreamedResponse; class avatar extends controller { @@ -31,13 +33,14 @@ class avatar extends controller $this->config = $config; $this->db = $db; $this->storage = $storage; + $this->response = new StreamedResponse(); } public function handle($file) { $file = $this->decode_avatar_filename($file); - parent::handle($file); + return parent::handle($file); } protected function is_allowed($file) @@ -68,9 +71,15 @@ class avatar extends controller { if (!headers_sent()) { - header("Content-Disposition: inline; filename*=UTF-8''" . rawurlencode($file)); + $disposition = $this->response->headers->makeDisposition( + ResponseHeaderBag::DISPOSITION_INLINE, + rawurlencode($file) + ); - header('Expires: ' . gmdate('D, d M Y H:i:s', time() + 3600*24*365) . ' GMT'); + $this->response->headers->set('Content-Disposition', $disposition); + + $time = new \Datetime(); + $this->response->setExpires($time->modify('+1 year')); } parent::send($file); diff --git a/phpBB/phpbb/storage/controller/controller.php b/phpBB/phpbb/storage/controller/controller.php index 36a12fc99b..c769d7b919 100644 --- a/phpBB/phpbb/storage/controller/controller.php +++ b/phpBB/phpbb/storage/controller/controller.php @@ -17,10 +17,10 @@ use phpbb\cache\service; use phpbb\db\driver\driver_interface; use phpbb\exception\http_exception; use phpbb\storage\storage; +use Symfony\Component\HttpFoundation\StreamedResponse; class controller { - /** @var service */ protected $cache; @@ -30,11 +30,15 @@ class controller /** @var storage */ protected $storage; + /** @var StreamedResponse */ + protected $response; + public function __construct(service $cache, driver_interface $db, storage $storage) { $this->cache = $cache; $this->db = $db; $this->storage = $storage; + $this->response = new StreamedResponse(); } public function handle($file) @@ -50,6 +54,8 @@ class controller } $this->send($file); + + return $this->response->send(); } protected function is_allowed($file) @@ -64,44 +70,43 @@ class controller protected function send($file) { - if (!headers_sent()) + $this->response->setPublic(); + + $file_info = $this->storage->file_info($file); + + try { - header('Cache-Control: public'); + $this->response->headers->set('Content-Type', $file_info->mimetype); + } + catch (\phpbb\storage\exception\exception $e) + { + // Just don't send this header + } - $file_info = $this->storage->file_info($file); + try + { + $this->response->headers->set('Content-Length', $file_info->size); + } + catch (\phpbb\storage\exception\exception $e) + { + // Just don't send this header + } - try - { - header('Content-Type: ' . $file_info->mimetype); - } - catch (\phpbb\storage\exception\exception $e) - { - // Just don't send this header - } + @set_time_limit(0); - try - { - header('Content-Length: ' . $file_info->size); - } - catch (\phpbb\storage\exception\exception $e) - { - // Just don't send this header - } + $fp = $this->storage->read_stream($file); - $fp = $this->storage->read_stream($file); + // Close db connection + $this->file_gc(); - // Close db connection - $this->file_gc(); - - $output = fopen('php://output', 'w+b'); + $output = fopen('php://output', 'w+b'); + $this->response->setCallback(function () use ($fp, $output) { stream_copy_to_stream($fp, $output); - fclose($fp); fclose($output); - flush(); - } + }); } /**