backup_migrate-5.0.0-rc2/src/Core/Destination/BrowserDownloadDestination.php
src/Core/Destination/BrowserDownloadDestination.php
<?php
namespace Drupal\backup_migrate\Core\Destination;
use Drupal\backup_migrate\Core\Exception\DestinationNotWritableException;
use Drupal\backup_migrate\Core\File\BackupFileReadableInterface;
use Drupal\backup_migrate\Core\Plugin\PluginCallerInterface;
use Drupal\backup_migrate\Core\Plugin\PluginCallerTrait;
/**
* A destination that downloads files to the browser.
*
* @package Drupal\backup_migrate\Core\Destination
*/
class BrowserDownloadDestination extends StreamDestination implements WritableDestinationInterface, PluginCallerInterface {
use PluginCallerTrait;
/**
* {@inheritdoc}
*/
public function saveFile(BackupFileReadableInterface $file) {
// Set some default download headers.
$headers = [
[
'key' => 'Content-Disposition',
'value' => 'attachment; filename="' . $file->getFullName() . '"',
],
[
'key' => 'Cache-Control',
'value' => 'no-cache',
],
];
// Set a mime-type header.
if ($mime = $file->getMeta('mimetype')) {
$headers[] = ['key' => 'Content-Type', 'value' => $mime];
}
else {
// Get the mime type for this file if possible.
$mime = 'application/octet-stream';
$mime = $this->plugins()->call('alterMime', $mime, [
'ext' => $file->getExtLast(),
]);
$headers[] = ['key' => 'Content-Type', 'value' => $mime];
}
// In some circumstances, web-servers will double compress gzipped files.
// This may help alleviate that issue by disabling mod-deflate.
if ($file->getMeta('mimetype') == 'application/x-gzip') {
if (function_exists('apache_setenv')) {
apache_setenv('no-gzip', '1');
}
$headers[] = ['key' => 'Content-Encoding', 'value' => 'gzip'];
}
if ($size = $file->getMeta('filesize')) {
$headers[] = ['key' => 'Content-Length', 'value' => $size];
}
// Suppress the warning you get when the buffer is empty.
@ob_end_clean();
if ($file->openForRead()) {
foreach ($headers as $header) {
// To prevent HTTP header injection, we delete new lines that are
// not followed by a space or a tab.
// See http://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.2
$header['value'] = preg_replace('/\r?\n(?!\t| )/', '', $header['value']);
header($header['key'] . ': ' . $header['value']);
}
// Transfer file in 1024 byte chunks to save memory usage.
while ($data = $file->readBytes(1024 * 512)) {
print $data;
}
$file->close();
}
// @todo Throw exception.
}
/**
* {@inheritdoc}
*/
public function checkWritable() {
// Check that we're running as a web process via a browser.
// @todo It could check if the 'HTTP_ACCEPT' header contains the right mime
// but that is probably overkill.
if (!isset($_SERVER['REQUEST_METHOD'])) {
throw new DestinationNotWritableException('The download destination only works when accessed through a http client.');
}
}
}
