Pyjo.Server.FastCGI - FastCGI connections of the servers¶
import Pyjo.Server.Daemon
daemon = Pyjo.Server.Daemon.new(listen=['fcgi://127.0.0.1:9000'])
@daemon.unsubscribe('request').on('request')
def request(daemon, tx):
# Request
method = tx.req.method
path = tx.req.url.path
# Response
tx.res.code = 200
tx.res.headers.content_type = 'text/plain'
tx.res.body = f'{method} request for {path}!'.encode()
# Resume transaction
tx.resume()
daemon.run()
Pyjo.Server.FastCGI speaks FastCGI 1.0 on the
connections of the listen locations fcgi:// and fcgi+unix:// of
Pyjo.Server.Daemon, and so of the servers built on it,
Pyjo.Server.Prefork, Pyjo.Server.Hot and
Pyjo.Server.Reload, with the same applications, timeouts, signals and
graceful shutdown as HTTP.
$ ./myapp.py daemon -l fcgi://127.0.0.1:9000
$ ./myapp.py prefork -l fcgi+unix://%2Ftmp%2Fmyapp.sock
A web server in front of the application speaks HTTP to the clients and
FastCGI to the application, which gets the request as the environment of
RFC 3875, as Pyjo.Server.CGI does, but in a process that keeps
running. A connection takes one request at a time, in the role of a
responder, the only one that it supports, and stays open after it when the
web server asks for it with FCGI_KEEP_CONN. The content of the response
can come later, as with Pyjo.Server.Daemon, and goes to the web server
as soon as it is written. WebSockets are not available, as FastCGI has no
protocol for them.
The application can also be started by the web server, which gives it its
listen socket as the file descriptor 0, as Apache with mod_fcgid and
lighttpd do; the command Pyjoyment.Command.fastcgi serves it, and is
detected by Pyjoyment.Commands, so the script of the application
needs no command.
Environment¶
The request is read from the parameters of FastCGI, as the environment of
CGI that Pyjo.Message.Request.Pyjo_Message_Request.parse() takes, with
a few changes for what the web servers send:
A path in
SCRIPT_NAMEwithoutPATH_INFOis the path of the request, as nginx with itsfastcgi_paramsand Caddy send the whole path inSCRIPT_NAME. An application deployed under a path prefix gets it inSCRIPT_NAMEand the rest of the path inPATH_INFO.The bytes of the paths beyond ASCII are percent-encoded, as the path is escaped, as with
Pyjo.Server.WSGI.A request body without
CONTENT_LENGTH, of a chunked request whose framing the web server removed, is read whole before the request is parsed.
Web servers¶
Caddy, with
transport fastcgi: it sends the response to the client with theStatusheader next to its status line.example.com { reverse_proxy 127.0.0.1:9000 { transport fastcgi } }
Apache with
mod_proxy_fcgi:ProxyPass / fcgi://127.0.0.1:9000/ enablereuse=on
Apache with
mod_fcgid, which starts the application:<VirtualHost *:80> ServerName localhost ScriptAlias / /home/sri/myapp/myapp.py/ <Directory /home/sri/myapp> SetHandler fcgid-script Options +ExecCGI Require all granted </Directory> </VirtualHost>
nginx:
location / { include fastcgi_params; fastcgi_pass 127.0.0.1:9000; fastcgi_keep_conn on; }
See also¶
Pyjoyment.Command.fastcgi, Pyjo.Server.Daemon, Pyjoyment,
https://mojolicious.org.
It has no counterpart in Mojolicious; Pyjo.Server.CGI is the
counterpart of Mojo::Server::CGI.
Classes¶
- class Pyjo.Server.FastCGI.Pyjo_Server_FastCGI(daemon: Pyjo_Server_Daemon, id: str)[source]¶
Pyjo.Server.FastCGIis the FastCGI side of a connection ofPyjo.Server.Daemon, which makes it for the connections of its listen locationsfcgi://andfcgi+unix://.- closed() None[source]¶
fcgi.closed()
The connection has been closed, which finishes the transaction of the request in progress.
- id¶
id = fcgi.id
Id of the connection in the event loop of the daemon.