I\'m trying to setup python on A2 shared hosting via passenger_wsgi. The app is working fine when I run it via \'runserver\'. I tested this both in my local PC, and via SSH tun
It looks like you may have solved this, but to followup for anyone that may stumble here. I have been using A2Hosting, Passenger, and CPanel with django (and wagtail). What I found was that during POST requests the wsgi SCRIPT_NAME
was being set to a relative path and not the root of the application.
When I added logging to each application call, the correct GET
request was:
{
'REQUEST_URI': '/admin/',
'PATH_INFO': '/admin/',
'SCRIPT_NAME': '',
'QUERY_STRING': '',
'REQUEST_METHOD': 'GET',
...
But on that page, a form was submitting a POST
, which had the PATH_INFO
incorrectly set:
{
'REQUEST_URI': '/admin/login/',
'PATH_INFO': '/login/',
'SCRIPT_NAME': '/admin',
'QUERY_STRING': '',
'REQUEST_METHOD': 'POST',
...
The workaround I ended up using was to create middleware which asserted a known SCRIPT_NAME
and rebuilt the PATH_INFO
from it.
# Set this to your root
SCRIPT_NAME = ''
class PassengerPathInfoFix(object):
"""
Sets PATH_INFO from REQUEST_URI since Passenger doesn't provide it.
"""
def __init__(self, app):
self.app = app
def __call__(self, environ, start_response):
from urllib.parse import unquote
environ['SCRIPT_NAME'] = SCRIPT_NAME
request_uri = unquote(environ['REQUEST_URI'])
script_name = unquote(environ.get('SCRIPT_NAME', ''))
offset = request_uri.startswith(script_name) and len(environ['SCRIPT_NAME']) or 0
environ['PATH_INFO'] = request_uri[offset:].split('?', 1)[0]
return self.app(environ, start_response)
application = get_wsgi_application()
application = PassengerPathInfoFix(application)
Related Reading: