summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdrian Holovaty <adrian@holovaty.com>2006-03-03 04:53:04 +0000
committerAdrian Holovaty <adrian@holovaty.com>2006-03-03 04:53:04 +0000
commit5beb39b896d581940ad3681229e87575aa83174d (patch)
treed28b0e93108936d12cf4e37a26a36f377e1ed638
parentcffd184daf070e5a1ce03d77cab55e0adebb90f8 (diff)
Fixed #1457 -- Added support for if-modified-since header in django.views.static. Thanks, Shannon -jj Behrens
git-svn-id: http://code.djangoproject.com/svn/django/trunk@2476 bcc190cf-cafb-0310-a4f2-bffc1f526a37
-rw-r--r--AUTHORS1
-rw-r--r--django/views/static.py54
2 files changed, 48 insertions, 7 deletions
diff --git a/AUTHORS b/AUTHORS
index c983289fe2..1e061703c6 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -37,6 +37,7 @@ answer newbie questions, and generally made Django that much better:
Arthur <avandorp@gmail.com>
Jiri Barton
Ned Batchelder <http://www.nedbatchelder.com/>
+ Shannon -jj Behrens <http://jjinux.blogspot.com/>
James Bennett
Paul Bissex <http://e-scribe.com/>
Simon Blanchard
diff --git a/django/views/static.py b/django/views/static.py
index 536720f5e8..1499dd4847 100644
--- a/django/views/static.py
+++ b/django/views/static.py
@@ -2,9 +2,13 @@ import os
import urllib
import posixpath
import mimetypes
+import re
+import rfc822
+import stat
from django.core import template_loader
from django.core.exceptions import Http404, ImproperlyConfigured
-from django.utils.httpwrappers import HttpResponse, HttpResponseRedirect
+from django.utils.httpwrappers import HttpResponse, HttpResponseRedirect, \
+ HttpResponseNotModified
from django.core.template import Template, Context, TemplateDoesNotExist
def serve(request, path, document_root=None, show_indexes=False):
@@ -41,13 +45,19 @@ def serve(request, path, document_root=None, show_indexes=False):
if os.path.isdir(fullpath):
if show_indexes:
return directory_index(newpath, fullpath)
- else:
- raise Http404, "Directory indexes are not allowed here."
- elif not os.path.exists(fullpath):
+ raise Http404, "Directory indexes are not allowed here."
+ if not os.path.exists(fullpath):
raise Http404, '"%s" does not exist' % fullpath
- else:
- mimetype = mimetypes.guess_type(fullpath)[0]
- return HttpResponse(open(fullpath, 'rb').read(), mimetype=mimetype)
+ # Respect the If-Modified-Since header.
+ statobj = os.stat(fullpath)
+ if not was_modified_since(request.META.get('HTTP_IF_MODIFIED_SINCE'),
+ statobj[stat.ST_MTIME], statobj[stat.ST_SIZE]):
+ return HttpResponseNotModified()
+ mimetype = mimetypes.guess_type(fullpath)[0]
+ contents = open(fullpath, 'rb').read()
+ response = HttpResponse(contents, mimetype=mimetype)
+ response["Last-Modified"] = rfc822.formatdate(statobj[stat.ST_MTIME])
+ return response
DEFAULT_DIRECTORY_INDEX_TEMPLATE = """
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
@@ -85,3 +95,33 @@ def directory_index(path, fullpath):
'file_list' : files,
})
return HttpResponse(t.render(c))
+
+def was_modified_since(header=None, mtime=0, size=0):
+ """
+ Was something modified since the user last downloaded it?
+
+ header
+ This is the value of the If-Modified-Since header. If this is None,
+ I'll just return True.
+
+ mtime
+ This is the modification time of the item we're talking about.
+
+ size
+ This is the size of the item we're talking about.
+ """
+ try:
+ if header is None:
+ raise ValueError
+ matches = re.match(r"^([^;]+)(; length=([0-9]+))?$", header,
+ re.IGNORECASE)
+ header_mtime = rfc822.mktime_tz(rfc822.parsedate_tz(
+ matches.group(1)))
+ header_len = matches.group(3)
+ if header_len and int(header_len) != size:
+ raise ValueError
+ if mtime > header_mtime:
+ raise ValueError
+ except (AttributeError, ValueError):
+ return True
+ return False