On Sep 25, 3:54 am, Jeffrey Froman <[EMAIL PROTECTED]> wrote:
> Hello,
>
> As of revision #6164, when accessing my site over HTTPS, all redirects
> are being sent to plain HTTP urls.
>
> It seems that this is because build_absolute_uri() uses
> request.is_secure() to determine if the absolute url should be secure,
> and request.is_secure() makes its determination based on whether or
> not the variable 'HTTPS' is set to "on" in the operating system
> environment. But this variable is not set in the operating system
> environment in all cases. In particular, it does not work when
> deploying Django through mod_wsgi. I have not tested HTTPS redirects
> through fastcgi, but I suspect a similar problem may exist there. Can
> anyone verify or debunk this suspicion?
>
> I'm not sure what the right solution is to this problem, or if it is
> best addressed in Django, or mod_wsgi, or somewhere else.

In WSGI indication of https is specified by:

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.

If HTTPS is being set then it is incidental and should not be relied
upon. If the internals of Django is expecting HTTPS to be set, in the
WSGI interface it should check for wsgi.url_scheme and if it is
'https' then set HTTPS explicitly to 'on'. Ie., translate from WSGI
convention.

Also, Django should possibly be checking for more than just 'on' as
value for HTTPS as some web servers pass '1' rather than 'on' anyway.
The WSGI PEP even shows an example for a CGI/WSGI adapater as such
where it caters for this.

if environ.get('HTTPS','off') in ('on','1'):
        environ['wsgi.url_scheme'] = 'https'
    else:
        environ['wsgi.url_scheme'] = 'http'

The WSGI specification also show the correct way of constructing an
absolute URL:

from urllib import quote
url = environ['wsgi.url_scheme']+'://'

if environ.get('HTTP_HOST'):
    url += environ['HTTP_HOST']
else:
    url += environ['SERVER_NAME']

    if environ['wsgi.url_scheme'] == 'https':
        if environ['SERVER_PORT'] != '443':
           url += ':' + environ['SERVER_PORT']
    else:
        if environ['SERVER_PORT'] != '80':
           url += ':' + environ['SERVER_PORT']

url += quote(environ.get('SCRIPT_NAME',''))
url += quote(environ.get('PATH_INFO',''))
if environ.get('QUERY_STRING'):
    url += '?' + environ['QUERY_STRING']

Note how it relies on wsgi.url_scheme and not HTTPS.

In summary, Django code needs to be updated so that its WSGI adapter
sets HTTPS explicitly based on wsgi.url_scheme if it wants to use
HTTPS internally.

Graham


--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to