Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

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
Adrian Holovaty authored March 03, 2006
1  AUTHORS
@@ -37,6 +37,7 @@ answer newbie questions, and generally made Django that much better:
37 37
     Arthur <avandorp@gmail.com>
38 38
     Jiri Barton
39 39
     Ned Batchelder <http://www.nedbatchelder.com/>
  40
+    Shannon -jj Behrens <http://jjinux.blogspot.com/>
40 41
     James Bennett
41 42
     Paul Bissex <http://e-scribe.com/>
42 43
     Simon Blanchard
54  django/views/static.py
@@ -2,9 +2,13 @@
2 2
 import urllib
3 3
 import posixpath
4 4
 import mimetypes
  5
+import re
  6
+import rfc822
  7
+import stat
5 8
 from django.core import template_loader
6 9
 from django.core.exceptions import Http404, ImproperlyConfigured
7  
-from django.utils.httpwrappers import HttpResponse, HttpResponseRedirect
  10
+from django.utils.httpwrappers import HttpResponse, HttpResponseRedirect, \
  11
+                                      HttpResponseNotModified
8 12
 from django.core.template import Template, Context, TemplateDoesNotExist
9 13
 
10 14
 def serve(request, path, document_root=None, show_indexes=False):
@@ -41,13 +45,19 @@ def serve(request, path, document_root=None, show_indexes=False):
41 45
     if os.path.isdir(fullpath):
42 46
         if show_indexes:
43 47
             return directory_index(newpath, fullpath)
44  
-        else:
45  
-            raise Http404, "Directory indexes are not allowed here."
46  
-    elif not os.path.exists(fullpath):
  48
+        raise Http404, "Directory indexes are not allowed here."
  49
+    if not os.path.exists(fullpath):
47 50
         raise Http404, '"%s" does not exist' % fullpath
48  
-    else:
49  
-        mimetype = mimetypes.guess_type(fullpath)[0]
50  
-        return HttpResponse(open(fullpath, 'rb').read(), mimetype=mimetype)
  51
+    # Respect the If-Modified-Since header.
  52
+    statobj = os.stat(fullpath)
  53
+    if not was_modified_since(request.META.get('HTTP_IF_MODIFIED_SINCE'),
  54
+                              statobj[stat.ST_MTIME], statobj[stat.ST_SIZE]):
  55
+        return HttpResponseNotModified()
  56
+    mimetype = mimetypes.guess_type(fullpath)[0]
  57
+    contents = open(fullpath, 'rb').read()
  58
+    response = HttpResponse(contents, mimetype=mimetype)
  59
+    response["Last-Modified"] = rfc822.formatdate(statobj[stat.ST_MTIME])
  60
+    return response
51 61
 
52 62
 DEFAULT_DIRECTORY_INDEX_TEMPLATE = """
53 63
 <!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):
85 95
         'file_list' : files,
86 96
     })
87 97
     return HttpResponse(t.render(c))
  98
+
  99
+def was_modified_since(header=None, mtime=0, size=0):
  100
+    """
  101
+    Was something modified since the user last downloaded it?
  102
+
  103
+    header
  104
+      This is the value of the If-Modified-Since header.  If this is None,
  105
+      I'll just return True.
  106
+
  107
+    mtime
  108
+      This is the modification time of the item we're talking about.
  109
+
  110
+    size
  111
+      This is the size of the item we're talking about.
  112
+    """
  113
+    try:
  114
+        if header is None:
  115
+            raise ValueError
  116
+        matches = re.match(r"^([^;]+)(; length=([0-9]+))?$", header,
  117
+                           re.IGNORECASE)
  118
+        header_mtime = rfc822.mktime_tz(rfc822.parsedate_tz(
  119
+            matches.group(1)))
  120
+        header_len = matches.group(3)
  121
+        if header_len and int(header_len) != size:
  122
+            raise ValueError
  123
+        if mtime > header_mtime:
  124
+            raise ValueError
  125
+    except (AttributeError, ValueError):
  126
+        return True
  127
+    return False

0 notes on commit 5beb39b

Please sign in to comment.
Something went wrong with that request. Please try again.