Django 1.11 on passenger_wsgi not routing POST request

后端 未结 1 1854
盖世英雄少女心
盖世英雄少女心 2021-01-25 05:05

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

相关标签:
1条回答
  • 2021-01-25 05:46

    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:

    • http://alyalearningdjango.blogspot.com/2014/05/issue-360-passenger-doesnt-set-pathinfo.html
    • https://github.com/phusion/passenger/issues/460
    • https://www.python.org/dev/peps/pep-0333/#environ-variables
    0 讨论(0)
提交回复
热议问题