From e9a236d86c82133ab1959e4ea4760ebe6f73bd8e Mon Sep 17 00:00:00 2001 From: Jacob Kaplan-Moss Date: Fri, 21 Jul 2006 16:20:22 +0000 Subject: [PATCH] Fixed #2092: added a "is_secure()" method to HttpRequest which correctly handles the subtleties of mod_python's interaction with os.environ. This one's been bugging me for about a *year*, so many many thanks to k.shaposhnikov@gmail.com for figuring it out, and Tim Shaffer for pointing out this ticket. git-svn-id: http://code.djangoproject.com/svn/django/trunk@3410 bcc190cf-cafb-0310-a4f2-bffc1f526a37 --- django/contrib/admin/views/doc.py | 2 +- django/core/handlers/modpython.py | 3 +++ django/core/handlers/wsgi.py | 5 ++++- django/http/__init__.py | 4 ++++ django/middleware/common.py | 4 ++-- django/views/debug.py | 4 ++-- docs/request_response.txt | 22 +++++++++++++--------- 7 files changed, 29 insertions(+), 15 deletions(-) diff --git a/django/contrib/admin/views/doc.py b/django/contrib/admin/views/doc.py index 5aa143e1fd..68799fcc17 100644 --- a/django/contrib/admin/views/doc.py +++ b/django/contrib/admin/views/doc.py @@ -28,7 +28,7 @@ def bookmarklets(request): # Hack! This couples this view to the URL it lives at. admin_root = request.path[:-len('doc/bookmarklets/')] return render_to_response('admin_doc/bookmarklets.html', { - 'admin_url': "%s://%s%s" % (os.environ.get('HTTPS') == 'on' and 'https' or 'http', get_host(request), admin_root), + 'admin_url': "%s://%s%s" % (request.is_secure() and 'https' or 'http', get_host(request), admin_root), }, context_instance=RequestContext(request)) bookmarklets = staff_member_required(bookmarklets) diff --git a/django/core/handlers/modpython.py b/django/core/handlers/modpython.py index 5a20ce9f67..8da8ca41d1 100644 --- a/django/core/handlers/modpython.py +++ b/django/core/handlers/modpython.py @@ -23,6 +23,9 @@ class ModPythonRequest(http.HttpRequest): def get_full_path(self): return '%s%s' % (self.path, self._req.args and ('?' + self._req.args) or '') + def is_secure(self): + return self._req.subprocess_env.has_key('HTTPS') and self._req.subprocess_env['HTTPS'] == 'on' + def _load_post_and_files(self): "Populates self._post and self._files" if self._req.headers_in.has_key('content-type') and self._req.headers_in['content-type'].startswith('multipart'): diff --git a/django/core/handlers/wsgi.py b/django/core/handlers/wsgi.py index 2f0d4f78b4..c53e428f85 100644 --- a/django/core/handlers/wsgi.py +++ b/django/core/handlers/wsgi.py @@ -54,7 +54,7 @@ class WSGIRequest(http.HttpRequest): def __init__(self, environ): self.environ = environ self.path = environ['PATH_INFO'] - self.META = environ + self.META = environ self.method = environ['REQUEST_METHOD'].upper() def __repr__(self): @@ -66,6 +66,9 @@ class WSGIRequest(http.HttpRequest): def get_full_path(self): return '%s%s' % (self.path, self.environ.get('QUERY_STRING', '') and ('?' + self.environ.get('QUERY_STRING', '')) or '') + def is_secure(self): + return self.environ.has_key('HTTPS') and self.environ['HTTPS'] == 'on' + def _load_post_and_files(self): # Populates self._post and self._files if self.method == 'POST': diff --git a/django/http/__init__.py b/django/http/__init__.py index 8fb4b293fc..06f6a106ee 100644 --- a/django/http/__init__.py +++ b/django/http/__init__.py @@ -1,3 +1,4 @@ +import os from Cookie import SimpleCookie from pprint import pformat from urllib import urlencode, quote @@ -37,6 +38,9 @@ class HttpRequest(object): def get_full_path(self): return '' + + def is_secure(self): + return os.environ.get("HTTPS") == "on" def parse_file_upload(header_dict, post_data): "Returns a tuple of (POST MultiValueDict, FILES MultiValueDict)" diff --git a/django/middleware/common.py b/django/middleware/common.py index a42c54751d..d63b71fed7 100644 --- a/django/middleware/common.py +++ b/django/middleware/common.py @@ -1,7 +1,7 @@ from django.conf import settings from django import http from django.core.mail import mail_managers -import md5, os +import md5 class CommonMiddleware(object): """ @@ -44,7 +44,7 @@ class CommonMiddleware(object): if new_url != old_url: # Redirect if new_url[0]: - newurl = "%s://%s%s" % (os.environ.get('HTTPS') == 'on' and 'https' or 'http', new_url[0], new_url[1]) + newurl = "%s://%s%s" % (request.is_secure() and 'https' or 'http', new_url[0], new_url[1]) else: newurl = new_url[1] if request.GET: diff --git a/django/views/debug.py b/django/views/debug.py index 6cbbde987b..ffcb284a86 100644 --- a/django/views/debug.py +++ b/django/views/debug.py @@ -124,7 +124,7 @@ def technical_500_response(request, exc_type, exc_value, tb): 'frames': frames, 'lastframe': frames[-1], 'request': request, - 'request_protocol': os.environ.get("HTTPS") == "on" and "https" or "http", + 'request_protocol': request.is_secure() and "https" or "http", 'settings': get_safe_settings(), 'template_info': template_info, 'template_does_not_exist': template_does_not_exist, @@ -149,7 +149,7 @@ def technical_404_response(request, exception): 'urlpatterns': tried, 'reason': str(exception), 'request': request, - 'request_protocol': os.environ.get("HTTPS") == "on" and "https" or "http", + 'request_protocol': request.is_secure() and "https" or "http", 'settings': get_safe_settings(), }) return HttpResponseNotFound(t.render(c), mimetype='text/html') diff --git a/docs/request_response.txt b/docs/request_response.txt index df95bc77b7..7480a6d3bb 100644 --- a/docs/request_response.txt +++ b/docs/request_response.txt @@ -134,21 +134,25 @@ Methods ------- ``__getitem__(key)`` - Returns the GET/POST value for the given key, checking POST first, then - GET. Raises ``KeyError`` if the key doesn't exist. + Returns the GET/POST value for the given key, checking POST first, then + GET. Raises ``KeyError`` if the key doesn't exist. - This lets you use dictionary-accessing syntax on an ``HttpRequest`` - instance. Example: ``request["foo"]`` would return ``True`` if either - ``request.POST`` or ``request.GET`` had a ``"foo"`` key. + This lets you use dictionary-accessing syntax on an ``HttpRequest`` + instance. Example: ``request["foo"]`` would return ``True`` if either + ``request.POST`` or ``request.GET`` had a ``"foo"`` key. ``has_key()`` - Returns ``True`` or ``False``, designating whether ``request.GET`` or - ``request.POST`` has the given key. + Returns ``True`` or ``False``, designating whether ``request.GET`` or + ``request.POST`` has the given key. ``get_full_path()`` - Returns the ``path``, plus an appended query string, if applicable. + Returns the ``path``, plus an appended query string, if applicable. - Example: ``"/music/bands/the_beatles/?print=true"`` + Example: ``"/music/bands/the_beatles/?print=true"`` + +``is_secure()`` + Returns ``True`` if the request is secure; that is, if it was made with + HTTPS. QueryDict objects -----------------