Not Logged In

gevent-fastcgi 1.0.1

FastCGI server implementation using gevent coroutine-based networking library.
No need to monkeypatch and slow down your favourite FastCGI server in order to make it “green”.

Provides simple request handler API to allow for custom request handlers.
Comes with two WSGI request hadler implementations – one using standard wsgiref.handlers.BasicCGIHandler and another using original request hadler.

Gevent-fastcgi defines three paste.server_runner entry points. Each of them will run FastCGIServer with different request
handler implementation:

wsgi

gevent_fastcgi.wsgi.WSGIRequestHandler will be used to handle requests.
Application is expected to be a WSGI-application.

wsgiref

gevent_fastcgi.wsgi.WSGIRefRequestHandler which uses standard
wsgiref.handlers will be used to handle requests.
Application is expected to be a WSGI-application.

fastcgi

Application is expected to implement gevent_fastcgi.interfaces.IRequestHandler
interface. It should use request.stdin to receive request body and
request.stdout and/or request.stderr to send response back to Web-server.

Use it as following:

[server:main]use=egg:gevent_fastcgi#wsgihost=127.0.0.1port=4000# UNIX domain socket can be used by specifying path instead of host and port# socket = /path/to/socket# socket_mode = 0660# The following values are used in reply to Web-server on `FCGI_GET_VALUES` request## Maximum allowed simulteneous connections, i.e. the size of greenlet pool# used for connection handlers.max_conns=1024max_reqs=1024# Fork `num_workers` child processes after socket is bound.# Must be equal or greate than 1. No children will be forked# if set to 1 or not specifiednum_workers=8# Call specified functions of gevent.monkey module before starting the servergevent.monkey.patch_thread=yesgevent.monkey.patch_time=nogevent.monkey.patch_socket=ongevent.monkey.patch_ssl=off# orgevent.monkey.patch_all=yes

Add gevent_fastcgi.adapters.django to INSTALLED_APPS of settings.py then run
the following command (replace <address> with <host>:<port> or <unix-socket>):

$ python manage.py run_gevent_fastcgi <address>

Custom request handlers

Starting from version 0.1.16dev It is possible to use custom request handler with gevent_fastcgi.server.FastCGIServer. Such a handler should implement
gevent_fastcgi.interfaces.IRequestHandler interface and basically is just a callable that accepts single positional argument request. gevent_fastcgi.wsgi module contains two implementations of IRequestHandler.

Request handler is run in separate greenlet. Request argument passed to request
handler callable has the following attributes:

File-like object that should be used by request handler to send response (including response headers)

stderr

File-like object that can be used to send error information back to Web-server

Following is sample of custom request handler implementation:

importosfromzope.interfaceimportimplementsfromgeventimportspawn,joinallfromgevent_subprocessimportPopen,PIPEfromgevent_fastcgi.interfacesimportIRequestHandler# WARNING!!!# CGIRequestHandler is for demonstration purposes only!!!# IT MUST NOT BE USED IN PRODUCTION ENVIRONMENT!!!classCGIRequestHandler(object):implements(IRequestHandler)def__init__(self,root,buf_size=1024):self.root=os.path.abspath(root)self.buf_size=buf_sizedef__call__(self,request):script_name=request.environ['SCRIPT_NAME']ifscript_name.startswith('/'):script_name=script_name[1:]script_filename=os.path.join(self.root,script_name)ifscript_filename.startswith(self.root)andos.path.isfile(script_filename)andos.access(script_filename,os.X_OK):proc=Popen(script_filename,stdin=PIPE,stdout=PIPE,stderr=PIPE)joinall((spawn(self.copy_stream,src,dest)forsrc,destin[(request.stdin,proc.stdin),(proc.stdout,request.stdout),(proc.stderr,request.stderr),]))else:# report an errorrequest.stderr.write('Cannot locate or execute CGI-script %s'%script_filename)# and send a replyrequest.stdout.write('\r\n'.join(('Status: 404 Not Found','Content-Type: text/plain','','No resource can be found for URI %s'%request.environ['REQUEST_URI'],)))defcopy_stream(self,src,dest):buf_size=self.buf_sizeread=src.readwrite=dest.writewhileTrue:buf=read(buf_size)ifnotbuf:breakwrite(buf)if__name__=='__main__':fromgevent_fastcgi.serverimportFastCGIServeraddress=('127.0.0.1',8000)handler=CGIRequestHandler('/var/www/cgi-bin')server=FastCGIServer(address,handler)server.serve_forever()

Contributors

This project could not be where it is now without help of the following great people: