Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Fixed #7603 -- Added a 'scheme' property to the HttpRequest object

`HttpRequest.scheme` is `https` if `settings.SECURE_PROXY_SSL_HEADER` is
appropriately set and falls back to `HttpRequest._get_scheme()` (a hook
for subclasses to implement) otherwise.

`WSGIRequest._get_scheme()` makes use of the `wsgi.url_scheme` WSGI
environ variable to determine the request scheme.

`HttpRequest.is_secure()` simply checks if `HttpRequest.scheme` is
`https`.

This provides a way to check the current scheme in templates, for example.
It also allows us to deal with other schemes.

Thanks nslater for the suggestion.
  • Loading branch information...
commit c7634cd7fe7dc09338fcec0ca48d816a29d791b0 1 parent 9bfe661
Unai Zalakain authored October 08, 2013 timgraham committed October 15, 2013
2  django/contrib/admindocs/views.py
@@ -38,7 +38,7 @@ def bookmarklets(request):
38 38
     admin_root = urlresolvers.reverse('admin:index')
39 39
     return render_to_response('admin_doc/bookmarklets.html', {
40 40
         'root_path': admin_root,
41  
-        'admin_url': "%s://%s%s" % ('https' if request.is_secure() else 'http', request.get_host(), admin_root),
  41
+        'admin_url': "%s://%s%s" % (request.scheme, request.get_host(), admin_root),
42 42
     }, context_instance=RequestContext(request))
43 43
 
44 44
 @staff_member_required
2  django/contrib/contenttypes/views.py
@@ -75,7 +75,7 @@ def shortcut(request, content_type_id, object_id):
75 75
     # If all that malarkey found an object domain, use it. Otherwise, fall back
76 76
     # to whatever get_absolute_url() returned.
77 77
     if object_domain is not None:
78  
-        protocol = 'https' if request.is_secure() else 'http'
  78
+        protocol = request.scheme
79 79
         return http.HttpResponseRedirect('%s://%s%s'
80 80
                                          % (protocol, object_domain, absurl))
81 81
     else:
2  django/contrib/gis/sitemaps/views.py
@@ -21,7 +21,7 @@ def index(request, sitemaps):
21 21
     """
22 22
     current_site = get_current_site(request)
23 23
     sites = []
24  
-    protocol = 'https' if request.is_secure() else 'http'
  24
+    protocol = request.scheme
25 25
     for section, site in sitemaps.items():
26 26
         if callable(site):
27 27
             pages = site().paginator.num_pages
4  django/contrib/sitemaps/views.py
@@ -22,7 +22,7 @@ def index(request, sitemaps,
22 22
           template_name='sitemap_index.xml', content_type='application/xml',
23 23
           sitemap_url_name='django.contrib.sitemaps.views.sitemap'):
24 24
 
25  
-    req_protocol = 'https' if request.is_secure() else 'http'
  25
+    req_protocol = request.scheme
26 26
     req_site = get_current_site(request)
27 27
 
28 28
     sites = []
@@ -44,7 +44,7 @@ def index(request, sitemaps,
44 44
 def sitemap(request, sitemaps, section=None,
45 45
             template_name='sitemap.xml', content_type='application/xml'):
46 46
 
47  
-    req_protocol = 'https' if request.is_secure() else 'http'
  47
+    req_protocol = request.scheme
48 48
     req_site = get_current_site(request)
49 49
 
50 50
     if section is not None:
4  django/core/handlers/wsgi.py
@@ -110,8 +110,8 @@ def __init__(self, environ):
110 110
         self._read_started = False
111 111
         self.resolver_match = None
112 112
 
113  
-    def _is_secure(self):
114  
-        return self.environ.get('wsgi.url_scheme') == 'https'
  113
+    def _get_scheme(self):
  114
+        return self.environ.get('wsgi.url_scheme')
115 115
 
116 116
     def _parse_content_type(self, ctype):
117 117
         """
19  django/http/request.py
@@ -129,15 +129,16 @@ def build_absolute_uri(self, location=None):
129 129
         if not location:
130 130
             location = self.get_full_path()
131 131
         if not absolute_http_url_re.match(location):
132  
-            current_uri = '%s://%s%s' % ('https' if self.is_secure() else 'http',
  132
+            current_uri = '%s://%s%s' % (self.scheme,
133 133
                                          self.get_host(), self.path)
134 134
             location = urljoin(current_uri, location)
135 135
         return iri_to_uri(location)
136 136
 
137  
-    def _is_secure(self):
138  
-        return os.environ.get("HTTPS") == "on"
  137
+    def _get_scheme(self):
  138
+        return 'https' if os.environ.get("HTTPS") == "on" else 'http'
139 139
 
140  
-    def is_secure(self):
  140
+    @property
  141
+    def scheme(self):
141 142
         # First, check the SECURE_PROXY_SSL_HEADER setting.
142 143
         if settings.SECURE_PROXY_SSL_HEADER:
143 144
             try:
@@ -145,11 +146,13 @@ def is_secure(self):
145 146
             except ValueError:
146 147
                 raise ImproperlyConfigured('The SECURE_PROXY_SSL_HEADER setting must be a tuple containing two values.')
147 148
             if self.META.get(header, None) == value:
148  
-                return True
149  
-
150  
-        # Failing that, fall back to _is_secure(), which is a hook for
  149
+                return 'https'
  150
+        # Failing that, fall back to _get_scheme(), which is a hook for
151 151
         # subclasses to implement.
152  
-        return self._is_secure()
  152
+        return self._get_scheme()
  153
+
  154
+    def is_secure(self):
  155
+        return self.scheme == 'https'
153 156
 
154 157
     def is_ajax(self):
155 158
         return self.META.get('HTTP_X_REQUESTED_WITH') == 'XMLHttpRequest'
2  django/middleware/common.py
@@ -85,7 +85,7 @@ def process_request(self, request):
85 85
             return
86 86
         if new_url[0]:
87 87
             newurl = "%s://%s%s" % (
88  
-                'https' if request.is_secure() else 'http',
  88
+                request.scheme,
89 89
                 new_url[0], urlquote(new_url[1]))
90 90
         else:
91 91
             newurl = urlquote(new_url[1])
4  django/middleware/locale.py
@@ -51,8 +51,8 @@ def process_response(self, request, response):
51 51
 
52 52
             if path_valid:
53 53
                 language_url = "%s://%s/%s%s" % (
54  
-                    'https' if request.is_secure() else 'http',
55  
-                    request.get_host(), language, request.get_full_path())
  54
+                    request.scheme, request.get_host(), language,
  55
+                    request.get_full_path())
56 56
                 return self.response_redirect_class(language_url)
57 57
 
58 58
         # Store language back into session if it is not present
7  docs/ref/request-response.txt
@@ -32,6 +32,13 @@ Attributes
32 32
 All attributes should be considered read-only, unless stated otherwise below.
33 33
 ``session`` is a notable exception.
34 34
 
  35
+.. attribute:: HttpRequest.scheme
  36
+
  37
+   .. versionadded:: 1.7
  38
+
  39
+   A string representing the scheme of the request (``http`` or ``https`` 
  40
+   usually).
  41
+
35 42
 .. attribute:: HttpRequest.body
36 43
 
37 44
     The raw HTTP request body as a byte string. This is useful for processing
6  docs/releases/1.7.txt
@@ -386,6 +386,12 @@ Templates
386 386
   <naive_vs_aware_datetimes>` ``datetime`` instances performing the expected
387 387
   rendering.
388 388
 
  389
+Requests
  390
+^^^^^^^^
  391
+
  392
+* The new :attr:`HttpRequest.scheme <django.http.HttpRequest.scheme>` attribute
  393
+  specifies the scheme of the request (``http`` or ``https`` normally).
  394
+
389 395
 Tests
390 396
 ^^^^^
391 397
 

0 notes on commit c7634cd

Please sign in to comment.
Something went wrong with that request. Please try again.