# fcgi module

## Synopsis

The `fcgi` module builds upon the classes defined in the `cgi` module to provide an implementation of the FastCGI protocol. Code originally written with the CGI protocol in mind can be used unchanged with the FastCGI protocol by using this module. The module implements the entire FastCGI specification version 1.0, including multiple simultaneous connections per process and multiple simultaneous requests per connection. Requests are executed using Python's threading facilities, although it can be configured to run without using threading.

## Usage

See the documentation for the `cgi` module for information on how to use the CGI abstraction layer. The only difference with the `fcgi` module is that instead of using `cgi.Request` to call your handler code, you use `fcgi.Server`. In addition, if you are willing to tie your code in to using the FastCGI protocol, you can make use of its facilities for providing authorization and filter code.

Example:

`import jon.cgi as cgi
import jon.fcgi as fcgi
class Handler(cgi.Handler):
def process(self, req):
req.set_header("Content-Type", "text/plain")
req.write("Hello, world!\n")
fcgi.Server({fcgi.FCGI_RESPONDER: Handler}).run()`

## class: Server

`Server` provides the 'main loop' required by a FastCGI application. It accepts connections from the web server and uses instances of `cgi.Handler` subclasses to handle the requests.

### Public Methods

#### `__init__(self, handler_types, max_requests=0, params=None, request_type=Request, threading_level=1)`

`handler_types`: map from FastCGI request types to subclasses of `cgi.Handler`
`max_requests`: integer
`params`: map from strings to strings
`request_type`: subclass of `Request`
`threading_level`: integer

Create new `Server` instance. Instances of the appropriate type as indicated by `handler_types` are created to handle the requests. The valid keys for the `handler_types` map are `fcgi.FCGI_RESPONDER`, `fcgi.FCGI_AUTHORIZER` and `fcgi.FCGI_FILTER`. These types are described in the FastCGI specification. The usual one to use (that corresponds to the usual function of a CGI application) is `fcgi.FCGI_RESPONDER`.

Normally, once started, the server will loop forever accepting connections. However, if you specify a non-zero value for `max_requests` then it will exit after that many requests have been initiated. Note that when control returns to the caller, requests that have been initiated but not yet completed may still be in progress in other threads.

You can alter the values that are returned to the web server if it sends a `FCGI_GET_VALUES` request by using the optional `params` parameter, which is a map from requested variable names to their value. The following default values are used unless explicitly specified:

`threading_level` | `FCGI_MAX_CONNS` | `FCGI_MAX_REQS` | `FCGI_MPXS_CONNS`
--- | --- | --- | ---
`0` | `1` | `1` | `0`
`1` | `10` | `10` | `0`
`2` | `10` | `10` | `1`

You can alter the class used to provide request information using `request_type`. The class provided must always be a subclass of `fcgi.Request`. For instance, you might wish to use `fcgi.GZipRequest` instead.

By default, `fcgi` uses threading to handle requests. It creates one thread per connection. However, on some platforms threading is either not available, or the operating system support for it is buggy. You can alter the use of threading with the `threading_level` parameter. The valid `threading_level` values are:

`threading_level` | Meaning
--- | ---
`0` | Threading is not used at all. Only one connection can be handled at once, and multiple requests cannot be multiplexed onto that connection, so only one request can be handled at once.
`1` | One thread is created per connection. Multiple connections can be handled simultaneously, but multiple requests cannot be multiplexed onto a connection.
`2` | One thread is created per connection, and one thread is created per request. Multiple connections can be handled simultaneously, and multiple requests can be multiplexed onto a connection.

The default `threading_level` is `1`. If your web server supports multiplexing of connections then you may wish to use level `2`, however Apache mod_fastcgi does not support multiplexing and the `fcgi` module makes less efficient use of threads if multiplexing is not used so it is not the default.

If threading is requested (i.e. a `threading_level` greater than zero is specified, or `threading_level` is left unspecified), but the Python `thread` module cannot be imported (i.e. threading support is not available) then `fcgi` will automatically downgrade to `threading_level = 0`.

#### `exit(self):`

This method will cause the `Server.run()` loop to exit. This can be used to exit the FastCGI application.

#### `run(self)`

The 'main loop' for the FastCGI application. Listens for connections and handles them appropriately.

If the program does not appear to be running in a FastCGI environment (i.e. `stdin` is not a socket) then this method will automatically fall back to the CGI protocol and attempt to execute the `fcgi.FCGI_RESPONDER` handler using `cgi.CGIRequest`. This means that you can write your applications using the `fcgi` module and you can switch between using FastCGI and ordinary CGI simply by changing your web server configuration, with no changes required to your code.

Example:

`fcgi.Server({fcgi.FCGI_RESPONDER: Handler}).run()`

## class: Request(cgi.Request)

`Request` is a subclass of `cgi.Request` that provides the same public interface but uses the FastCGI protocol behind the scenes.

### Public Instance Variables

#### `fastcgi_data`

A file-like object that provides the `FASTCGI_DATA` stream as provided by the FastCGI protocol. This is not used by ordinary CGI applications, but may be used by `FCGI_FILTER` code.

## class: GZipRequest(GZipMixIn, Request)

For convenience, this class provides the standard `Request` class with the `cgi.GZipMixIn` already mixed in. To use this class, specify it as the value of the `request_type` parameter when creating your `Server` object.

Example:

`fcgi.Server({fcgi.FCGI_RESPONDER: Handler}, request_type=fcgi.GZipRequest).run()`

$Id: fcgi.html,v 0416d65875b7 2014/03/05 17:37:06 jon $