Force-Download с php на Amazon S3
Я пытаюсь использовать http://code.google.com/p/amazon-s3-php-class/ для принудительной загрузки файлов из AWS S3. У меня есть mp3, который я хочу, чтобы люди "играли" или "загружали". По умолчанию при доступе к файлу непосредственно на s3 он начинает воспроизводиться в браузере. Мне нужно добавить опцию для загрузки. У меня есть Googled и нашел ничего не придумал. Я концептуально знаю, что должно произойти, но не знаю, как произвести его php. Я знаю, что мне нужно изменить заголовки в Content-Disposition: attachment. Любая помощь будет принята с благодарностью.
Спасибо,
Майкл
Ответы
Ответ 1
Сценарии php, которые были упомянуты до сих пор, будут работать нормально, но основной недостаток заключается в том, что каждый раз, когда посетитель вашего сайта запрашивает файл, ваши собственные серверы загружают его с S3, а затем ретранслируют эти данные в браузер, Для сайтов с низким трафиком это, вероятно, не большое дело, но для трафика с высоким трафиком вы определенно хотите избежать запуска всего через свои собственные серверы.
К счастью, есть довольно простой способ настроить файлы для принудительной загрузки с S3. И вы совершенно правы - вы просто хотите установить контент-тип и контент-расположение (просто настройка содержимого будет работать в некоторых браузерах, но настройка обоих должна работать во всех браузерах).
Этот код предполагает, что вы используете класс Amazon S3 PHP из Undesigned:
<?php
// set S3 auth and get your bucket listing
// then loop through the bucket and copy each file over itself, replacing the "request headers":
S3::copyObject($bucketName, $filename, $bucketName, $filename, "public-read", array(), array("Content-Type" => "application/octet-stream", "Content-Disposition" => "attachment"));
?>
Теперь все ваши файлы будут вынуждены загружаться. Возможно, вам понадобится очистить кеш, чтобы увидеть изменение. И, очевидно, не делайте этого в любом файле, который вы действительно хотите загрузить в браузере "inline".
Приятной частью этого решения является то, что приложения, которые загружают файлы мультимедиа напрямую (например, пусть говорят, mp3-плеер во Flash) не заботятся о типе контента или содержимом, поэтому вы все равно можете воспроизводить свои файлы в браузер, а затем ссылку для загрузки того же файла. Если пользователь уже закончил загрузку файла во флэш-памяти, он, скорее всего, все еще будет иметь его в своем кеше, а это означает, что загрузка будет очень быстрой, и она даже не будет стоить вам каких-либо дополнительных сборов за пропускную способность от S3.
Ответ 2
Amazon теперь решила эту проблему и позволяет переопределять заголовки по запросу с запросами на подписку:
http://docs.amazonwebservices.com/AmazonS3/latest/API/index.html?RESTObjectGET.html
w00t!
Ответ 3
Просто добавьте это в свои метаданные файла на s3:
Content-Disposition: attachment; filename=FILENAME.EXT
Content-Type: application/octet-stream
Ответ 4
Просто желая опубликовать свой вклад в это, Алекс Нет прав в этой ссылке, но я не чувствую, что ссылка является достаточной информацией, используя собственный AWS PHP SDK2 от amazon. Ниже я изложил базовый (непроверенный) метод для вызова данных таким образом, вы можете использовать S3 Factory Method или AWS Service Builder для создания клиента S3.
<?php
// S3 Factory Method
/*use Aws\S3\S3Client;
$s3= S3Client::factory(array(
'key' => '<aws access key>',
'secret' => '<aws secret key>'
));*/
// OR AWS Service Builder
use Aws\Common\Aws;
// Create a service builder using a configuration file
$aws = Aws::factory('/path/to/my_config.json');
// Get the client from the builder by namespace
$s3 = $aws->get('S3');
// Now lets create our request object.
$command = $s3->getCommand('GetObject',array(
'Bucket' => 'your-bucket-name',
'Key' => 'keyname',
'ResponseContentType' => 'application/octet-stream',
'ResponseContentDisposition' => 'attachment; filename="filename.mp3',
));
$url = $command->createPresignedUrl('+1 days');
?>
Затем вы можете использовать заголовок PHP ( "Location: $url" ); Чтобы перенаправить посетителя в файл MP3 с загрузкой силы, это должно помешать ему играть в браузере. Обратите внимание: я часто использую ResponseContentType, но я никогда не использовал ResponseContentDisposition с AWS (он должен работать в соответствии с документами).
Преобразование этого образца в функцию должно быть простым, вы даже можете передать $bucket, $key, $force_download как таковой
<?php
use Aws\Common\Aws;
function gen_url($bucket,$key,$force_download=false){
// OR AWS Service Builder (personal method to do this)
// Create a service builder using a configuration file
$aws = Aws::factory('/path/to/my_config.json');
// Get the client from the builder by namespace
$s3 = $aws->get('S3');
$params = array(
'Bucket' => $bucket,
'Key' => 'keyname',
'ResponseContentType' => 'application/octet-stream',
'ResponseContentDisposition' => 'attachment; filename="filename.mp3',
);
if($force_download){
$params['ResponseContentType'] = 'application/octet-stream';
$params['ResponseContentDisposition'] = 'attachment; filename="'.basename($key).'"';
}
$command = $s3->getCommand('GetObject',$params);
return $command->createPresignedUrl('+1 days');
}
// Location redirection to an MP3 force downlaod
header("Location: ".gen_url("recordings","my-file.mp3",true));
// Location redirection to a MP3 that lets the browser decide what to do.
header("Location: ".gen_url("recordings","my-file.mp3"));
?>
ПРЕДУПРЕЖДЕНИЕ, если вы этого не поняли, для этого требуется AWS PHP SDK 2 (7 апреля 2014 года), найденный здесь http://aws.amazon.com/sdkforphp/ Этот код в основном псевдокод и может потребовать некоторой дополнительной настройки для фактической работы, поскольку я ссылаюсь на это из памяти.
Ответ 5
Так измените мой пример выше, чтобы быть таким
<?php
header('Content-Type: audio/mpeg');
header("Content-Disposition: attachment; filename={$_GET['file']};");
readfile("url to the file/{$_GET['file']}");
exit();
?>
Теперь вы захотите поместить некоторую валидацию там, чтобы вы не предоставляли миру доступ к каждому файлу, который вы помещали на S3, но это должно работать.
Ответ 6
Если вы используете библиотеку, например Tarzan AWS, вы можете добавить заголовки метаданных, которые будут включать амазонки, когда файл будет восстановлен. Проверьте здесь meta-параметр в функции update_object, например:
http://tarzan-aws.com/docs/2.0/files/s3-class-php.html#AmazonS3.update_object
Ответ 7
Также стоит упомянуть, что вы можете жестко настроить заголовки для файлов на S3. Например, если вам нужно принудительно загрузить определенный файл, вы можете установить соответствующие заголовки для этого файла. Такие, как по умолчанию для потока, и либо имеющие дополнительный файл, чтобы принудительно загрузить или потратить полосу пропускания для использования php/fputs и принудительной загрузки через PHP.
Ответ 8
<?php
require_once __DIR__.'/vendor/autoload.php';
use Aws\Common\Aws;
function gen_url($bucket,$key,$force_download=false){
// OR AWS Service Builder (personal method to do this)
$config = array(
'key' => '',
'secret' => '',
);
// Create a service builder using a configuration file
$aws = Aws::factory($config);
// Get the client from the builder by namespace
$s3 = $aws->get('S3');
$params = array(
'Bucket' => $bucket,
'Key' => $key,
'ResponseContentType' => 'application/octet-stream',
'ResponseContentDisposition' => 'attachment; filename="'.$key,
);
if($force_download){
$params['ResponseContentType'] = 'application/octet-stream';
$params['ResponseContentDisposition'] = 'attachment; filename="'.basename($key).'"';
}
$command = $s3->getCommand('GetObject',$params);
return $command->createPresignedUrl('+1 days');
}
$bucket = '';
$filename = '';
$url = gen_url($bucket,$filename,true);
echo "\n".$url."\n\n";
Приведенный выше код работает, вам просто нужно установить зависимость и ссылку на композитор S3 в файле автозагрузки, поместить ключ/секрет в конфигурацию, а затем предоставить ведро/имя файла.
Ответ 9
php просто загрузит файл на сервер, а не клиент. помните, php ничего не делает на клиенте, он просто возвращает содержимое (html, javascript, css, xml, whatever...)
[edit: добавлено для ясности]: php может обслуживать аудиоконтент, но вы хотите одновременно обслуживать веб-страницу и аудио. Чтобы получить поведение этого клиента, вы должны заставить клиента запросить файл на основе html или javascript веб-страницы.
Итак, вы должны заставить клиента загрузить файл. Например, на iframe есть страница с URL-адресом файла на s3. Используйте css, чтобы сделать iframe невидимым. Он должен отображать страницу, загружать и воспроизводить mp3.
В противном случае изучите использование javascript для загрузки загрузки при загрузке страницы. Я не уверен, что это возможно.
Ответ 10
<?php
// PHP solution (for OP and others), works with public and private files
// Download url expires after 30 minutes (no experation after the download initiates, for large files)
// ***Forces client download***
$signed_url = $s3_client->getObjectUrl($s3_bucket_name, $s3_filename_key, '+30 minutes', array(
'ResponseContentType' => 'application/octet-stream',
'ResponseContentDisposition' => 'attachment; filename="your-file-name-here.mp4"'
));
redirect($signed_url);
Ответ 11
Теперь это возможно, перезаписав заголовки S3, используя подписанные запросы.
Параметры запроса
Бывают случаи, когда вы хотите переопределить определенные значения заголовка ответа в ответе GET. Например, вы можете переопределить значение заголовка ответа Content-Disposition в запросе GET.
Вы можете переопределить значения для набора заголовков ответов, используя параметры запроса, перечисленные в следующей таблице.
response-content-type - устанавливает заголовок Content-Type ответа response-content-disposition - устанавливает заголовок Content-Disposition ответа.
Примечание
При использовании этих параметров вы должны подписать запрос, используя заголовок авторизации или предварительно подписанный URL. Они не могут использоваться с неподписанным (анонимным) запросом.
Итак, вы должны установить следующие заголовки:
response-content-disposition: attachment; filename=FILENAME.EXT
response-content-type: application/octet-stream
Найден ответ здесь: fooobar.com/questions/389114/...
Ответ 12
Я никогда не пробовал хостинг Amazon S3, но разве у вас нет доступа к файлам .htaccess? Затем вы можете установить Content-Type и Content-Disposition для всего каталога с этой записью:
<IfModule mod_headers.c>
<FilesMatch "\.(mp3)$">
ForceType audio/mpeg
Header set Content-Disposition attachment
</FilesMatch>
</IfModule>