def inner(request, *args, **kwargs): # Get HTTP request headers if_modified_since = request.META.get("HTTP_IF_MODIFIED_SINCE") if_none_match = request.META.get("HTTP_IF_NONE_MATCH") if_match = request.META.get("HTTP_IF_MATCH") if if_none_match or if_match: # There can be more than one ETag in the request, so we # consider the list of values. etags = parse_etags(if_none_match or if_match) # Compute values (if any) for the requested resource. if etag_func: res_etag = etag_func(request, *args, **kwargs) else: res_etag = None if last_modified_func: dt = last_modified_func(request, *args, **kwargs) if dt: res_last_modified = formatdate(timegm(dt.utctimetuple()))[:26] + 'GMT' else: res_last_modified = None else: res_last_modified = None response = None if not ((if_match and (if_modified_since or if_none_match)) or (if_match and if_none_match)): # We only get here if no undefined combinations of headers are # specified. if ((if_none_match and (res_etag in etags or "*" in etags and res_etag)) and (not if_modified_since or res_last_modified == if_modified_since)): if request.method in ("GET", "HEAD"): response = HttpResponseNotModified() else: response = HttpResponse(status=412) elif if_match and ((not res_etag and "*" in etags) or (res_etag and res_etag not in etags)): response = HttpResponse(status=412) elif (not if_none_match and if_modified_since and request.method == "GET" and res_last_modified == if_modified_since): response = HttpResponseNotModified() if response is None: response = func(request, *args, **kwargs) # Set relevant headers on the response if they don't already exist. if res_last_modified and not response.has_header('Last-Modified'): response['Last-Modified'] = res_last_modified if res_etag and not response.has_header('ETag'): response['ETag'] = quote_etag(res_etag) return response
def inner(request, *args, **kwargs): # Get HTTP request headers if_modified_since = request.META.get("HTTP_IF_MODIFIED_SINCE") if_none_match = request.META.get("HTTP_IF_NONE_MATCH") if_match = request.META.get("HTTP_IF_MATCH") if if_none_match or if_match: # There can be more than one ETag in the request, so we # consider the list of values. try: etags = parse_etags(if_none_match or if_match) except ValueError: # In case of invalid etag ignore all ETag headers. # Apparently Opera sends invalidly quoted headers at times # (we should be returning a 400 response, but that's a # little extreme) -- this is Django bug #10681. if_none_match = None if_match = None # Compute values (if any) for the requested resource. if etag_func: res_etag = etag_func(request, *args, **kwargs) else: res_etag = None if last_modified_func: dt = last_modified_func(request, *args, **kwargs) if dt: res_last_modified = formatdate(timegm( dt.utctimetuple()))[:26] + 'GMT' else: res_last_modified = None else: res_last_modified = None response = None if not ((if_match and (if_modified_since or if_none_match)) or (if_match and if_none_match)): # We only get here if no undefined combinations of headers are # specified. if ((if_none_match and (res_etag in etags or "*" in etags and res_etag)) and (not if_modified_since or res_last_modified == if_modified_since)): if request.method in ("GET", "HEAD"): response = HttpResponseNotModified() else: logger.warning('Precondition Failed: %s' % request.path, extra={ 'status_code': 412, 'request': request }) response = HttpResponse(status=412) elif if_match and ((not res_etag and "*" in etags) or (res_etag and res_etag not in etags)): logger.warning('Precondition Failed: %s' % request.path, extra={ 'status_code': 412, 'request': request }) response = HttpResponse(status=412) elif (not if_none_match and if_modified_since and request.method == "GET" and res_last_modified == if_modified_since): response = HttpResponseNotModified() if response is None: response = func(request, *args, **kwargs) # Set relevant headers on the response if they don't already exist. if res_last_modified and not response.has_header('Last-Modified'): response['Last-Modified'] = res_last_modified if res_etag and not response.has_header('ETag'): response['ETag'] = quote_etag(res_etag) return response
def inner(request, *args, **kwargs): # Get HTTP request headers if_modified_since = request.META.get("HTTP_IF_MODIFIED_SINCE") if if_modified_since: if_modified_since = parse_http_date_safe(if_modified_since) if_none_match = request.META.get("HTTP_IF_NONE_MATCH") if_match = request.META.get("HTTP_IF_MATCH") if if_none_match or if_match: # There can be more than one ETag in the request, so we # consider the list of values. try: etags = parse_etags(if_none_match or if_match) except ValueError: # In case of invalid etag ignore all ETag headers. # Apparently Opera sends invalidly quoted headers at times # (we should be returning a 400 response, but that's a # little extreme) -- this is Django bug #10681. if_none_match = None if_match = None # Compute values (if any) for the requested resource. if etag_func: res_etag = etag_func(request, *args, **kwargs) else: res_etag = None if last_modified_func: dt = last_modified_func(request, *args, **kwargs) if dt: res_last_modified = timegm(dt.utctimetuple()) else: res_last_modified = None else: res_last_modified = None response = None if not ((if_match and (if_modified_since or if_none_match)) or (if_match and if_none_match)): # We only get here if no undefined combinations of headers are # specified. if ((if_none_match and (res_etag in etags or "*" in etags and res_etag)) and (not if_modified_since or (res_last_modified and if_modified_since and res_last_modified <= if_modified_since))): if request.method in ("GET", "HEAD"): response = HttpResponseNotModified() else: logger.warning('Precondition Failed: %s' % request.path, extra={ 'status_code': 412, 'request': request } ) response = HttpResponse(status=412) elif if_match and ((not res_etag and "*" in etags) or (res_etag and res_etag not in etags)): logger.warning('Precondition Failed: %s' % request.path, extra={ 'status_code': 412, 'request': request } ) response = HttpResponse(status=412) elif (not if_none_match and request.method == "GET" and res_last_modified and if_modified_since and res_last_modified <= if_modified_since): response = HttpResponseNotModified() if response is None: response = func(request, *args, **kwargs) # Set relevant headers on the response if they don't already exist. if res_last_modified and not response.has_header('Last-Modified'): response['Last-Modified'] = http_date(res_last_modified) if res_etag and not response.has_header('ETag'): response['ETag'] = quote_etag(res_etag) return response
def inner(request, *args, **kwargs): # Get HTTP request headers if_modified_since = request.META.get("HTTP_IF_MODIFIED_SINCE") if if_modified_since: if_modified_since = parse_http_date_safe(if_modified_since) if_unmodified_since = request.META.get("HTTP_IF_UNMODIFIED_SINCE") if if_unmodified_since: if_unmodified_since = parse_http_date_safe(if_unmodified_since) if_none_match = request.META.get("HTTP_IF_NONE_MATCH") if_match = request.META.get("HTTP_IF_MATCH") etags = [] if if_none_match or if_match: # There can be more than one ETag in the request, so we # consider the list of values. try: etags = parse_etags(if_none_match or if_match) except ValueError: # In case of invalid etag ignore all ETag headers. # Apparently Opera sends invalidly quoted headers at times # (we should be returning a 400 response, but that's a # little extreme) -- this is Django bug #10681. if_none_match = None if_match = None # Compute values (if any) for the requested resource. def get_last_modified(): if last_modified_func: dt = last_modified_func(request, *args, **kwargs) if dt: return timegm(dt.utctimetuple()) res_etag = etag_func(request, *args, ** kwargs) if etag_func else None res_last_modified = get_last_modified() response = None if not ((if_match and if_modified_since) or (if_none_match and if_unmodified_since) or (if_modified_since and if_unmodified_since) or (if_match and if_none_match)): # We only get here if no undefined combinations of headers are # specified. if ((if_none_match and (res_etag in etags or "*" in etags and res_etag)) and (not if_modified_since or (res_last_modified and if_modified_since and res_last_modified <= if_modified_since))): if request.method in ("GET", "HEAD"): response = HttpResponseNotModified() else: response = _precondition_failed(request) elif (if_match and ((not res_etag and "*" in etags) or (res_etag and res_etag not in etags) or (res_last_modified and if_unmodified_since and res_last_modified > if_unmodified_since))): response = _precondition_failed(request) elif (not if_none_match and request.method in ("GET", "HEAD") and res_last_modified and if_modified_since and res_last_modified <= if_modified_since): response = HttpResponseNotModified() elif (not if_match and res_last_modified and if_unmodified_since and res_last_modified > if_unmodified_since): response = _precondition_failed(request) if response is None: response = func(request, *args, **kwargs) # Set relevant headers on the response if they don't already exist. if res_last_modified and not response.has_header('Last-Modified'): response['Last-Modified'] = http_date(res_last_modified) if res_etag and not response.has_header('ETag'): response['ETag'] = quote_etag(res_etag) return response