Apr 17

web2py behind apache with mod_wsgi part II: mod_rewrite rules

Tag: Computer World,Howtos,Software Liberojdoe @ 2:48 pm

Ok, in the previous post I’ve shown a way to run web2py behind apache  using mod_wsgi.

The main “problem” still to be addressed is: URIs. Assume you have 3 website which implies (in the common case) 3 web2py application,

  1. www.primo.it with the we2bpy app called primo
  2. www.secondo.it , appname is secondo
  3. www.terzo.it, appname is terzo.

(ok, maybe I lack of fantasy … )

Now we ended up having a vhost with

ServerName web2py.localhost

so all of our 3 applications are at

web2py.localhost/primo/default/index, web2py.localhost/secondo/default/index, web2py.localhost/terzo/default/index. It should work, but it’s not what we want.

The simplest thing here is to add

ServerAlias www.primo.it www.secondo.it www.terzo.it

to the vhost conf file. This works, but has a couple of disadvantages:

  1. application name is still in the url (i.e. www.primo.it/primo/default/index)
  2. secondo and terzo are available from primo’s url and vice-versa (www.primo.it/secondo/default/index shows secondo application)

Here enters mod_rewrite. Leave the ServerAlias in place, as they are needed.

Disclaimer I’m **NOT** a mod_rewrite guru -as you’ll see-, and I really think that there are better ways to accomplish this task: suggestions are welcome ^^

Starting with www.primo.it, add this at the beginning of the vhost file, just after the DocumentRoot directive:

RewriteEngine On

RewriteCond %{HTTP_HOST} =www.primo.it [NC,OR]
RewriteCond %{HTTP_HOST} =primo.it [NC]
RewriteRule /primo/(.*) /$1 [N]

RewriteCond %{HTTP_HOST} =www.primo.it [NC,OR]
RewriteCond %{HTTP_HOST} =primo.it [NC]
RewriteRule ^/(.*) /primo/$1 [PT,L]

The first “block” is needed to fix “links” in web2py applications, so that if you are using URL() function it continues to work. The problem it addresses is that we don’t want application name in URLs buth URL() keeps adding it. So we remove it;  the [N] flag after  the first RewriteRule means “restart from the beginning after applying” (the downside is that this is an external redirect :( )

The second “block” is needed to do the actual work: it transparently add the app name to the request, but the url in user browser remains without. So one user accessing www.primo.it/default/index arrives to wsgi as if he/she was calling www.primo.it/primo/default/index (and the user still have www.primo.it/default/index) in his/her location bar. The [L] flags means “last” (i.e. stop processing rewrites) and [PT] means “jump directly to the next alias handler”, which is the WSGIScriptAlias defined in previous posts.

Repeat this two blocks (RewriteEngine On is needed only the first time) for every application you have (you can do includes in separate files if you wish)  and you end up having

  • www.primo.it that redirect to www.primo.it/default/index.
  • www.primo.it/secondo/default/index still working
  • web2py.localhost/primo/default/index still working
  • https (i.e. management) only on web2py.localhost. If you want https support for primo.it you should add the rewrite rules event to the https section, (or -better- include two times the same file)

Hope this helps… and if you have better options or ideas write a comment :)

Last thing about the RewriteCond: yes, I already know that it can be done with a regex instead of using the =www.primo.it AND rewriting the condition without www. but I like this way far more as it’s simpler and much more understandable.

  • seth

    Thanks so much for the second writeup! Super useful, the only snag I’ve hit is in the apache virtual hosts file doesn’t resolve to the application (/appname/index), it always always goes to the default application (/default/index). As I don’t have much Apache config experience, I may be missing something obvious. My config file is pretty much identical to yours, any chance we could get a peek at the new config file which includes multiple apps?

    Your assistance has been greatly appreciated :)

    Cheers.
    -Seth

  • http://www.pctuner.net jdoe

    Well, apache resolv http://www.domain.tld/ to http://www.domain.tld/appname/, then it’s up to web2py and it resolv /appname/ to /appname/default/index.
    If you want a different default route you should check the routes_in parameter of web2py.
    Here there’s some doc about it http://www.web2py.com/AlterEgo/default/show/42

  • http://jon.is.emotionull.com Jon

    Thanks for this nice tutorial! I tried the .htaccess but I got a 500 error.
    Any ideas?

  • http://www.pctuner.net jdoe

    watch the apache error_log, you’ll find an explanation of the problem. Can be permission-related, some misconfiguration or something not considered when I was writing this tutorial :)
    and, yes, set the RewriteLog and watch what’s happening there too..
    http://httpd.apache.org/docs/2.2/mod/mod_rewrite.html#rewritelog

  • http://jon.is.emotionull.com Jon

    Thanks for your reply! I am getting:
    RewriteCond: bad flag delimiters

  • http://www.pctuner.net jdoe

    can you post the rewrite rule?

  • http://jon.is.emotionull.com Jon

    RewriteEngine On

    RewriteCond %{HTTP_HOST} =www.mydomain.com [NC, OR]
    RewriteCond %{HTTP_HOST} =mydomain.com [NC]
    RewriteRule /mydomain/(.*) /$1 [N]

    RewriteCond %{HTTP_HOST} =www.mydomain.com [NC, OR]
    RewriteCond %{HTTP_HOST} =mydomain.com [NC]
    RewriteRule ^/(.*) /mydomain/$1 [PT,L]

    RewriteRule ^dispatch\.fcgi/ – [L]
    RewriteRule ^(.*)$ dispatch.fcgi/$1 [L]

    This is the whole .htaccess

  • http://www.pctuner.net jdoe

    seems ok, but are you sure RewriteRule ^dispatch\.fcgi/ – [L] is correct?

  • http://jon.is.emotionull.com Jon

    RewriteRule ^dispatch\.fcgi/ – [L]
    seems to work
    but I get ‘RewriteCond: bad flag delimiters’ from the RewriteCond

  • http://www.pctuner.net jdoe

    could be that you have a non-unix line feed. If the server is linux and you use windows please use a text-editor that permit you to set the line feeds type.
    Or could be a space left in the rewrite cond.
    Sorry, just guessing here… try google for the error and see what happens.

  • http://jon.is.emotionull.com Jon

    Thanks a lot for your help. I am writing it on linux. I am googling and I’ve even added a question at stackoverflow and serverfault.com. It’s definitely something wrong with my spaces :)
    Thank again!

  • http://jon.is.emotionull.com Jon

    After a lot of fiddling around and posting around the internet:
    http://stackoverflow.com/questions/1454384/htaccess-transparently-adding-a-name-to-the-request
    http://serverfault.com/questions/67615/htaccess-transparently-adding-a-name-to-the-request

    I think that the problem is the added space between parameters (like [NC, OR]).
    Now, it doesn’t throw an error but when I am hitting the domain, it redirects to http://mydomain.com/welcome/default/index (is it ignoring it?)

  • http://www.pctuner.net jdoe

    sorry, I didn’t notice the space between flags :)

    looking at your .htaccess you are using PT flag but you don’t have a Alias/ScriptAlias/WSGIScriptAlias so, yes, I think it’s ignoring the rewrite rule
    Look here for more info on PT flag: http://httpd.apache.org/docs/2.2/mod/mod_rewrite.html#rewriterule

  • http://jon.is.emotionull.com Jon

    So, what has to be added to your code to make it ok? I don’t think removing [PT] solves the problem :)

    RewriteEngine On

    RewriteCond %{HTTP_HOST} =www.primo.it [NC,OR]
    RewriteCond %{HTTP_HOST} =primo.it [NC]
    RewriteRule /primo/(.*) /$1 [N]

    RewriteCond %{HTTP_HOST} =www.primo.it [NC,OR]
    RewriteCond %{HTTP_HOST} =primo.it [NC]
    RewriteRule ^/(.*) /primo/$1 [PT,L]

  • http://www.pctuner.net jdoe

    look at the previous post http://jdoe.asidev.com/2009/02/26/configure-web2py-to-run-behind-apache-with-wsgi-mod_wsgi/
    You need a WSGIScriptAlias or ScriptAlias for this to work

  • http://jon.is.emotionull.com Jon

    But what happens when you are on a shared hosting environment? (I am trying for the past two days to write a full tutorial on how to install and setup web2py on shared hosting accounts. IF I ever gather all the info, you’ll get a HUGE HUGE HUGE thanks-and a link of course).

    Thanks again for all the help (I can’t believe it’s THAT difficult to run web2py on shared account)

  • http://www.pctuner.net jdoe

    uhm, maybe this email can be of help? are you using fcgi or wsgi? http...@googlegroups.com/msg00499.html

  • Haros

    Thank you VERY much for this guide! It really helped!

    *a minor fix*
    [NC, OR] must be [NC,OR] (without the space) otherwise you get a “bad flag delimiters” error.

  • http://www.pctuner.net jdoe

    Thanks Haro, I’ve updated the post.

  • Haros

    Hey jdoe.
    Can we also exclude the application name from the url? Because when you start visiting the links in a site it reveals the application’s name. For example let’s say we have a “links” category. When we visit it, it reveals http://www.primo.it/primo/links. It would be better if we could just have wwww.primo.it/links

blog comments powered by Disqus