Opened 8 years ago

Closed 3 years ago

#7603 closed New feature (fixed)

Add HttpRequest.scheme property

Reported by: nslater Owned by: Unai Zalakain
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 Morales)

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 8 years ago by anonymous

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 8 years ago by Ramiro Morales

Description: modified (diff)

comment:3 Changed 8 years ago by Adrian Holovaty

Triage Stage: UnreviewedDesign decision needed

comment:4 Changed 8 years ago by nslater

Owner: changed from nobody to nslater
Status: newassigned

Great, thanks for that!

I still think this would be useful though.

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

Component: UncategorizedHTTP handling

comment:6 Changed 8 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 6 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 6 years ago by Luke Plant

Severity: Normal
Type: New feature

comment:9 Changed 5 years ago by Alex Gaynor

Easy pickings: unset
Triage Stage: Design decision neededAccepted
UI/UX: unset

comment:10 Changed 3 years ago by Unai Zalakain

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 3 years ago by Tim Graham

Patch needs improvement: set
Summary: The Request object should have a "scheme" attributeAdd HttpRequest.get_scheme()

Comments for improvement on the branch.

comment:12 Changed 3 years ago by Unai Zalakain

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

comment:13 Changed 3 years ago by Unai Zalakain

Summary: Add HttpRequest.get_scheme()Add HttpRequest.scheme property

comment:14 Changed 3 years ago by Unai Zalakain

Owner: changed from nslater to Unai Zalakain

comment:15 Changed 3 years ago by Tim Graham

Patch needs improvement: unset
Triage Stage: AcceptedReady 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 3 years ago by Aymeric Augustin

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 3 years ago by Unai Zalakain

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 3 years ago by Tim Graham <timograham@…>

Resolution: fixed
Status: assignedclosed

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