web/lib/django/http/utils.py
changeset 0 0d40e90630ef
equal deleted inserted replaced
-1:000000000000 0:0d40e90630ef
       
     1 """
       
     2 Functions that modify an HTTP request or response in some way.
       
     3 """
       
     4 
       
     5 # This group of functions are run as part of the response handling, after
       
     6 # everything else, including all response middleware. Think of them as
       
     7 # "compulsory response middleware". Be careful about what goes here, because
       
     8 # it's a little fiddly to override this behavior, so they should be truly
       
     9 # universally applicable.
       
    10 
       
    11 def fix_location_header(request, response):
       
    12     """
       
    13     Ensures that we always use an absolute URI in any location header in the
       
    14     response. This is required by RFC 2616, section 14.30.
       
    15 
       
    16     Code constructing response objects is free to insert relative paths, as
       
    17     this function converts them to absolute paths.
       
    18     """
       
    19     if 'Location' in response and request.get_host():
       
    20         response['Location'] = request.build_absolute_uri(response['Location'])
       
    21     return response
       
    22 
       
    23 def conditional_content_removal(request, response):
       
    24     """
       
    25     Removes the content of responses for HEAD requests, 1xx, 204 and 304
       
    26     responses. Ensures compliance with RFC 2616, section 4.3.
       
    27     """
       
    28     if 100 <= response.status_code < 200 or response.status_code in (204, 304):
       
    29        response.content = ''
       
    30        response['Content-Length'] = 0
       
    31     if request.method == 'HEAD':
       
    32         response.content = ''
       
    33     return response
       
    34 
       
    35 def fix_IE_for_attach(request, response):
       
    36     """
       
    37     This function will prevent Django from serving a Content-Disposition header
       
    38     while expecting the browser to cache it (only when the browser is IE). This
       
    39     leads to IE not allowing the client to download.
       
    40     """
       
    41     if 'MSIE' not in request.META.get('HTTP_USER_AGENT', '').upper():
       
    42         return response
       
    43 
       
    44     offending_headers = ('no-cache', 'no-store')
       
    45     if response.has_header('Content-Disposition'):
       
    46         try:
       
    47             del response['Pragma']
       
    48         except KeyError:
       
    49             pass
       
    50         if response.has_header('Cache-Control'):
       
    51             cache_control_values = [value.strip() for value in
       
    52                     response['Cache-Control'].split(',')
       
    53                     if value.strip().lower() not in offending_headers]
       
    54 
       
    55             if not len(cache_control_values):
       
    56                 del response['Cache-Control']
       
    57             else:
       
    58                 response['Cache-Control'] = ', '.join(cache_control_values)
       
    59 
       
    60     return response
       
    61 
       
    62 def fix_IE_for_vary(request, response):
       
    63     """
       
    64     This function will fix the bug reported at
       
    65     http://support.microsoft.com/kb/824847/en-us?spid=8722&sid=global
       
    66     by clearing the Vary header whenever the mime-type is not safe
       
    67     enough for Internet Explorer to handle.  Poor thing.
       
    68     """
       
    69     if 'MSIE' not in request.META.get('HTTP_USER_AGENT', '').upper():
       
    70         return response
       
    71 
       
    72     # These mime-types that are decreed "Vary-safe" for IE:
       
    73     safe_mime_types = ('text/html', 'text/plain', 'text/sgml')
       
    74 
       
    75     # The first part of the Content-Type field will be the MIME type,
       
    76     # everything after ';', such as character-set, can be ignored.
       
    77     if response['Content-Type'].split(';')[0] not in safe_mime_types:
       
    78         try:
       
    79             del response['Vary']
       
    80         except KeyError:
       
    81             pass
       
    82 
       
    83     return response
       
    84