Search code examples
apache.htaccessfastcgi

How can I run a FastCGI script in root url (/ - without path)?


I have created a simple application in Python/Flask, which has a home url (www.site.com/). I have acquired a HostGator shared account to host it, so I only have access to .htaccess, but no other Apache config files.

I setup a FastCGI script to run the application (following these instructions), but they require the URL to have a /index.fcgi or any other path. Can I make the root path (/) be served directly by the FastCGI script? Also, folders like /static/ and /favicon.ico should be served by Apache instead.

What I have now as .htaccess is:

AddHandler fcgid-script .fcgi
DirectoryIndex index.fcgi

RewriteEngine On
RewriteBase /
RewriteRule ^index.fcgi$ - [R=302,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.fcgi/$1 [R=302,L]

I'm not sure, but I think the Apache version is 2.2.


Solution

  • FYI: You can check apache version with

    apachectl -V  # or /<pathwhereapachelives>/apachectl -V
    

    For the fastCGI setup, see if this link helps. http://redconservatory.com/blog/getting-django-up-and-running-with-hostgator-part-2-enable-fastcgi/

    Basically, if you want to run the script in /, you can use mod_rewrite to serve static files directly (as /media in the example below), and every other path being served by the WSGI script:

    AddHandler fcgid-script .fcgi
    Options +FollowSymLinks
    RewriteEngine On
    
    RewriteRule (media/.*)$ - [L]
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^(.*)$ index.fcgi/$1 [QSA,L]
    

    Note that, as you are using Flask, you will have to override the SCRIPT_NAME request variable (as described here), otherwise the result of url_for() will be a string starting in /index.fcgi/...:

    #!/usr/bin/python
    #: optional path to your local python site-packages folder
    import sys
    sys.path.insert(0, '<your_local_path>/lib/python2.6/site-packages')
    
    from flup.server.fcgi import WSGIServer
    from yourapplication import app
    
    class ScriptNameStripper(object):
       def __init__(self, app):
           self.app = app
    
       def __call__(self, environ, start_response):
           environ['SCRIPT_NAME'] = ''
           return self.app(environ, start_response)
    
    app = ScriptNameStripper(app)
    
    if __name__ == '__main__':
        WSGIServer(app).run()