Django Friends Meetup, 2015-02-05


A short tale about MEDIA_URLs

... or testing with settings override


Florian Demmer (@fdemmer)
www.floriandemmer.com

backstory

 
web frontend & api


CDN_URL = 'https://da2s5d7fli.cloudfront.net'
MEDIA_URL = CDN_URL + MEDIA_URL

backstory


http://en.wikipedia.org/wiki/POODLE

backstory


CVE-2014-3566 Advisory


We have disabled SSLv3 for all customers
who use SSL with the default CloudFront
domain name (*.cloudfront.net).


http://aws.amazon.com/security/security-bulletins/CVE-2014-3566-advisory/

backstory




smart, but only SSL3

backstory



solution


don't use HTTPS for SmartTV API


... but still use it on web frontend.


... and also better use protocol relative URLs.
(but not in API)


CDN_URL = '//da2s5d7fli.cloudfront.net'

solution


def rewrite_protocol(url, replacement=None):
replacement = replacement or settings.STV_API_MEDIA_PROTOCOL
if replacement:
parts = urlparse.urlsplit(url)
# only rewrite protocol if host is available
if parts[1]:
return urlparse.urlunsplit((replacement,) + parts[1:])
return url


... now, does this really work?

testing


class APITest(testcases.TestCase):
  def
test_http_location(self):
CDN_URL = 'http://cloudfront.com'
MEDIA_URL = '/media/'
with self.settings(MEDIA_URL=CDN_URL+MEDIA_URL):
...

... does not work.

... looks like settings override has no effect!

the settings override


happens at runtime


"ImageFields" use storage to generate URLs

should affect the "DefaultStorage" all "ImageFields" use


but "DefaultStorage" loads setting at init


how about a signal on setting change?

the signal

https://code.djangoproject.com/ticket/17744

@receiver(setting_changed)
def file_storage_changed(**kwargs):
if kwargs['setting'] in ('MEDIA_ROOT', 'DEFAULT_FILE_STORAGE'):
from django.core.files.storage import default_storage
default_storage._wrapped = empty

... no trigger on MEDIA_URL change.


and other storages?

eg. easy_thumbnails


quick solution in test class:

def _nuke_storage_instances(self):
# reset image storages to reload settings
from django.core.files.storage import default_storage
default_storage._wrapped = empty

from easy_thumbnails.storage import thumbnail_default_storage
thumbnail_default_storage._wrapped = empty

clean solution:
submit issue to Django and easy_thumbnails, write patch, explain reasoning, ...

all the things


https://code.djangoproject.com/ticket/17744

https://github.com/django/django/commit/a24ffa52d02998f5082fbc5a461ccdc8004db4a6

self.url = https://slides.com/fdemmer
https://www.floriandemmer.com
Made with Slides.com