## 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)