Bug 50581 - Apache sets HTTPS variable to '1' instead of 'on'
Summary: Apache sets HTTPS variable to '1' instead of 'on'
Alias: None
Product: Apache httpd-2
Classification: Unclassified
Component: mod_ssl (show other bugs)
Version: 2.2.16
Hardware: PC Windows Vista
: P2 normal (vote)
Target Milestone: ---
Assignee: Apache HTTPD Bugs Mailing List
Depends on:
Reported: 2011-01-13 16:46 UTC by techtonik
Modified: 2011-01-14 23:34 UTC (History)
0 users

probe.wsgi (310 bytes, text/plain)
2011-01-14 08:29 UTC, techtonik
probe.output (1.13 KB, text/plain)
2011-01-14 08:33 UTC, techtonik

Note You need to log in before you can comment on or make changes to this bug.
Description techtonik 2011-01-13 16:46:44 UTC
It seems that the standard way for the web server to report that site is running under https is to set value of environment variable HTTPS to 'on'. Apache2 sets it to '1'.

Comment 1 Eric Covener 2011-01-13 21:12:36 UTC
In what context do you see it set to "1"?
Comment 2 techtonik 2011-01-14 06:38:01 UTC
Django running on Apache2 using mod_wsgi. The variable is copied from os.environ to WSGIRequest class and available as request.META['HTTPS']. Do you think it is transformed on the way? I'll check later from ordinary .wsgi script.
Comment 3 Eric Covener 2011-01-14 07:27:06 UTC
You or your framework or your interpreter are coercing it into one. You can log it in your access log a bit more directly with %{HTTPS}e.  Re-open the bug if there's something more sinister going on.
Comment 4 techtonik 2011-01-14 08:29:21 UTC
Created attachment 26487 [details]
Comment 5 techtonik 2011-01-14 08:33:03 UTC
Created attachment 26488 [details]

As you may see from probe script mod_wsgi calls application with HTTPS='1' already set in environ, so the problem is not in Django or Python scripts.
Comment 6 techtonik 2011-01-14 08:51:27 UTC
Seems like a problem with mod_wsgi module. I've added the following log format:

LogFormat "%t %{HTTPS}e  \"%r\" %>s %b" https

It reports the following information:

[14/Jan/2011:07:47:05 -0600] 1  "GET / HTTP/1.1" 200 2278
[14/Jan/2011:07:47:08 -0600] on  "GET /static/styles.css HTTP/1.1" 304 -
[14/Jan/2011:07:47:08 -0600] on  "GET /static/script.js HTTP/1.1" 304 -
[14/Jan/2011:07:47:08 -0600] on  "GET /static/rss.gif HTTP/1.1" 304 -
[14/Jan/2011:07:47:41 -0600] 1  "GET /search HTTP/1.1" 200 2592

/static is an alias and it is served by Apache2 directly. / and /search are served by WSGIDaemonProcess. Thanks for the hint.
Comment 7 Graham Dumpleton 2011-01-14 23:34:00 UTC
OP is wrong on a few accounts.

First off, under WSGI scripts the correct way of identifying whether HTTPS was used is to check the wsgi.url_scheme variable. The value of HTTPS cannot be relied upon and could be missing depending on the WSGI hosting environment being used even though HTTPS may be used.

Their probe output even showed the correct value to check:

 'wsgi.url_scheme': 'https'

Second thing wrong is that the environ they printed out was a WSGI per request environment and not process wide environment variables from os.environ. That WSGI per request environment isn't the same as what you would see for a CGI script where process environment variables are used and so you cant use CGI as the basis for what is in it.

FWIW, the WSGI specification even gives an example for a CGI/WSGI bridge which is tolerant of HTTPS being 'On' or '1' as historically there seems to have been hosting systems where 'On' may not have been used:

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

A value of '1' for HTTPS was also potentially used in non WSGI hosting systems for Python in the past as some Python web frameworks were hardwired to look for HTTPS being '1' rather than 'On' and also weren't updated to use wsgi.url_scheme instead. It is to accommodate those Python web frameworks that '1' in particular was used rather than 'On' for what was a variable being passed in WSGI environment and nothing to do with CGI or Apache.