diff options
| author | Unai Zalakain <unai@gisa-elkartea.org> | 2013-11-04 00:34:11 +0100 |
|---|---|---|
| committer | Tim Graham <timograham@gmail.com> | 2014-06-07 08:59:02 -0400 |
| commit | 11284a63d48c84f1d60b5686d55cf8a9f8d64422 (patch) | |
| tree | 6c16ab34fae64bbdc37ac7d5f990b979598b7a17 /django/http/request.py | |
| parent | 9ed4a8c6b1a552a03fd27b77f1b742e3f9c66bde (diff) | |
Fixed #18314 -- Corrected request.build_absolute_uri() handling of paths starting with //
``HttpRequest.build_absolute_uri()`` now correctly handles paths starting with ``//``.
``WSGIRequest`` now doesn't remove all the leading slashes either,
because ``http://test/server`` and http://test//server`` aren't the same thing
(RFC2396).
Thanks to SmileyChris for the initial patch.
Diffstat (limited to 'django/http/request.py')
| -rw-r--r-- | django/http/request.py | 27 |
1 files changed, 19 insertions, 8 deletions
diff --git a/django/http/request.py b/django/http/request.py index ded4744a87..84457c5300 100644 --- a/django/http/request.py +++ b/django/http/request.py @@ -15,7 +15,7 @@ from django.http.multipartparser import MultiPartParser, MultiPartParserError from django.utils import six from django.utils.datastructures import MultiValueDict, ImmutableList from django.utils.encoding import force_bytes, force_text, force_str, iri_to_uri -from django.utils.six.moves.urllib.parse import parse_qsl, urlencode, quote, urljoin +from django.utils.six.moves.urllib.parse import parse_qsl, urlencode, quote, urljoin, urlsplit RAISE_ERROR = object() @@ -119,14 +119,25 @@ class HttpRequest(object): def build_absolute_uri(self, location=None): """ Builds an absolute URI from the location and the variables available in - this request. If no location is specified, the absolute URI is built on - ``request.get_full_path()``. + this request. If no ``location`` is specified, the absolute URI is + built on ``request.get_full_path()``. Anyway, if the location is + absolute, it is simply converted to an RFC 3987 compliant URI and + returned and if location is relative or is scheme-relative (i.e., + ``//example.com/``), it is urljoined to a base URL constructed from the + request variables. """ - if not location: - location = self.get_full_path() - if not absolute_http_url_re.match(location): - current_uri = '%s://%s%s' % (self.scheme, - self.get_host(), self.path) + if location is None: + # Make it an absolute url (but schemeless and domainless) for the + # edge case that the path starts with '//'. + location = '//%s' % self.get_full_path() + bits = urlsplit(location) + if not (bits.scheme and bits.netloc): + current_uri = '{scheme}://{host}{path}'.format(scheme=self.scheme, + host=self.get_host(), + path=self.path) + # Join the constructed URL with the provided location, which will + # allow the provided ``location`` to apply query strings to the + # base path as well as override the host, if it begins with // location = urljoin(current_uri, location) return iri_to_uri(location) |
