Ticket #717: ifmodifiedsince.diff

File ifmodifiedsince.diff, 6.2 KB (added by Julian Bez, 14 years ago)
  • django/middleware/http.py

     
    11from django.core.exceptions import MiddlewareNotUsed
    22from django.utils.http import http_date
     3from email.utils import parsedate
     4import datetime
    35
    46class ConditionalGetMiddleware(object):
    57    """
     
    2426
    2527        if response.has_header('Last-Modified'):
    2628            if_modified_since = request.META.get('HTTP_IF_MODIFIED_SINCE', None)
    27             if if_modified_since == response['Last-Modified']:
    28                 # Setting the status code is enough here (same reasons as
    29                 # above).
    30                 response.status_code = 304
     29            if if_modified_since:
     30                lm = datetime.datetime(*parsedate(response['Last-Modified'])[:6])
     31                ims = datetime.datetime(*parsedate(if_modified_since)[:6])
     32                if lm <= ims:
     33                    # Setting the status code is enough here (same reasons as
     34                    # above).
     35                    response.status_code = 304
    3136
    3237        return response
    3338
  • django/views/decorators/http.py

     
    77except ImportError:
    88    from django.utils.functional import wraps  # Python 2.4 fallback.
    99
     10import datetime
    1011from calendar import timegm
    1112from datetime import timedelta
    12 from email.Utils import formatdate
     13from email.Utils import formatdate, parsedate
    1314
    1415from django.utils.decorators import decorator_from_middleware, available_attrs
    1516from django.utils.http import parse_etags, quote_etag
     
    6970    def decorator(func):
    7071        def inner(request, *args, **kwargs):
    7172            # Get HTTP request headers
    72             if_modified_since = request.META.get("HTTP_IF_MODIFIED_SINCE")
     73            if_modified_since = request.META.get('HTTP_IF_MODIFIED_SINCE', None)
     74            if if_modified_since:
     75                try:
     76                    if_modified_since = datetime.datetime(*parsedate(if_modified_since)[:6])
     77                except ValueError:
     78                    if_modified_since = None
    7379            if_none_match = request.META.get("HTTP_IF_NONE_MATCH")
    7480            if_match = request.META.get("HTTP_IF_MATCH")
    7581            if if_none_match or if_match:
     
    8692                    if_match = None
    8793
    8894            # Compute values (if any) for the requested resource.
     95            res_etag = None
    8996            if etag_func:
    9097                res_etag = etag_func(request, *args, **kwargs)
    91             else:
    92                 res_etag = None
     98            res_last_modified = None
    9399            if last_modified_func:
    94100                dt = last_modified_func(request, *args, **kwargs)
    95101                if dt:
    96                     res_last_modified = formatdate(timegm(dt.utctimetuple()))[:26] + 'GMT'
    97                 else:
    98                     res_last_modified = None
    99             else:
    100                 res_last_modified = None
     102                    res_last_modified = dt
    101103
    102104            response = None
    103105            if not ((if_match and (if_modified_since or if_none_match)) or
     
    107109                if ((if_none_match and (res_etag in etags or
    108110                        "*" in etags and res_etag)) and
    109111                        (not if_modified_since or
    110                             res_last_modified == if_modified_since)):
     112                            (if_modified_since and
     113                            res_last_modified <= if_modified_since))):
    111114                    if request.method in ("GET", "HEAD"):
    112115                        response = HttpResponseNotModified()
    113116                    else:
     
    117120                    response = HttpResponse(status=412)
    118121                elif (not if_none_match and if_modified_since and
    119122                        request.method == "GET" and
    120                         res_last_modified == if_modified_since):
     123                        res_last_modified and
     124                        res_last_modified <= if_modified_since):
    121125                    response = HttpResponseNotModified()
    122126
    123127            if response is None:
     
    125129
    126130            # Set relevant headers on the response if they don't already exist.
    127131            if res_last_modified and not response.has_header('Last-Modified'):
    128                 response['Last-Modified'] = res_last_modified
     132                response['Last-Modified'] = formatdate(timegm(res_last_modified.utctimetuple()))[:26] + 'GMT'
    129133            if res_etag and not response.has_header('ETag'):
    130134                response['ETag'] = quote_etag(res_etag)
    131135
  • tests/regressiontests/conditional_processing/models.py

     
    88FULL_RESPONSE = 'Test conditional get response'
    99LAST_MODIFIED = datetime(2007, 10, 21, 23, 21, 47)
    1010LAST_MODIFIED_STR = 'Sun, 21 Oct 2007 23:21:47 GMT'
     11LAST_MODIFIED_NEWER_STR = 'Mon, 18 Oct 2010 16:56:23 GMT'
     12LAST_MODIFIED_INVALID_STR = 'Mon, 32 Oct 2010 16:56:23 GMT'
    1113EXPIRED_LAST_MODIFIED_STR = 'Sat, 20 Oct 2007 23:21:47 GMT'
    1214ETAG = 'b4246ffc4f62314ca13147c9d4f76974'
    1315EXPIRED_ETAG = '7fae4cd4b0f81e7d2914700043aa8ed6'
     
    3335        self.client.defaults['HTTP_IF_MODIFIED_SINCE'] = LAST_MODIFIED_STR
    3436        response = self.client.get('/condition/')
    3537        self.assertNotModified(response)
     38        self.client.defaults['HTTP_IF_MODIFIED_SINCE'] = LAST_MODIFIED_NEWER_STR
     39        response = self.client.get('/condition/')
     40        self.assertNotModified(response)
     41        self.client.defaults['HTTP_IF_MODIFIED_SINCE'] = LAST_MODIFIED_INVALID_STR
     42        response = self.client.get('/condition/')
     43        self.assertFullResponse(response)
    3644        self.client.defaults['HTTP_IF_MODIFIED_SINCE'] = EXPIRED_LAST_MODIFIED_STR
    3745        response = self.client.get('/condition/')
    3846        self.assertFullResponse(response)
Back to Top