librelist archives

« back to archive

problem with apache proxy and canonical urls

problem with apache proxy and canonical urls

From:
Jérôme Pigeot
Date:
2011-03-14 @ 10:25
Hello,

I'm testing some flask apps deployed with an apache server with mod proxy in
front, and gunicorn instances to serve them.
In all apps, all the routes finish with a trailing slash to let an url
without it to be redirected  to the canonical url (like mentions the doc:
http://flask.pocoo.org/docs/quickstart/#routing)

Here's a part of my apache conf:

<VirtualHost *:80>
    ServerName myserver.mydomain.com

    <Proxy *>
        Order deny,allow
        Allow from all
    </Proxy>

    ProxyPass /app1/ http://givenserver:givenport/
    ProxyPass /app2/ http://givenserver:givenport/

</VirtualHost>

As you can see apache serves each apps on a given prefix (/app1/,
/app2/...), the problem comes when flask/werkzeug redirects the urls, it
doesn't append the prefix to urls :
Ex: http://myserver.mydomain.com/app1/url will be redirected to
http://myserver.mydomain.com/url/
I think that the SERVER_NAME atribute in the configuration is used to handle
that kind of configuration, but i didn't succeed in using it...

Any help would be very usefull.
Thanks by advance.

Jérôme.

Re: [flask] problem with apache proxy and canonical urls

From:
Abdul Bijur V. A.
Date:
2011-03-14 @ 11:39
Please set ProxyPreserveHost to On and try again.

Cheers,
Abdul
On Mar 14, 2011 11:26 AM, "Jérôme Pigeot" <j.pigeot@gmail.com> wrote:
> Hello,
>
> I'm testing some flask apps deployed with an apache server with mod proxy
in
> front, and gunicorn instances to serve them.
> In all apps, all the routes finish with a trailing slash to let an url
> without it to be redirected to the canonical url (like mentions the doc:
> http://flask.pocoo.org/docs/quickstart/#routing)
>
> Here's a part of my apache conf:
>
> <VirtualHost *:80>
> ServerName myserver.mydomain.com
>
> <Proxy *>
> Order deny,allow
> Allow from all
> </Proxy>
>
> ProxyPass /app1/ http://givenserver:givenport/
> ProxyPass /app2/ http://givenserver:givenport/
>
> </VirtualHost>
>
> As you can see apache serves each apps on a given prefix (/app1/,
> /app2/...), the problem comes when flask/werkzeug redirects the urls, it
> doesn't append the prefix to urls :
> Ex: http://myserver.mydomain.com/app1/url will be redirected to
> http://myserver.mydomain.com/url/
> I think that the SERVER_NAME atribute in the configuration is used to
handle
> that kind of configuration, but i didn't succeed in using it...
>
> Any help would be very usefull.
> Thanks by advance.
>
> Jérôme.

Re: [flask] problem with apache proxy and canonical urls

From:
Jérôme Pigeot
Date:
2011-03-14 @ 15:21
Thanks for your answer but it doesn't solve the problem.

I tested a similar configuration with nginx in place of apache and it works
better:
This is clearly a mistake in the apache conf cause the full path (/app1/url)
is kept in the nginx environment when it passes the request to the wsgi
environement (via PATH_INFO).
This is thanks to 2 variables in the nginx conf :

proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;

I didn't find any way to do the same in the apache one: so the PATH_INFO is
'/url'

I will continue searching and giving you my answer if it find it.
Thanks.

Jérôme.


2011/3/14 Abdul Bijur V. A. <bijur@grep-i.com>

> Please set ProxyPreserveHost to On and try again.
>
> Cheers,
> Abdul
> On Mar 14, 2011 11:26 AM, "Jérôme Pigeot" <j.pigeot@gmail.com> wrote:
> > Hello,
> >
> > I'm testing some flask apps deployed with an apache server with mod proxy
> in
> > front, and gunicorn instances to serve them.
> > In all apps, all the routes finish with a trailing slash to let an url
> > without it to be redirected to the canonical url (like mentions the doc:
> > http://flask.pocoo.org/docs/quickstart/#routing)
> >
> > Here's a part of my apache conf:
> >
> > <VirtualHost *:80>
> > ServerName myserver.mydomain.com
> >
> > <Proxy *>
> > Order deny,allow
> > Allow from all
> > </Proxy>
> >
> > ProxyPass /app1/ http://givenserver:givenport/
> > ProxyPass /app2/ http://givenserver:givenport/
> >
> > </VirtualHost>
> >
> > As you can see apache serves each apps on a given prefix (/app1/,
> > /app2/...), the problem comes when flask/werkzeug redirects the urls, it
> > doesn't append the prefix to urls :
> > Ex: http://myserver.mydomain.com/app1/url will be redirected to
> > http://myserver.mydomain.com/url/
> > I think that the SERVER_NAME atribute in the configuration is used to
> handle
> > that kind of configuration, but i didn't succeed in using it...
> >
> > Any help would be very usefull.
> > Thanks by advance.
> >
> > Jérôme.
>

Re: [flask] problem with apache proxy and canonical urls

From:
Rob Mela
Date:
2011-03-17 @ 01:21
I actually find it really useful that Apache strips off PATH_INFO from 
SCRIPT_NAME ( and gives me both ).

This simplifies having different environments of the same Flask apps 
running behind Apache.    The location of the path is used to route to 
different mod_wsgi servers, and Apache strips the rest off into a 
PATH_INFO that I can use in routing in my Flask apps, and this second 
part, the PATH_INFO, stays constant regardless of how I route locations to
mod_wsgi.

So I might request these from a server:

   /staging/stocks/quotes
   /dev/stocks/quotes

... where /staging/ and /dev/ are Apache <Location>s, pointing to 
different mod_wsgi instances, but on the Flask side, my routes are always 
/stocks/quotes.  This is because Apache strips off the Location part of 
the path when creatin PATH_INFO.   This is really convenient.   I still 
have the full path in some other WSGI environment variable -- I think it's
SCRIPT_NAME.

In nginx things work differently, but I've been able to replicate the 
Apache PATH_INFO variable with the following config:

 location ~ ^/staging/applets/stocks(.*)$ {
        set $path_info $1;
        uwsgi_pass   127.0.0.1:10001;
  }

and add this to my uwsgi_params:

uwsgi_param  PATH_INFO          $path_info;

Den Mar 14, 2011 kl. 11:21 AM skrev Jérôme Pigeot:

Thanks for your answer but it doesn't solve the problem.

I tested a similar configuration with nginx in place of apache and it 
works better:
This is clearly a mistake in the apache conf cause the full path 
(/app1/url) is kept in the nginx environment when it passes the request to
the wsgi environement (via PATH_INFO).
This is thanks to 2 variables in the nginx conf :

proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;

I didn't find any way to do the same in the apache one: so the PATH_INFO is '/url'

I will continue searching and giving you my answer if it find it.
Thanks.

Jérôme.


2011/3/14 Abdul Bijur V. A. <bijur@grep-i.com<mailto:bijur@grep-i.com>>

Please set ProxyPreserveHost to On and try again.

Cheers,
Abdul

On Mar 14, 2011 11:26 AM, "Jérôme Pigeot" 
<j.pigeot@gmail.com<mailto:j.pigeot@gmail.com>> wrote:
> Hello,
>
> I'm testing some flask apps deployed with an apache server with mod proxy in
> front, and gunicorn instances to serve them.
> In all apps, all the routes finish with a trailing slash to let an url
> without it to be redirected to the canonical url (like mentions the doc:
> http://flask.pocoo.org/docs/quickstart/#routing)
>
> Here's a part of my apache conf:
>
> <VirtualHost *:80>
> ServerName myserver.mydomain.com<http://myserver.mydomain.com/>
>
> <Proxy *>
> Order deny,allow
> Allow from all
> </Proxy>
>
> ProxyPass /app1/ http://givenserver:givenport/
> ProxyPass /app2/ http://givenserver:givenport/
>
> </VirtualHost>
>
> As you can see apache serves each apps on a given prefix (/app1/,
> /app2/...), the problem comes when flask/werkzeug redirects the urls, it
> doesn't append the prefix to urls :
> Ex: http://myserver.mydomain.com/app1/url will be redirected to
> http://myserver.mydomain.com/url/
> I think that the SERVER_NAME atribute in the configuration is used to handle
> that kind of configuration, but i didn't succeed in using it...
>
> Any help would be very usefull.
> Thanks by advance.
>
> Jérôme.

Re: [flask] problem with apache proxy and canonical urls

From:
Jérôme Pigeot
Date:
2011-03-17 @ 16:58
Thanks for this info.

You're right, apache keeps the server name and not the locations.
I displayed the gunicorn wsgi environment, there is 0 key that contains the
location...

Do you think it's possible to have an apache conf that let me using them??



2011/3/17 Rob Mela <rob@thinkingscreen.com>

> I actually find it really useful that Apache strips off PATH_INFO from
> SCRIPT_NAME ( and gives me both ).
>
> This simplifies having different environments of the same Flask apps
> running behind Apache.    The location of the path is used to route to
> different mod_wsgi servers, and Apache strips the rest off into a PATH_INFO
> that I can use in routing in my Flask apps, and this second part, the
> PATH_INFO, stays constant regardless of how I route locations to mod_wsgi.
>
> So I might request these from a server:
>
>    /staging/stocks/quotes
>    /dev/stocks/quotes
>
> ... where /staging/ and /dev/ are Apache <Location>s, pointing to different
> mod_wsgi instances, but on the Flask side, my routes are always
> /stocks/quotes.  This is because Apache strips off the Location part of the
> path when creatin PATH_INFO.   This is really convenient.   I still have the
> full path in some other WSGI environment variable -- I think it's
> SCRIPT_NAME.
>
> In nginx things work differently, but I've been able to replicate the
> Apache PATH_INFO variable with the following config:
>
>  location ~ ^/staging/applets/stocks(.*)$ {
>         set $path_info $1;
>         uwsgi_pass   127.0.0.1:10001;
>   }
>
>
> and add this to my uwsgi_params:
>
> uwsgi_param  PATH_INFO          $path_info;
>
> Den Mar 14, 2011 kl. 11:21 AM skrev Jérôme Pigeot:
>
> Thanks for your answer but it doesn't solve the problem.
>
> I tested a similar configuration with nginx in place of apache and it works
> better:
> This is clearly a mistake in the apache conf cause the full path
> (/app1/url) is kept in the nginx environment when it passes the request to
> the wsgi environement (via PATH_INFO).
> This is thanks to 2 variables in the nginx conf :
>
> proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
> proxy_set_header Host $http_host;
>
> I didn't find any way to do the same in the apache one: so the PATH_INFO is
> '/url'
>
> I will continue searching and giving you my answer if it find it.
> Thanks.
>
> Jérôme.
>
>
> 2011/3/14 Abdul Bijur V. A. <bijur@grep-i.com>
>
>> Please set ProxyPreserveHost to On and try again.
>>
>> Cheers,
>> Abdul
>> On Mar 14, 2011 11:26 AM, "Jérôme Pigeot" <j.pigeot@gmail.com> wrote:
>> > Hello,
>> >
>> > I'm testing some flask apps deployed with an apache server with mod
>> proxy in
>> > front, and gunicorn instances to serve them.
>> > In all apps, all the routes finish with a trailing slash to let an url
>> > without it to be redirected to the canonical url (like mentions the doc:
>> > http://flask.pocoo.org/docs/quickstart/#routing)
>> >
>> > Here's a part of my apache conf:
>> >
>> > <VirtualHost *:80>
>> > ServerName myserver.mydomain.com
>> >
>> > <Proxy *>
>> > Order deny,allow
>> > Allow from all
>> > </Proxy>
>> >
>> > ProxyPass /app1/ http://givenserver:givenport/
>> > ProxyPass /app2/ http://givenserver:givenport/
>> >
>> > </VirtualHost>
>> >
>> > As you can see apache serves each apps on a given prefix (/app1/,
>> > /app2/...), the problem comes when flask/werkzeug redirects the urls, it
>> > doesn't append the prefix to urls :
>> > Ex: http://myserver.mydomain.com/app1/url will be redirected to
>> > http://myserver.mydomain.com/url/
>> > I think that the SERVER_NAME atribute in the configuration is used to
>> handle
>> > that kind of configuration, but i didn't succeed in using it...
>> >
>> > Any help would be very usefull.
>> > Thanks by advance.
>> >
>> > Jérôme.
>>
>
>
>

Re: [flask] problem with apache proxy and canonical urls

From:
Rob Mela
Date:
2011-03-31 @ 02:55
BTW -- looking back at your original email -- if the problem is on 
redirect then maybeyou need to also add ProxyPassReverse directives 
alongside your ProxyPass directives.    See the various ProxyPassReverse 
directives at 
http://httpd.apache.org/docs/current/mod/mod_proxy.html#proxypassreverse :

This directive lets Apache adjust the URL in the Location, 
Content-Location and URI headers on HTTP redirect responses. This is 
essential when Apache is used as a reverse proxy (or gateway) to avoid 
by-passing the reverse proxy because of HTTP redirects on the backend 
servers which stay behind the reverse proxy.

So for your app,

ProxyPass /app1/ http://tivenserver:givenport/
ProxyPassReverse /app1/ http://givenserver:givenport/

There's two or three ProxyPassReverse directives.   For fixing up cookie 
domains and such there's ProxyPassReverseCookie.

As for going with mod_wsgi, I found that the WSGIScriptAlias determines 
how the path is split.

If for example you have a WSGIScriptAlias

 WSGIScriptAlias /applets/echo "path/to/my/echo.wsgi"

Then the alias - /applets/echo - becomes the SCRIPT_NAME.   For a request 
to http://myserver/applets/echo/a/b/c?x=y your wsgi ( or Flask ) script 
will get environment variables

PATH_INFO /a/b/c
SCRIPT_NAME /applets/echo
REQUEST_URI /applets/echo/a/b/c?x=u

If you change your script alias to "/" then SCRIPT_NAME becomes "" and 
PATH_INFO becomes /applets/echo/a/b/c

So, with mod_wsgi, you can always generate the full URI path by prepending
SCRIPT_NAME to PATH_INFO for your redirects.

But if you're going gunicorn, you should look at the ProxyPassReverse 
directives that fix up the Location header ( there's also a 
ProxyPassReverse to
Den Mar 17, 2011 kl. 12:58 PM skrev Jérôme Pigeot:

Thanks for this info.

You're right, apache keeps the server name and not the locations.
I displayed the gunicorn wsgi environment, there is 0 key that contains 
the location...

Do you think it's possible to have an apache conf that let me using them??



2011/3/17 Rob Mela <rob@thinkingscreen.com<mailto:rob@thinkingscreen.com>>
I actually find it really useful that Apache strips off PATH_INFO from 
SCRIPT_NAME ( and gives me both ).

This simplifies having different environments of the same Flask apps 
running behind Apache.    The location of the path is used to route to 
different mod_wsgi servers, and Apache strips the rest off into a 
PATH_INFO that I can use in routing in my Flask apps, and this second 
part, the PATH_INFO, stays constant regardless of how I route locations to
mod_wsgi.

So I might request these from a server:

   /staging/stocks/quotes
   /dev/stocks/quotes

... where /staging/ and /dev/ are Apache <Location>s, pointing to 
different mod_wsgi instances, but on the Flask side, my routes are always 
/stocks/quotes.  This is because Apache strips off the Location part of 
the path when creatin PATH_INFO.   This is really convenient.   I still 
have the full path in some other WSGI environment variable -- I think it's
SCRIPT_NAME.

In nginx things work differently, but I've been able to replicate the 
Apache PATH_INFO variable with the following config:

 location ~ ^/staging/applets/stocks(.*)$ {
        set $path_info $1;
        uwsgi_pass   127.0.0.1:10001<http://127.0.0.1:10001/>;
  }

and add this to my uwsgi_params:

uwsgi_param  PATH_INFO          $path_info;

Den Mar 14, 2011 kl. 11:21 AM skrev Jérôme Pigeot:

Thanks for your answer but it doesn't solve the problem.

I tested a similar configuration with nginx in place of apache and it 
works better:
This is clearly a mistake in the apache conf cause the full path 
(/app1/url) is kept in the nginx environment when it passes the request to
the wsgi environement (via PATH_INFO).
This is thanks to 2 variables in the nginx conf :

proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;

I didn't find any way to do the same in the apache one: so the PATH_INFO is '/url'

I will continue searching and giving you my answer if it find it.
Thanks.

Jérôme.


2011/3/14 Abdul Bijur V. A. <bijur@grep-i.com<mailto:bijur@grep-i.com>>

Please set ProxyPreserveHost to On and try again.

Cheers,
Abdul

On Mar 14, 2011 11:26 AM, "Jérôme Pigeot" 
<j.pigeot@gmail.com<mailto:j.pigeot@gmail.com>> wrote:
> Hello,
>
> I'm testing some flask apps deployed with an apache server with mod proxy in
> front, and gunicorn instances to serve them.
> In all apps, all the routes finish with a trailing slash to let an url
> without it to be redirected to the canonical url (like mentions the doc:
> http://flask.pocoo.org/docs/quickstart/#routing)
>
> Here's a part of my apache conf:
>
> <VirtualHost *:80>
> ServerName myserver.mydomain.com<http://myserver.mydomain.com/>
>
> <Proxy *>
> Order deny,allow
> Allow from all
> </Proxy>
>
> ProxyPass /app1/ http://givenserver:givenport/
> ProxyPass /app2/ http://givenserver:givenport/
>
> </VirtualHost>
>
> As you can see apache serves each apps on a given prefix (/app1/,
> /app2/...), the problem comes when flask/werkzeug redirects the urls, it
> doesn't append the prefix to urls :
> Ex: http://myserver.mydomain.com/app1/url will be redirected to
> http://myserver.mydomain.com/url/
> I think that the SERVER_NAME atribute in the configuration is used to handle
> that kind of configuration, but i didn't succeed in using it...
>
> Any help would be very usefull.
> Thanks by advance.
>
> Jérôme.