app/django/middleware/http.py
changeset 54 03e267d67478
child 323 ff1a9aa48cfd
equal deleted inserted replaced
53:57b4279d8c4e 54:03e267d67478
       
     1 from django.utils.http import http_date
       
     2 
       
     3 class ConditionalGetMiddleware(object):
       
     4     """
       
     5     Handles conditional GET operations. If the response has a ETag or
       
     6     Last-Modified header, and the request has If-None-Match or
       
     7     If-Modified-Since, the response is replaced by an HttpNotModified.
       
     8 
       
     9     Also sets the Date and Content-Length response-headers.
       
    10     """
       
    11     def process_response(self, request, response):
       
    12         response['Date'] = http_date()
       
    13         if not response.has_header('Content-Length'):
       
    14             response['Content-Length'] = str(len(response.content))
       
    15 
       
    16         if response.has_header('ETag'):
       
    17             if_none_match = request.META.get('HTTP_IF_NONE_MATCH', None)
       
    18             if if_none_match == response['ETag']:
       
    19                 # Setting the status is enough here. The response handling path
       
    20                 # automatically removes content for this status code (in
       
    21                 # http.conditional_content_removal()).
       
    22                 response.status = 304
       
    23 
       
    24         if response.has_header('Last-Modified'):
       
    25             if_modified_since = request.META.get('HTTP_IF_MODIFIED_SINCE', None)
       
    26             if if_modified_since == response['Last-Modified']:
       
    27                 # Setting the status code is enough here (same reasons as
       
    28                 # above).
       
    29                 response.status = 304
       
    30 
       
    31         return response
       
    32 
       
    33 class SetRemoteAddrFromForwardedFor(object):
       
    34     """
       
    35     Middleware that sets REMOTE_ADDR based on HTTP_X_FORWARDED_FOR, if the
       
    36     latter is set. This is useful if you're sitting behind a reverse proxy that
       
    37     causes each request's REMOTE_ADDR to be set to 127.0.0.1.
       
    38 
       
    39     Note that this does NOT validate HTTP_X_FORWARDED_FOR. If you're not behind
       
    40     a reverse proxy that sets HTTP_X_FORWARDED_FOR automatically, do not use
       
    41     this middleware. Anybody can spoof the value of HTTP_X_FORWARDED_FOR, and
       
    42     because this sets REMOTE_ADDR based on HTTP_X_FORWARDED_FOR, that means
       
    43     anybody can "fake" their IP address. Only use this when you can absolutely
       
    44     trust the value of HTTP_X_FORWARDED_FOR.
       
    45     """
       
    46     def process_request(self, request):
       
    47         try:
       
    48             real_ip = request.META['HTTP_X_FORWARDED_FOR']
       
    49         except KeyError:
       
    50             return None
       
    51         else:
       
    52             # HTTP_X_FORWARDED_FOR can be a comma-separated list of IPs. The
       
    53             # client's IP will be the first one.
       
    54             real_ip = real_ip.split(",")[0].strip()
       
    55             request.META['REMOTE_ADDR'] = real_ip