Opened 7 years ago

Closed 22 months ago

#7603 closed New feature (fixed)

Add HttpRequest.scheme property

Reported by: nslater Owned by: unaizalakain
Component: HTTP handling Version: master
Severity: Normal Keywords:
Cc: Triage Stage: Ready for checkin
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description (last modified by ramiro)

As it stands, the scheme is located at request["wsgi.url_scheme"] which translates as {{ request.wsgi.url_scheme}} which is invalid for obvious reasons, leaving no way to access this value from the template.

The Request object should be modified to have a "scheme" attritbute.

I could then do this from a template:

<img src="{{ request.scheme }}://{{ site.domain }}/logo"/>

Change History (18)

comment:1 Changed 7 years ago by anonymous

  • Needs documentation unset
  • Needs tests unset
  • Patch needs improvement unset

You could also use a "protocol relative URI" that starts with two slashes: {{ site.domain }}/logo

(For an example in the wild, ibm.com uses this technique.)

comment:2 Changed 7 years ago by ramiro

  • Description modified (diff)

comment:3 Changed 7 years ago by adrian

  • Triage Stage changed from Unreviewed to Design decision needed

comment:4 Changed 7 years ago by nslater

  • Owner changed from nobody to nslater
  • Status changed from new to assigned

Great, thanks for that!

I still think this would be useful though.

comment:5 Changed 7 years ago by Piotr Lewandowski <django@…>

  • Component changed from Uncategorized to HTTP handling

comment:6 Changed 6 years ago by holdenweb

Given that the scheme is relatively easily deduced from request.is_secure() this seems like it shouldn't really be needed.

comment:7 Changed 5 years ago by cgieringer

@holdenweb so now all templates must perform: {% if request.is_secure() %}https{% else %}http{% endif %}?

That's less elegant, and doesn't allow generally for applications that are dealing with other schemes, e.g. a django PBX application that needs to differentiate between a set of schemes in a way that isn't just a binary question: is HTTP, is HTTPS.

comment:8 Changed 4 years ago by lukeplant

  • Severity set to Normal
  • Type set to New feature

comment:9 Changed 4 years ago by Alex

  • Easy pickings unset
  • Triage Stage changed from Design decision needed to Accepted
  • UI/UX unset

comment:10 Changed 22 months ago by unaizalakain

  • Has patch set

Patch: https://github.com/unaizalakain/django/tree/ticket_7603

HttpRequest.get_scheme() uses self.is_secure() to determine if scheme is 'http' or 'https' wether WSGIRequest.get_scheme() makes use of the 'wsgi.url_scheme' WSGI environ variable.

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

comment:11 Changed 22 months ago by timo

  • Patch needs improvement set
  • Summary changed from The Request object should have a "scheme" attribute to Add HttpRequest.get_scheme()

Comments for improvement on the branch.

comment:12 Changed 22 months ago by unaizalakain

Comments taken into account, pull request: https://github.com/django/django/pull/1730

comment:13 Changed 22 months ago by unaizalakain

  • Summary changed from Add HttpRequest.get_scheme() to Add HttpRequest.scheme property

comment:14 Changed 22 months ago by unaizalakain

  • Owner changed from nslater to unaizalakain

comment:15 Changed 22 months ago by timo

  • Patch needs improvement unset
  • Triage Stage changed from Accepted to Ready for checkin

This looks good to me, but since it's potentially security related I'd like one more +1 before committing.

comment:16 Changed 22 months ago by aaugustin

LGTM.

Why do the docs say "normally" and "usually"? The current implementation is always going to return 'http' or 'https'. Let's avoid vague terms.

comment:17 Changed 22 months ago by unaizalakain

In fact, scheme is gotten from wsgi.url_scheme WSGI variable. The docs state that:

wsgi.url_scheme: A string representing the "scheme" portion of the URL at which the application is being invoked. Normally, this will have the value "http" or "https", as appropriate.

It's true that this will always be http or https but there's no guarantee about it.

comment:18 Changed 22 months ago by Tim Graham <timograham@…>

  • Resolution set to fixed
  • Status changed from assigned to closed

In c7634cd7fe7dc09338fcec0ca48d816a29d791b0:

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.

Note: See TracTickets for help on using tickets.
Back to Top