mirror of
https://github.com/Hopiu/django.git
synced 2026-05-18 20:41:06 +00:00
We now have automatic HEAD processing always (previously required ConditionalGetMiddleware), middleware benefits from the Location header rewrite, so they can use relative URLs as well, and responses with response codes 1xx, 204 or 304 will always have their content removed, in accordance with the HTTP spec (so it's much harder to indavertently deliver invalid responses). Based on a patch and diagnosis from regexbot@gmail.com. git-svn-id: http://code.djangoproject.com/svn/django/trunk@6662 bcc190cf-cafb-0310-a4f2-bffc1f526a37
55 lines
2.4 KiB
Python
55 lines
2.4 KiB
Python
from django.utils.http import http_date
|
|
|
|
class ConditionalGetMiddleware(object):
|
|
"""
|
|
Handles conditional GET operations. If the response has a ETag or
|
|
Last-Modified header, and the request has If-None-Match or
|
|
If-Modified-Since, the response is replaced by an HttpNotModified.
|
|
|
|
Also sets the Date and Content-Length response-headers.
|
|
"""
|
|
def process_response(self, request, response):
|
|
response['Date'] = http_date()
|
|
if not response.has_header('Content-Length'):
|
|
response['Content-Length'] = str(len(response.content))
|
|
|
|
if response.has_header('ETag'):
|
|
if_none_match = request.META.get('HTTP_IF_NONE_MATCH', None)
|
|
if if_none_match == response['ETag']:
|
|
# Setting the status is enough here. The response handling path
|
|
# automatically removes content for this status code (in
|
|
# http.conditional_content_removal()).
|
|
response.status = 304
|
|
|
|
if response.has_header('Last-Modified'):
|
|
if_modified_since = request.META.get('HTTP_IF_MODIFIED_SINCE', None)
|
|
if if_modified_since == response['Last-Modified']:
|
|
# Setting the status code is enough here (same reasons as
|
|
# above).
|
|
response.status = 304
|
|
|
|
return response
|
|
|
|
class SetRemoteAddrFromForwardedFor(object):
|
|
"""
|
|
Middleware that sets REMOTE_ADDR based on HTTP_X_FORWARDED_FOR, if the
|
|
latter is set. This is useful if you're sitting behind a reverse proxy that
|
|
causes each request's REMOTE_ADDR to be set to 127.0.0.1.
|
|
|
|
Note that this does NOT validate HTTP_X_FORWARDED_FOR. If you're not behind
|
|
a reverse proxy that sets HTTP_X_FORWARDED_FOR automatically, do not use
|
|
this middleware. Anybody can spoof the value of HTTP_X_FORWARDED_FOR, and
|
|
because this sets REMOTE_ADDR based on HTTP_X_FORWARDED_FOR, that means
|
|
anybody can "fake" their IP address. Only use this when you can absolutely
|
|
trust the value of HTTP_X_FORWARDED_FOR.
|
|
"""
|
|
def process_request(self, request):
|
|
try:
|
|
real_ip = request.META['HTTP_X_FORWARDED_FOR']
|
|
except KeyError:
|
|
return None
|
|
else:
|
|
# HTTP_X_FORWARDED_FOR can be a comma-separated list of IPs. The
|
|
# client's IP will be the first one.
|
|
real_ip = real_ip.split(",")[0].strip()
|
|
request.META['REMOTE_ADDR'] = real_ip
|