I'm using Apache 2.2 with mod_wsgi 3.1. I use hostname-based virtual
hosts. I used to have this working on another server by simply using
"WSGIPassAuthorization On" in the httpd.conf file, but I've changed
setup and now I can't figure out why it's not working.
Here is my httpd.conf:
ServerRoot "/path/to/apache2"
Listen 12345
LoadModule log_config_module modules/mod_log_config.so
LoadModule authz_host_module modules/mod_authz_host.so
LoadModule authn_default_module modules/mod_authn_default.so
#LoadModule authz_host_module modules/mod_authz_host.so
LoadModule authz_user_module modules/mod_authz_user.so
LoadModule authz_default_module modules/mod_authz_default.so
LoadModule auth_basic_module modules/mod_auth_basic.so
LoadModule auth_digest_module modules/mod_auth_digest.so
#LoadModule log_config_module modules/mod_log_config.so
LoadModule env_module modules/mod_env.so
LoadModule mime_module modules/mod_mime.so
LoadModule dir_module modules/mod_dir.so
LoadModule alias_module modules/mod_alias.so
LoadModule rewrite_module modules/mod_rewrite.so
LoadModule wsgi_module modules/mod_wsgi.so
ServerAdmin admin@(removed).com
#DocumentRoot "/path/to/apache2/htdocs"
<Directory />
Options FollowSymLinks
AllowOverride None
Order deny,allow
Deny from all
</Directory>
# Logging
ErrorLog "logs/error_log"
LogLevel warn
LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i
\"" combined
CustomLog "logs/access_log" combined
# Virtual Hosting Setup
ServerLimit 1
MinSpareThreads 1
MaxSpareThreads 5
ThreadsPerChild 10
<Directory /path/to/wsgi>
Order allow,deny
Allow from all
</Directory>
NameVirtualHost *:12345
# Virtual Hosts
<VirtualHost *:12345>
ServerName (domain1).com
KeepAlive Off
WSGIDaemonProcess (domain1).com processes=1 threads=20 inactivity-
timeout=60 display-name=[wsgi-scriptshare]httpd
WSGIProcessGroup (domain1).com
WSGIScriptAlias / /path/to/wsgi/scriptshare.wsgi
</VirtualHost>
<VirtualHost *:12345>
ServerName (domain2).com
ServerAlias www.(domain2).com
KeepAlive Off
WSGIDaemonProcess (domain2).com processes=1 threads=10 inactivity-
timeout=60 display-name=[wsgi-everythingri]httpd
WSGIProcessGroup (domain2).com
WSGIScriptAlias / /path/to/wsgi/everythingri.wsgi
</VirtualHost>
<VirtualHost *:12345>
ServerName (domain3).com
KeepAlive Off
# THIS SHOULD PASS HTTP_AUTHORIZATION TO DJANGO...
WSGIPassAuthorization On
WSGIDaemonProcess (domain3).com processes=1 threads=10 inactivity-
timeout=60 display-name=[wsgi-dev-seemonkey]httpd
WSGIProcessGroup (domain3).com
WSGIScriptAlias / /path/to/wsgi/seemonkey.wsgi
</VirtualHost>
I run this test program:
import urllib
import urllib2
url = '(removed)'
print 'URL: %s' % url
headers = {
'HTTP_AUTHORIZATION': '!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
HTTP_AUTHORIZATION',
'FAKE': '!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! FAKE',
}
print 'headers: %s' % headers
print 'Results:'
#print 'sending headers: %s' % headers
req = urllib2.Request(url, headers=headers)
try:
url1 = urllib2.urlopen(req)
except Exception, e:
print 'Exception:'
print e
else:
response = url1.read()
print 'response:'
print '----------------------------------------'
print response
print '----------------------------------------'
print ''
For "manage.py runserver", I get this result:
URL: (django runserver url)
headers: {'HTTP_AUTHORIZATION':
'!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! HTTP_AUTHORIZATION', 'FAKE':
'!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! FAKE'}
Results:
response:
----------------------------------------
request.META[wsgi.version]: (1, 0)
request.META[wsgi.multiprocess]: False
request.META[RUN_MAIN]: 'true'
request.META[SERVER_PROTOCOL]: 'HTTP/1.1'
request.META[SERVER_SOFTWARE]: 'WSGIServer/0.1 Python/2.5.4'
request.META[SCRIPT_NAME]: u''
request.META[REQUEST_METHOD]: 'GET'
request.META[PROCESSOR_REVISION]: '0f0b'
request.META[QUERY_STRING]: ''
request.META[HTTP_HTTP_AUTHORIZATION]:
'!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! HTTP_AUTHORIZATION'
request.META[wsgi.errors]: <open file '<stderr>', mode 'w' at
0x00A400B0>
request.META[CONTENT_LENGTH]: ''
request.META[HTTP_CONNECTION]: 'close'
request.META[REMOTE_HOST]: ''
request.META[REMOTE_ADDR]: '127.0.0.1'
request.META[SERVER_PORT]: '10002'
request.META[SESSIONNAME]: 'Console'
request.META[PROCESSOR_LEVEL]: '6'
request.META[HTTP_FAKE]: '!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
FAKE'
request.META[USERNAME]: '(username)'
request.META[wsgi.input]: <socket._fileobject object at 0x018B76B0>
request.META[HTTP_USER_AGENT]: 'Python-urllib/2.5'
request.META[HTTP_HOST]: 'localhost:10002'
request.META[wsgi.multithread]: True
request.META[PATHEXT]:
'.COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH'
request.META[PATH_INFO]: u'/(page_url)'
request.META[SERVER_NAME]: '(server name)'
request.META[GATEWAY_INTERFACE]: 'CGI/1.1'
request.META[wsgi.run_once]: False
request.META[DJANGO_SETTINGS_MODULE]: '(django app name).settings'
request.META[CONTENT_TYPE]: 'text/plain'
request.META[wsgi.file_wrapper]: <class
'django.core.servers.basehttp.FileWrapper'>
request.META[OS]: 'Windows_NT'
request.META[HTTP_ACCEPT_ENCODING]: 'identity'
request.META[wsgi.url_scheme]: 'http'
request.META.get('HTTP_AUTHORIZATION', None): None
request.META.get('HTTP_HTTP_AUTHORIZATION', None):
'!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! HTTP_AUTHORIZATION'
----------------------------------------
The HTTP_HTTP_AUTHORIZATION shows up just fine.
But with the apache server, I get these results:
URL: (apache url)
headers: {'HTTP_AUTHORIZATION':
'!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! HTTP_AUTHORIZATION', 'FAKE':
'!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! FAKE'}
Results:
response:
----------------------------------------
request.META[mod_wsgi.reload_mechanism]: '1'
request.META[mod_wsgi.listener_port]: '29019'
request.META[SERVER_SOFTWARE]: 'Apache/2.2.14 (Unix) mod_wsgi/2.5
Python/2.5.4'
request.META[SCRIPT_NAME]: u''
request.META[SERVER_SIGNATURE]: ''
request.META[REQUEST_METHOD]: 'GET'
request.META[PATH_INFO]: u'/(page url)'
request.META[SERVER_PROTOCOL]: 'HTTP/1.0'
request.META[QUERY_STRING]: ''
request.META[HTTP_USER_AGENT]: 'Python-urllib/2.5'
request.META[HTTP_CONNECTION]: 'close'
request.META[SERVER_NAME]: '(server name)'
request.META[REMOTE_ADDR]: '127.0.0.1'
request.META[wsgi.url_scheme]: 'http'
request.META[SERVER_PORT]: '80'
request.META[wsgi.multiprocess]: True
request.META[HTTP_FAKE]: '!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
FAKE'
request.META[SERVER_ADDR]: '127.0.0.1'
request.META[mod_wsgi.process_group]: '(removed)'
request.META[SCRIPT_FILENAME]: '(removed).wsgi'
request.META[SERVER_ADMIN]: '(removed)'
request.META[wsgi.input]: <mod_wsgi.Input object at 0xb03b8f48>
request.META[HTTP_HOST]: '(removed)'
request.META[wsgi.multithread]: True
request.META[mod_wsgi.callable_object]: 'application'
request.META[REQUEST_URI]: '/(removed)'
request.META[wsgi.version]: (1, 0)
request.META[GATEWAY_INTERFACE]: 'CGI/1.1'
request.META[HTTP_X_FORWARDED_FOR]: '(removed)'
request.META[wsgi.errors]: <mod_wsgi.Log object at 0xa348338>
request.META[REMOTE_PORT]: '51174'
request.META[mod_wsgi.listener_host]: ''
request.META[mod_wsgi.version]: (2, 5)
request.META[wsgi.run_once]: False
request.META[mod_wsgi.application_group]: '(removed)|'
request.META[mod_wsgi.script_reloading]: '1'
request.META[wsgi.file_wrapper]: <built-in method file_wrapper of
mod_wsgi.Adapter object at 0xa268c80>
request.META[HTTP_ACCEPT_ENCODING]: 'identity'
request.META.get('HTTP_AUTHORIZATION', None): None
request.META.get('HTTP_HTTP_AUTHORIZATION', None): None
----------------------------------------
The "FAKE" http header shows up as "HTTP_FAKE", but the
"HTTP_AUTHORIZATION" header doesn't show up at all. It's being
filtered out, which is what you'd expect if the WSGIPassAuthorization
was Off. I've restarted the server a ton, played with the http.conf,
and I'm stuck.
What other steps can I try to troubleshoot this? My host is
webfaction, which runs Apache behind an nginx proxy frontend. I'm not
sure if that makes a difference. I've been using this fine on another
machine, but recently switched machines, then recompiled apache, and
now it doesn't work. Something's wrong, but I'm out of ideas of where
to look.
Thanks so much for any help!
http://code.google.com/p/modwsgi/wiki/DebuggingTechniques#Displaying_Request_Environment
That will take Django out of the picture.
Graham
2009/12/23 Jumpfroggy <rocket...@gmail.com>:
> --
>
> You received this message because you are subscribed to the Google Groups "modwsgi" group.
> To post to this group, send email to mod...@googlegroups.com.
> To unsubscribe from this group, send email to modwsgi+u...@googlegroups.com.
> For more options, visit this group at http://groups.google.com/group/modwsgi?hl=en.
>
>
>
Graham,
Thanks so much for your help. It's a shame I'm not great at reading
the mod_wsgi docs, because there's a ton of helpful stuff in there
that I just seem to gloss over.
I've added that test application in and below are the results. Same
thing: the "FAKE" header shows up as "HTTP_FAKE", but the
HTTP_AUTHORIZATION header is missing. I'm going to contact my hosting
co. to make sure it's not a problem on their side, but I have a hunch
it's something I've done wrong in the config.
-James
BTW, Thanks Graham for being so involved with mod_wsgi. It's very
useful, and it's nice to find a project that's so 'alive'.
-- Pasted from the debugging application: --
URL: http://test.(domain).com
headers: {'HTTP_AUTHORIZATION':
'!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! HTTP_AUTHORIZATION', 'FAKE':
'!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! FAKE'}
Results:
----------------------------------------
PID: 13460
UID: 654
GID: 654
DOCUMENT_ROOT: '/path/to/htdocs'
GATEWAY_INTERFACE: 'CGI/1.1'
HTTP_ACCEPT_ENCODING: 'identity'
HTTP_CONNECTION: 'close'
HTTP_FAKE: '!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! FAKE'
HTTP_HOST: 'test.(domain).com'
HTTP_USER_AGENT: 'Python-urllib/2.5'
HTTP_X_FORWARDED_FOR: '(removed)'
PATH: '(removed)'
PATH_INFO: '/'
PATH_TRANSLATED: '/path/to/test.wsgi/'
QUERY_STRING: ''
REMOTE_ADDR: '127.0.0.1'
REMOTE_PORT: '57509'
REQUEST_METHOD: 'GET'
REQUEST_URI: '/'
SCRIPT_FILENAME: '/path/to/test.wsgi'
SCRIPT_NAME: ''
SERVER_ADDR: '127.0.0.1'
SERVER_ADMIN: 'admin@(domain).com'
SERVER_NAME: 'test.(domain).com'
SERVER_PORT: '80'
SERVER_PROTOCOL: 'HTTP/1.0'
SERVER_SIGNATURE: ''
SERVER_SOFTWARE: 'Apache/2.2.14 (Unix) mod_wsgi/2.5 Python/2.5.4'
mod_wsgi.application_group: 'test.(domain).com|'
mod_wsgi.callable_object: 'application'
mod_wsgi.listener_host: ''
mod_wsgi.listener_port: '12345'
mod_wsgi.process_group: 'test.(domain).com'
mod_wsgi.reload_mechanism: '1'
mod_wsgi.script_reloading: '1'
mod_wsgi.version: (2, 5)
wsgi.errors: <mod_wsgi.Log object at 0xb7f3f608>
wsgi.file_wrapper: <built-in method file_wrapper of mod_wsgi.Adapter
object at 0xb7f10650>
wsgi.input: <mod_wsgi.Input object at 0xb7f2b4a8>
wsgi.multiprocess: True
wsgi.multithread: True
wsgi.run_once: False
wsgi.url_scheme: 'http'
wsgi.version: (1, 0)
----------------------------------------
WSGIPassAuthorization On
outside of all virtual hosts rather than restricting it to just one.
If this works though, suggests that virtual host mapping by Apache
isn't working as you expect.
You could also add:
SetEnv XXX YYY
in Apache configuration, inside of virtual host, but also then outside
of virtual host, to verify that that setting even carrying through
into WSGI environment when that is used in different contexts.
Overall, as far as I know all that needs to be done on WebFaction is
set WSGIPassAuthorization. Ie., nothing need in nginx front end.
Graham
2009/12/23 Jumpfroggy <rocket...@gmail.com>:
Ok, so after playing around, I think the problem is with my test
program, and also with my incorrect/incomplete understanding of HTTP
header names.
These http headers show up fine:
A -> HTTP_A
FAKE -> HTTP_FAKE
PAGE-TYPE -> HTTP_PAGE_TYPE
However, these do not show up at all:
A_
HTTP_FAKE
PAGE_TYPE
So apache filters out all names with underscores. It also prepends
HTTP_, and converts _ to -, which I knew. I think the problem is that
I'm sending "HTTP_AUTHORIZATION", which gets filtered out. However,
if I send an "AUTHORIZATION" header, it gets turned into
"HTTP_AUTHORIZATION" due to apache name mangling and then shows up
fine with "WSGIPassAuthorization On".
I've been focusing too much on "HTTP_AUTHORIZATION" to realize that
that's just the mangled version of the AUTHORIZATION header. Does
that make sense, or am I short-circuiting here?
So if this is truly the case, then I'm being stupid;
WSGIPassAuthorization worked just fine, it was my test program that
was incorrect. I'll try this with Google Checkout, and see if that
works as well.
Yep. I sort of assumed you were using standard client which sent it as
'Authorization' HTTP header.
Interesting that Apache filters out anything with underscore, I didn't
know that. Will have to remember for future.
Graham
--
You received this message because you are subscribed to the Google Groups "modwsgi" group.
To unsubscribe from this group and stop receiving emails from it, send an email to modwsgi+u...@googlegroups.com.
To post to this group, send email to mod...@googlegroups.com.
Visit this group at http://groups.google.com/group/modwsgi.
For more options, visit https://groups.google.com/d/optout.