2014-02-15 3 views
7

Как установить тип содержимого в файле в учетной записи S3 с поддержкой хостинга через модуль Python boto?Невозможно установить тип содержимого файла в S3

Я делаю:

from boto.s3.connection import S3Connection 
from boto.s3.key import Key 
from boto.cloudfront import CloudFrontConnection 

conn = S3Connection(access_key_id, secret_access_key) 
bucket = conn.create_bucket('mybucket') 
b = conn.get_bucket(bucket) 
b.set_acl('public-read') 

fn = 'index.html' 
template = '<html>blah</html>' 
k = Key(b) 
k.key = fn 
k.set_contents_from_string(template) 
k.set_acl('public-read') 
k.set_metadata('Content-Type', 'text/html') 

Однако, когда я к нему доступ из http://mybucket.s3-website-us-east-1.amazonaws.com/index.html мой браузер предложит мне скачать файл вместо того, чтобы просто служить ей в качестве веб-страницы.

Глядя на метаданные в консоли управления S3 показывает, что Content-Type фактически был установлен в «application/octet-stream». Если я вручную изменю его в консоли, я могу получить доступ к этой странице в обычном режиме, но если я снова запустил свой сценарий, он сбрасывает его обратно на неправильный тип контента.

Что я делаю неправильно?

+0

Я не совсем уверен, но, если я правильно помню, процесс _order_ значителен. Попытайтесь изменить порядок своих ключевых операций - установите метаданные «Content-Type» перед настройкой содержимого, например. – lanzz

ответ

14

Метод set_metadata действительно предназначен для установки пользовательских метаданных на объектах S3. Многие стандартные поля метаданных HTTP имеют атрибуты первого класса для их представления, например. content_type. Кроме того, вы хотите установить метаданные, прежде чем отправлять объект на S3. Нечто подобное должно работать:

import boto 

conn = boto.connect_s3() 
bucket = conn.get_bucket('mybucket') # Assumes bucket already exists 
key = bucket.new_key('mykey') 
key.content_type = 'text/html' 
key.set_contents_from_string(mystring, policy='public-read') 

Обратите внимание, что вы можете установить консервированную политику ACL в то время вы пишете объект в S3, который избавляет от необходимости сделать еще один вызов API.

0

Я не смог получить вышеуказанное решение, чтобы фактически сохранить изменения в метаданных.

Возможно, потому, что я использовал файл, и он менял тип контента, используя mimetype? Также я загружаю файлы m3u8 и ts для кодирования HLS, чтобы это также мешало.

В любом случае, вот что сработало для меня.

import boto 
conn = boto.connect_s3() 
bucket = conn.get_bucket('mybucket') 
key_m3u8 = Key(bucket_handle) 
key_m3u8.key = s3folder+"/"+s3keyname 
key_m3u8.metadata = {"Content-Type":"application/x-mpegURL","Cache-Control":"public,max-age=8"}        
key_m3u8.set_contents_from_filename("path_to_my_file", policy="public-read") 
+0

Что такое 'bucket_handle'? –

+0

это просто строка, содержащая имя ведра в S3 – carterh062

Смежные вопросы