1
0
mirror of https://github.com/phpbb/phpbb.git synced 2025-06-06 22:45:02 +02:00

[ticket/14285] Use StreamedResponse

PHPBB3-14285
This commit is contained in:
Rubén Calvo 2018-07-04 23:42:09 +02:00 committed by rubencm
parent 7b678fdbfa
commit 05c44e74b3
3 changed files with 60 additions and 47 deletions

View File

@ -24,6 +24,7 @@ use phpbb\request\request;
use phpbb\storage\storage; use phpbb\storage\storage;
use phpbb\user; use phpbb\user;
use Symfony\Component\HttpFoundation\RedirectResponse; use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\StreamedResponse;
class attachment extends controller class attachment extends controller
{ {
@ -59,6 +60,7 @@ class attachment extends controller
$this->request = $request; $this->request = $request;
$this->storage = $storage; $this->storage = $storage;
$this->user = $user; $this->user = $user;
$this->response = new StreamedResponse();
} }
public function handle($file) public function handle($file)
@ -203,13 +205,14 @@ class attachment extends controller
if (!empty($redirect)) if (!empty($redirect))
{ {
$response = new RedirectResponse($redirect); $this->response = new RedirectResponse($redirect);
$response->send();
} }
else else
{ {
$this->send_file_to_browser($attachment, $display_cat); $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'; $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 // Now send the File Contents to the Browser
try try
{ {
@ -284,10 +282,10 @@ class attachment extends controller
} }
// Now the tricky part... let's dance // 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. // 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'); header('X-Content-Type-Options: nosniff');
@ -310,7 +308,7 @@ class attachment extends controller
{ {
if ($size) if ($size)
{ {
header("Content-Length: $size"); $this->response->headers->set('Content-Length', $size);
} }
// Try to deliver in chunks // Try to deliver in chunks
@ -324,14 +322,15 @@ class attachment extends controller
if ($fp !== false) if ($fp !== false)
{ {
$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); stream_copy_to_stream($fp, $output);
fclose($fp); fclose($fp);
} fclose($output);
flush(); flush();
});
}
} }
exit;
} }
/** /**

View File

@ -17,6 +17,8 @@ use phpbb\cache\service;
use phpbb\config\config; use phpbb\config\config;
use phpbb\db\driver\driver_interface; use phpbb\db\driver\driver_interface;
use phpbb\storage\storage; use phpbb\storage\storage;
use Symfony\Component\HttpFoundation\ResponseHeaderBag;
use Symfony\Component\HttpFoundation\StreamedResponse;
class avatar extends controller class avatar extends controller
{ {
@ -31,13 +33,14 @@ class avatar extends controller
$this->config = $config; $this->config = $config;
$this->db = $db; $this->db = $db;
$this->storage = $storage; $this->storage = $storage;
$this->response = new StreamedResponse();
} }
public function handle($file) public function handle($file)
{ {
$file = $this->decode_avatar_filename($file); $file = $this->decode_avatar_filename($file);
parent::handle($file); return parent::handle($file);
} }
protected function is_allowed($file) protected function is_allowed($file)
@ -68,9 +71,15 @@ class avatar extends controller
{ {
if (!headers_sent()) 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); parent::send($file);

View File

@ -17,10 +17,10 @@ use phpbb\cache\service;
use phpbb\db\driver\driver_interface; use phpbb\db\driver\driver_interface;
use phpbb\exception\http_exception; use phpbb\exception\http_exception;
use phpbb\storage\storage; use phpbb\storage\storage;
use Symfony\Component\HttpFoundation\StreamedResponse;
class controller class controller
{ {
/** @var service */ /** @var service */
protected $cache; protected $cache;
@ -30,11 +30,15 @@ class controller
/** @var storage */ /** @var storage */
protected $storage; protected $storage;
/** @var StreamedResponse */
protected $response;
public function __construct(service $cache, driver_interface $db, storage $storage) public function __construct(service $cache, driver_interface $db, storage $storage)
{ {
$this->cache = $cache; $this->cache = $cache;
$this->db = $db; $this->db = $db;
$this->storage = $storage; $this->storage = $storage;
$this->response = new StreamedResponse();
} }
public function handle($file) public function handle($file)
@ -50,6 +54,8 @@ class controller
} }
$this->send($file); $this->send($file);
return $this->response->send();
} }
protected function is_allowed($file) protected function is_allowed($file)
@ -64,15 +70,13 @@ class controller
protected function send($file) protected function send($file)
{ {
if (!headers_sent()) $this->response->setPublic();
{
header('Cache-Control: public');
$file_info = $this->storage->file_info($file); $file_info = $this->storage->file_info($file);
try try
{ {
header('Content-Type: ' . $file_info->mimetype); $this->response->headers->set('Content-Type', $file_info->mimetype);
} }
catch (\phpbb\storage\exception\exception $e) catch (\phpbb\storage\exception\exception $e)
{ {
@ -81,13 +85,15 @@ class controller
try try
{ {
header('Content-Length: ' . $file_info->size); $this->response->headers->set('Content-Length', $file_info->size);
} }
catch (\phpbb\storage\exception\exception $e) catch (\phpbb\storage\exception\exception $e)
{ {
// Just don't send this header // Just don't send this header
} }
@set_time_limit(0);
$fp = $this->storage->read_stream($file); $fp = $this->storage->read_stream($file);
// Close db connection // Close db connection
@ -95,13 +101,12 @@ class controller
$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); stream_copy_to_stream($fp, $output);
fclose($fp); fclose($fp);
fclose($output); fclose($output);
flush(); flush();
} });
} }
/** /**