Force-Download с php на Amazon S3

Я пытаюсь использовать http://code.google.com/p/amazon-s3-php-class/ для принудительной загрузки файлов из AWS S3. У меня есть mp3, который я хочу, чтобы люди «играли» или «загружали». По умолчанию при доступе к файлу непосредственно на s3 он начинает воспроизводиться в браузере. Мне нужно добавить опцию для загрузки. У меня есть Googled и нашел ничего не придумал. Я концептуально знаю, что должно произойти, но не знаю, как произвести его php. Я знаю, что мне нужно изменить заголовки в Content-Disposition: attachment. Любая помощь будет принята с благодарностью.

Спасибо, Майкл

Сценарии 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.

Amazon теперь решила эту проблему и позволяет переопределять заголовки по запросу с запросами на подписку:

http://docs.amazonwebservices.com/AmazonS3/latest/API/index.html?RESTObjectGET.html

w00t!

Просто добавьте это в метаданные вашего файла на s3:

 Content-Disposition: attachment; filename=FILENAME.EXT Content-Type: application/octet-stream 

Просто хочу внести свой вклад в это, Алекс Нет прав в этой ссылке, но я не чувствую, что ссылка является достаточной информацией, используя собственный AWS PHP SDK2 от Amazon. Ниже я изложил базовый (непроверенный) метод для вызова данных таким образом, вы можете использовать S3 Factory Method или AWS Service Builder, чтобы сделать S3 Client.

 <?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/ Этот код в основном псевдокод и может потребовать некоторой дополнительной настройки на самом деле сделать работу, поскольку я ссылаюсь на это из памяти.

Поэтому измените мой пример выше, чтобы быть таким

 <?php header('Content-Type: audio/mpeg'); header("Content-Disposition: attachment; filename={$_GET['file']};"); readfile("url to the file/{$_GET['file']}"); exit(); ?> 

Теперь вы захотите провести там проверку, чтобы вы не предоставили миру доступ к каждому файлу, который вы надели на S3, но это должно сработать.

Если вы используете библиотеку, такую ​​как Tarzan AWS , вы можете добавить заголовки метаданных, которые будут включать амазонки, когда файл будет восстановлен. Ознакомьтесь с мета-параметром в функции update_object здесь, например: http://tarzan-aws.com/docs/2.0/files/s3-class-php.html#AmazonS3.update_object

Также стоит упомянуть, что вы можете жестко настроить заголовки для файлов на S3. Например, если вам нужно принудительно загрузить определенный файл, вы можете установить соответствующие заголовки для этого файла. Такие, как дефолт к потоку, и либо имеющий дополнительный файл, чтобы принудительно загрузить или потратить полосу пропускания для использования php / fputs и принудительной загрузки через PHP.

 <?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 в файле автозагрузки, поместить свой ключ / секрет в конфигурацию, а затем предоставить ведро / имя файла.

php просто загрузит файл на сервер, а не клиент. помните, php ничего не делает на клиенте, он просто возвращает содержимое (html, javascript, css, xml, что угодно …)

[edit: добавлено для ясности]: php может обслуживать аудиоконтент, но вы хотите одновременно обслуживать веб-страницу и аудио. Чтобы получить поведение этого клиента, вы должны заставить клиента запросить файл на основе html или javascript веб-страницы.

Таким образом, вы должны заставить клиента загрузить файл. Например, на iframe есть страница с URL-адресом файла на s3. Используйте css, чтобы сделать iframe невидимым. Он должен отображать страницу, загружать и воспроизводить mp3.

В противном случае изучите использование javascript для загрузки загрузки при загрузке страницы. Я не уверен, что это возможно.

 <?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); 

Теперь это возможно, перезаписав заголовки S3, используя подписанные запросы.

Параметры запроса

Бывают случаи, когда вы хотите переопределить определенные значения заголовка ответа в ответе GET. Например, вы можете переопределить значение заголовка ответа Content-Disposition в запросе GET.

Вы можете переопределить значения для набора заголовков ответов, используя параметры запроса, перечисленные в следующей таблице.

response-content-type – Устанавливает заголовок Content-Type ответа-content-disposition ответа – Устанавливает заголовок Content-Disposition ответа.

Заметка

При использовании этих параметров вы должны подписать запрос, используя заголовок авторизации или предварительно подписанный URL. Они не могут использоваться с неподписанным (анонимным) запросом.

Итак, вы должны установить те заголовки:

 response-content-disposition: attachment; filename=FILENAME.EXT response-content-type: application/octet-stream 

Найден ответ здесь: https://stackoverflow.com/a/5903710/922522

Я никогда не пробовал хостинг Amazon S3, но разве у вас нет доступа к файлам .htaccess? Затем вы можете установить Content-Type и Content-Disposition для всего каталога с этой записью:

 <IfModule mod_headers.c> <FilesMatch "\.(mp3)$"> ForceType audio/mpeg Header set Content-Disposition attachment </FilesMatch> </IfModule>