Multiple installs of Django - How to configure transparent multiplex through the webserver (Lighttpd)?

This question flows from the answer to:How does one set up multiple accounts with separate databases for Django on one server?

I haven't seen anything like this on Google or elsewhere (perhaps I have the wrong vocabulary), so I think input could be a valuable addition to the internet discourse.

How could one configure a server likeso:

  • One installation of Lighttpd
  • Multiple Django projects running as FastCGI
  • The Django projects may be added/removed at will, and ought not to require restarting the webserver
  • Transparent redirection of all requests/responses to a particular Django installation depending on the current user

I.e. Given Django projects (with corresponding FastCGI socket):

  • Bob (/tmp/bob.fcgi)
  • Sue (/tmp/sue.fcgi)
  • Joe (/tmp/joe.fcgi)

The Django projects being started with a (oversimplified) script likeso:

#!/bin/sh
NAME=bob

SOCKET=/tmp/$NAME.fcgi

PROTO=fcgi
DAEMON=true

/django_projects/$NAME/manage.py runfcgi protocol=$PROTO socket=$SOCKET
  daemonize=$DAEMON

I want traffic to http://www.example.com/ to direct the request to the correct Django application depending on the user that is logged in.

In other words, http://www.example.com should come "be" /tmp/bob.fcgi if bob is logged in, /tmp/joe.fcgi if joe is logged in, /tmp/sue.fcgi if sue is logged in. If no-one is logged in, it should redirect to a login page.

I've contemplated a demultiplexing "plexer" FastCGI script with the following algorithm:

  1. If the cookie $PLEX is set, pipe request to /tmp/$PLEX.fcgi

  2. Otherwise redirect to login page (which sets the cookie PLEX based on a many-to-one mapping of Username => PLEX)

Of course as a matter of security $PLEX should be taint checked, and $PLEX shouldn't give rise to any presumption of trust.

A Lighttpd configuration would be likeso (though Apache, Nginx, etc. could be used just as easily):

fastcgi.server = ( "plexer.fcgi" =>
                           ( "localhost" =>
                             (   
                               "socket" => "/tmp/plexer.fcgi",
                               "check-local" => "disable"
                             )
                           )   
                 )

Input and thoughts, helpful links, and to know how to properly implement the FastCGI plexer would all be appreciated.

Thank you.

Answers


Here's roughly how I solved this:

In lighttpd.conf

$SERVER["socket"] == "localhost:81" {
  include_shell "/opt/bin/lighttpd_conf.py"
}

And corresponding lighttpd_conf.py:

#!/usr/bin/python
import fileinput
ACCOUNT_LIST_FILE = "/opt/servers/account_list.txt"

for user in fileinput.input(ACCOUNT_LIST_FILE):
    print """
	$HTTP[\"url\"] =~ \"^/%s/\" {
		scgi.server = ( \"/\" => 
			(
			(
				\"socket\" => \"/tmp/user-socket-%s.scgi\",
				\"check-local\" => \"disable\",
			)
			)
		)
	}
    """ % (user, user)

Where ACCOUNT_LIST_FILE contains a number of accounts, e.g.

abc1
abc2
abc3

The server will map http://example.com/abc1 to /tmp/user-socket-abc1.scgi, where presumably a Django instance for user abc1 is talking SCGI.

One must obviously perform some sort of taint checking on the names of accounts (I generate these).


Need Your Help

TIMEZONE_CHANGED intent being received every few seconds

android android-intent timezone broadcastreceiver alarmmanager

I use a BroadcastReceiver with TIMEZONE_CHANGED action to reset alarms using AlarmManager just to make sure that the alarm runs exactly at the set time, not a few hours earlier or later, depending ...

param is missing or the value is empty: contacts

ruby-on-rails ruby actionmailer params form-for

I'm trying to submit my contact form which is supposed to send an email. Every time I click the submit button I get this error: "param is missing or the value is empty: contacts".

About UNIX Resources Network

Original, collect and organize Developers related documents, information and materials, contains jQuery, Html, CSS, MySQL, .NET, ASP.NET, SQL, objective-c, iPhone, Ruby on Rails, C, SQL Server, Ruby, Arrays, Regex, ASP.NET MVC, WPF, XML, Ajax, DataBase, and so on.