Here's a new PrefixMiddleware that works correctly:

class PrefixMiddleware(object):

    def __init__(self, application, config):
        self.application = application
        if 'url_prefix' in config:
            self.prefix = config['url_prefix'].rstrip('/')

    def __call__(self, environ, start_response):
        environ['wsgi.url_scheme'] = environ.get
('HTTP_X_FORWARDED_PROTO', 'http')
        if 'HTTP_X_FORWARDED_HOST' in environ:
            environ['HTTP_HOST']=environ['HTTP_X_FORWARDED_HOST']
        if self.prefix:
            environ['SCRIPT_NAME']=self.prefix

        return self.application(environ, start_response)


It depends on "url_prefix" setting in the config file (if using a
prefix), and on HTTP_X_FORWARDED_PROTO and HTTP_X_FORWARDED_HOST
headers in the http request to indicate the original host and
protocol.

In apache, HTTP_X_FORWARDED_HOST is set by default (when request is
forwarded using mod_proxy) and you can set the other one like this:

        RequestHeader set X_URL_SCHEME https

In nginx, you set them like this:

        proxy_set_header X_FORWARDED_PROTO $scheme;
        proxy_set_header X_FORWARDED_HOST $server_name;

You can use the PrefixMiddleware at the end of config/middleware.py:

    app = PrefixMiddleware(app, config)
    return app


On Jan 3, 12:34 am, Tycon <[email protected]> wrote:
> but the PrefixMiddleWare also doesn't seem to be setting the WSGI
> environment url_scheme
> (nor request.scheme). The PrefixMiddleware code never looks up
> HTTP_X_FORWARDED_PROTO and doesn't set the url scheme in the wsgi
> environment. So that needs  to be fixed, as well as made clear to
> users that they should include it (after it's fixed) if they use a
> reverse proxy even without a prefix.
>
> On Jan 2, 11:32 pm, Ben Bangert <[email protected]> wrote:
>
> > On Jan 2, 2009, at 9:45 PM, Tycon wrote:
>
> > > I submitted a ticket (#554) for this bug, with a proposed fix.
>
> > > But there is another bug underlying this function which affects
> > > detection of the request's url scheme. This decorator uses
> > > "request.scheme" to find out if the request was http or https, but in
> > > a reverse proxy configuration this is always set to "http" even if the
> > > original request was https.
>
> > That's not a bug. In a reverse proxy you should be using the  
> > PrefixMiddleware which fixes up the WSGI environ based on headers that  
> > your proxy should set, like X_FORWARDED_FOR, etc.
>
> > > The routes module (which provides url_for and redirect_to) actually
> > > has a better way of checking the request scheme by using the
> > > HTTP_X_FORWARDED_PROTO header (so it correctly creates fully qualified
> > > URLs even in proxy mode).
>
> > This will likely be removed in favor of using middleware as  
> > appropriate to fix the environ settings based on the deployment  
> > environment.
>
> > Cheers,
> > Ben
>
> >  smime.p7s
> > 3KViewDownload
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"pylons-discuss" 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/pylons-discuss?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to