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.
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.
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. >
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.
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. >> > > >
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.