Table of Contents



ashd-wsgi - WSGI adapter for ashd(7)




The ashd-wsgi handler translates ashd(7) requests to WSGI requests, and passes them to a specified Python handler module. The precise Python convention for doing so is described in the PROTOCOL section, below.

ashd-wsgi is a persistent handler, as defined in ashd(7). It uses multithreaded dispatching in a single Python interpreter, which means that WSGI applications that use it need to be thread-safe, but that they can also share all Python data structures and global variables between requests. More precisely, ashd-wsgi implements a couple of slightly different ways to handle requests and threads, which can be configured using the -t option, as described in the REQUEST HANDLING section, below.

The Python module that ashd-wsgi comes with also contains a standard handler module, ashd.wsgidir, which serves individual WSGI applications directly from the files in which they reside and as such makes this program useful as a dirplex(1) handler. Please see its Python documentation for further details.

ashd-wsgi requires the ashd.proto and ashd.util modules, which are only available for CPython. If you want to use some other Python implementation instead, you may want to use the scgi-wsgi(1) program instead, along with callscgi(1).


Print a brief help message to standard output and exit.
Use the convention used by Apache’s mod_wsgi module to find the WSGI application object. See the PROTOCOL section, below, for details.
By default, ashd-wsgi sets up the Python logging with a logging format and for logging to standard error. The -L option suppresses that behavior, so that any handler module may set up logging itself.
Prepend MODPATH to Python’s sys.path; can be given multiple times. Note that the working directory of ashd-wsgi is not on Python’s module path by default, so if you want to use a module in that directory, you will need to specify "-p .".
Specify the way ashd-wsgi handles requests. See below, under REQUEST HANDLING.
If the PDM library is installed on the system, create a listening socket for connecting PDM clients according to PDM-SPEC.


When starting, ashd-wsgi will attempt to import the module named by HANDLER-MODULE, look for an object named wmain in that module, call that object passing the ARGS (as Python strings) as positional parameters, and use the returned object as the WSGI application object. If the -A option was specified, it will look for an object named application instead of wmain, and use that object directly as the WSGI application object.

When calling the WSGI application, a new thread is started for each request, in which the WSGI application object is called (but see below, under REQUEST HANDLING, for details). All requests run in the same interpreter, so it is guaranteed that data structures and global variables can be shared between requests.

The WSGI environment is the standard CGI environment, including the SCRIPT_FILENAME variable whenever the X-Ash-File header was included in the request.


ashd-wsgi can be configured to handle requests in various ways, using the -t command-line option. The argument to the -t option takes the form HANDLER[:PAR[=VAL][(,PAR[=VAL])…]], in order to specify the handler model, along with parameters to the same (using the same syntax as the port specifications of htparser(1)). The HANDLER can be any of the following:

The free handler, which is the default, starts a new thread for every incoming request, which runs the whole request in its entirety, from running the WSGI handler function to sending the contents of the response iterator. Optionally, MAX-THREADS may be specified to an integer, in which case no more than that many request-handler threads will be allowed to run at any one time (by default, any number of threads are allowed to run, without limit). If further requests come in while MAX-THREADS handlers are running, the request dispatch thread itself will block until one exits, making new requests queue up in the socket over which they arrive, eventually filling up its buffers if no threads exit, in turn making the parent handler either block or receive EAGAIN errors. Also, if MAX-THREADS is specified, TIMEOUT may also be specified, to tell the dispatcher thread to never block more than so many seconds for a handler thread to exit. If it is forced to wait longer than TIMEOUT seconds, it will assume the whole process is somehow foobar and will abort(3).
The rplex handler starts a new thread for every incoming request, but unlike the free handler, only the WSGI handler function runs in that thread. Whenever any such thread, then, returns its response iterator, all such iterators will be passed to a single independent thread which sends their contents to the clients, multiplexing between them whenever their respective clients are ready to receive data. Like the free handler, a MAX-THREADS argument may be given to specify how many handler threads are allowed to run at the same time. The main advantage, compared to the free handler, is that the rplex handler allows an arbitrary number of response iterators to run simultaneously without tying up handler threads, therefore not counting towards MAX-THREADS, which may be necessary for applications handling large files. However, it must be noted that no response iterators in the application may block on returning data, since that would also block all other running responses. Also, the rplex handler does not support the write function returned by start_request, according to the WSGI specification.
The single handler starts no threads at all, running all received requests directly in the main dispatch thread. It is probably not good for much except as the simplest possible example of a request handling model.


The following dirplex(1) configuration can be used for serving WSGI modules directly from the filesystem.

child wsgidir
  exec ashd-wsgi ashd.wsgidir
  filename *.wsgi
  xset python-handler chain
  handler wsgidir

Since ashd-wsgi is a persistent handler, it can be used directly as a root handler for htparser(1). For instance, if the directory /srv/www/foo contains a file, which declares a standard WSGI application object, it can be served with the following command:

htparser plain:port=8080 -- ashd-wsgi -Ap /srv/www/foo wsgi


Fredrik Tolf <>


scgi-wsgi(1), ashd(7),