Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Fixed #1457 -- Added support for if-modified-since header in django.v…

…iews.static. Thanks, Shannon -jj Behrens

git-svn-id: http://code.djangoproject.com/svn/django/trunk@2476 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information...
commit 5beb39b896d581940ad3681229e87575aa83174d 1 parent cffd184
@adrianholovaty adrianholovaty authored
Showing with 48 additions and 7 deletions.
  1. +1 −0  AUTHORS
  2. +47 −7 django/views/static.py
View
1  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
View
54 django/views/static.py
@@ -2,9 +2,13 @@
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
Please sign in to comment.
Something went wrong with that request. Please try again.