From 7bf7eab616cc2d17941ee715c6885755f1ad3483 Mon Sep 17 00:00:00 2001 From: Chris Dodge Date: Wed, 26 Sep 2012 16:39:02 -0400 Subject: [PATCH] support client-side caching through 'Last-Modified' response headers --- common/djangoapps/contentserver/middleware.py | 22 ++++++++++++++++--- .../xmodule/xmodule/contentstore/__init__.py | 3 ++- .../lib/xmodule/xmodule/contentstore/mongo.py | 3 +-- 3 files changed, 22 insertions(+), 6 deletions(-) diff --git a/common/djangoapps/contentserver/middleware.py b/common/djangoapps/contentserver/middleware.py index 48b760a8d3..f0734dd202 100644 --- a/common/djangoapps/contentserver/middleware.py +++ b/common/djangoapps/contentserver/middleware.py @@ -1,6 +1,7 @@ import logging +import time -from django.http import HttpResponse, Http404 +from django.http import HttpResponse, Http404, HttpResponseNotModified from xmodule.contentstore.django import contentstore from xmodule.contentstore import StaticContent @@ -30,7 +31,22 @@ class StaticContentServer(object): else: logging.debug('cache hit on {0}'.format(content.filename)) + # see if the last-modified at hasn't changed, if not return a 302 (Not Modified) + + logging.debug(request.META) + + # convert over the DB persistent last modified timestamp to a HTTP compatible + # timestamp + last_modified_at_str = content.last_modified_at.strftime("%a, %d-%b-%Y %H:%M:%S GMT") + + # see if the client has cached this content, if so then compare the + # timestamps, if they are the same then just return a 304 (Not Modified) + if 'HTTP_IF_MODIFIED_SINCE' in request.META: + if_modified_since = request.META['HTTP_IF_MODIFIED_SINCE'] + if if_modified_since == last_modified_at_str: + return HttpResponseNotModified() + response = HttpResponse(content.data, content_type=content.content_type) - response['Content-Disposition'] = 'attachment; filename={0}'.format(content.name) - + response['Last-Modified'] = last_modified_at_str + return response diff --git a/common/lib/xmodule/xmodule/contentstore/__init__.py b/common/lib/xmodule/xmodule/contentstore/__init__.py index 08658ea721..e48c2d5303 100644 --- a/common/lib/xmodule/xmodule/contentstore/__init__.py +++ b/common/lib/xmodule/xmodule/contentstore/__init__.py @@ -1,9 +1,10 @@ class StaticContent(object): - def __init__(self, filename, name, content_type, data): + def __init__(self, filename, name, content_type, data, last_modified_at=None): self.filename = filename self.name = name self.content_type = content_type self.data = data + self.last_modified_at = last_modified_at @staticmethod def get_location_tag(): diff --git a/common/lib/xmodule/xmodule/contentstore/mongo.py b/common/lib/xmodule/xmodule/contentstore/mongo.py index eddb162539..12d783366d 100644 --- a/common/lib/xmodule/xmodule/contentstore/mongo.py +++ b/common/lib/xmodule/xmodule/contentstore/mongo.py @@ -23,8 +23,7 @@ class MongoContentStore(object): def find(self, filename): try: with self.fs.get_last_version(filename) as fp: - logging.debug('fetched {0}'.format(fp.name)) - return StaticContent(fp.filename, fp.displayname, fp.content_type, fp.read()) + return StaticContent(fp.filename, fp.displayname, fp.content_type, fp.read(), fp.uploadDate) except NoFile: raise NotFoundError()