Search code examples
pythonapache.htaccessbottlefastcgi

How do I deal with URL reroutes in Python Bottle and Apache .htaccess?


I am currently trying to create a simple standalone application using Python Bottle.

My entire project is under pytest/, where I have dispatch.fcgi and .htaccess.

dispatch.fcgi:

#!/usr/bin/python
# -*- coding: utf-8 -*-
import bottle
import os
from bottle import route, run, view

@route('<foo:path>')
@view('index')
def pytest(foo = ''):
    return dict(foo=foo)

APP_ROOT = os.path.abspath(os.path.dirname(__file__))
bottle.TEMPLATE_PATH.append(os.path.join(APP_ROOT, 'templates'))
app = bottle.default_app()

if __name__ == '__main__':
    from flup.server.fcgi import WSGIServer
    WSGIServer(app).run()

.htaccess:

DirectoryIndex dispatch.fcgi

The following URLs give me the corresponding values of foo:

url.com/pytest/
> /pytest/

url.com/pytest/dispatch.fcgi
> /pytest/dispatch.fcgi

url.com/pytest/dispatch.fcgi/
> /

url.com/pytest/dispatch.fcgi/foo/bar
> /foo/bar

url.com/pytest/dispatch.fcgi/pytest/
> /pytest/

How can I make the URLs uniform? Should I deal with the rerouting with the .htaccess file or within the Python code? What would be considered most pythonic, or best practices?

I am running Python 2.6.6, Bottle 0.11.6, Flup 1.0.2, and Apache 2.2.24. I would also like to point out that I'm using shared hosting, and mod_wsgi is out of the question (if that makes a difference).

EDIT

This is what I expect to see:

url.com/pytest/
> <redirect to url.com/pytest/dispatch.fcgi>

url.com/pytest/dispatch.fcgi
> <empty string>

url.com/pytest/dispatch.fcgi/
> /

url.com/pytest/dispatch.fcgi/foo/bar
> /foo/bar

url.com/pytest/dispatch.fcgi/pytest/
> /pytest/

If there is a more efficient way of tackling this problem, please let me know.


Solution

  • Bottle seems to be confused because it expects a trailing slash, followed by parameters. For that reason I changed my .htaccess file to read like this:

    DirectoryIndex dispatch.fcgi/
    

    Another option would be to have all errors fall back onto the dispatch script. That can be done with mod_rewrite:

    <IfModule mod_rewrite.c>
    Options -MultiViews
    
    # rewrite for current folder
    RewriteEngine On
    RewriteBase /pytest
    
    # redirect to front controller
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^ dispatch.fcgi/ [R=301,QSA,L]
    </IfModule>
    

    or FallbackResource:

    FallbackResource /pytest/dispatch.fcgi/