2013-10-23 61 views
2

我的Django项目使用django_compressor通过django-storages软件包通过boto在S3存储区中存储JavaScript和CSS文件。使用boto时为Amazon S3密钥设置cache-cotrol标题

Django的-存储器相关的配置包括

if 'AWS_STORAGE_BUCKET_NAME' in os.environ: 
    AWS_STORAGE_BUCKET_NAME = os.environ['AWS_STORAGE_BUCKET_NAME'] 
    AWS_HEADERS = { 
     'Cache-Control': 'max-age=100000', 
     'x-amz-acl': 'public-read', 
    } 
    AWS_QUERYSTRING_AUTH = False 

    # This causes images to be stored in Amazon S3 
    DEFAULT_FILE_STORAGE = 'storages.backends.s3boto.S3BotoStorage' 

    # This causes CSS and other static files to be served from S3 as well. 
    STATICFILES_STORAGE = 'storages.backends.s3boto.S3BotoStorage' 
    STATIC_ROOT = '' 
    STATIC_URL = 'https://{0}.s3.amazonaws.com/'.format(AWS_STORAGE_BUCKET_NAME) 

    # This causes conpressed CSS and JavaScript to also go in S3 
    COMPRESS_STORAGE = STATICFILES_STORAGE 
    COMPRESS_URL = STATIC_URL 

这工作只是当我访问的对象在S3管理控制台我看到等于在Cache-Control头签名已改为%3D,如max-age%3D100000,并停止缓存工作。

我写了一个小脚本来尝试沿着这些线路解决这个问题:

max_age = 30000000 
cache_control = 'public, max-age={}'.format(max_age) 

con = S3Connection(settings.AWS_ACCESS_KEY_ID, settings.AWS_SECRET_ACCESS_KEY) 
bucket = con.get_bucket(settings.AWS_STORAGE_BUCKET_NAME) 
for key in bucket.list(): 
    key.set_metadata('Cache-Control', cache_control) 

但显示在亚马逊S3管理控制台这不会改变的元数据。

(更新The documentation for S3 metadata

你上传的对象后,您不能修改对象元数据。修改对象元数据的唯一方法是使该对象的副本,并设置的元数据。欲了解更多您可以使用Amazon S3管理控制台更新对象元数据,但在内部使用对象副本替换现有对象以设置元数据。

因此,也许这并不奇怪,我无法设置元数据。我认为get_metadata仅在首先创建数据时使用。

末更新)

所以我的问题是,第一,我可以配置Django的存储器,使其在第一时间正确地创建cache-control头,二是set_metadata相同的元数据集作为用S3管理控制台查看的元数据,如果不是后者是什么,以及如何以编程方式设置它?

回答

5

使用ASCII字符串作为值为我解决这个问题。

AWS_HEADERS = {'Cache-Control': str('public, max-age=15552000')} 
+0

我试过了,它修复了这个问题。 – pdc

+0

你可以加一个更完整的例子吗?我猜目前在哪里粘贴你的解决方案。 –

+0

有关更正确的示例,我无法正确格式化... ' 'Cache-Control':'max-age = 604800',#60 x 60 x 24 x 7 = 1周 '内容 - 类型':CONTENT_TYPE, } K =密钥(self.get_bucket()) k.key =文件名 k.set_contents_from_string(contents.getvalue(),标头) 如果self.public:K .make_public() ' 为我工作。看到我下面的完整答案... –

0

cache_control是key的属性,而不是元数据的一部分。

所以设置缓存控制在一个桶中的所有对象,你可以这样做:如果你想添加缓存控制,同时上载文件

s3_conn = S3Connection(AWS_KEY, AWS_SECRET) 

bucket = s3_conn.get_bucket(AWS_BUCKET_NAME) 

bucket.make_public() 

for key in bucket.list(): 
    key = bucket.get_key(key.name) 
    key.cache_control = 'max-age=%d, public' % (3600 * 24 * 360 * 2) 
    print key.name + ' ' + key.cache_control 
+0

这不行。正如更新后的问题所述,设置新的缓存控制标头的唯一方法是“移动”文件。 – ehfeng

0

....

headers = { 
    'Cache-Control':'max-age=604800', # 60 x 60 x 24 x 7 = 1 week 
    'Content-Type':content_type, 
    } 

    k = Key(self.get_bucket()) 
    k.key = filename 
    k.set_contents_from_string(contents.getvalue(), headers) 
    if self.public: k.make_public() 

如果你想缓存控制添加到现有的文件...

for key in bucket.list(): 
    print key.name.encode('utf-8') 
    metadata = key.metadata 
    metadata['Cache-Control'] = 'max-age=604800' # 60 x 60 x 24 x 7 = 1 week 
    key.copy(AWS_BUCKET, key, metadata=metadata, preserve_acl=True) 

这博托2.32测试 - 2.40。

相关问题