1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62 | ## aws_tags.py
################
import urllib
from django import template
from django.conf import settings
from django.core.files.base import File as DjangoFile
from django.utils.safestring import mark_safe
from cloudfront import sign_streaming
register = template.Library()
def aws_rtmp_streamer():
return 'rtmp://%s/cfx/st' % settings.CLOUDFRONT_DOMAIN
register.simple_tag(aws_rtmp_streamer)
def aws_sign_cf_stream(f):
if isinstance(f, DjangoFile):
f = f.name
if not isinstance(f, basestring):
raise ValueError, "Must be string or django.core.files.base.File"
signed = sign_streaming(f)
return mark_safe(urllib.quote(signed)) # urls for flowplayer must be quoted
register.filter(aws_sign_cf_stream)
## cloudfront.py
#################
import hashlib
import base64
import os
import time
from M2Crypto import RSA
from django.conf import settings
from django.utils import simplejson as json
def rsa_sha1_sign(data, keyfile=None):
if keyfile is None:
key = RSA.load_key(settings.CLOUDFRONT_KEY)
else:
key = RSA.load_key(keyfile)
return key.sign(hashlib.sha1(data).digest(), 'sha1')
def safe_b64encode(data):
safe = ['+-', '=_', '/~']
data = base64.b64encode(data)
for s, r in safe:
data = data.replace(s, r)
return data
def sign_streaming(filename):
resource = os.path.splitext(filename)[0]
expires = getattr(settings, "CLOUDFRONT_EXPIRES_IN", 60*60*3) # 3h
expires += int(time.time())
policy = {"Statement":[{"Resource":resource,
"Condition":{"DateLessThan":{"AWS:EpochTime":expires}}}]}
policy = json.dumps(policy, separators=(',', ':'))
signature = safe_b64encode(rsa_sha1_sign(policy))
return "%s?Expires=%d&Signature=%s&Key-Pair-Id=%s" % (resource, expires,
signature, settings.CLOUDFRONT_KEY_PAIR_ID)
|
Comments