Django

Code

Changeset 2476

Show
Ignore:
Timestamp:
03/02/06 22:53:04 (3 years ago)
Author:
adrian
Message:

Fixed #1457 -- Added support for if-modified-since header in django.views.static. Thanks, Shannon -jj Behrens

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • django/trunk/AUTHORS

    r2453 r2476  
    3838    Jiri Barton 
    3939    Ned Batchelder <http://www.nedbatchelder.com/> 
     40    Shannon -jj Behrens <http://jjinux.blogspot.com/> 
    4041    James Bennett 
    4142    Paul Bissex <http://e-scribe.com/> 
  • django/trunk/django/views/static.py

    r2322 r2476  
    33import posixpath 
    44import mimetypes 
     5import re 
     6import rfc822 
     7import stat 
    58from django.core import template_loader 
    69from django.core.exceptions import Http404, ImproperlyConfigured 
    7 from django.utils.httpwrappers import HttpResponse, HttpResponseRedirect 
     10from django.utils.httpwrappers import HttpResponse, HttpResponseRedirect, \ 
     11                                      HttpResponseNotModified 
    812from django.core.template import Template, Context, TemplateDoesNotExist 
    913 
     
    4246        if show_indexes: 
    4347            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): 
    4750        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 
    5161 
    5262DEFAULT_DIRECTORY_INDEX_TEMPLATE = """ 
     
    8696    }) 
    8797    return HttpResponse(t.render(c)) 
     98 
     99def 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