What are CGI and fast CGI

This is part of the Semicolon&Sons Code Diary - consisting of lessons learned on the job. You're in the web-development category.

Last Updated: 2024-04-25

CGI stands for (Fast) Common Gateway Interface

Purpose

These are protocols used to run a server-side script (most commonly in PHP) when a HTTP request comes in.

Arguably today, it it doesn't offer much extra over just using HTTP to communicate.

API

Web servers may support connecting to externally-managed daemons speaking the FastCGI protocol on a TCP/IP or local Unix socket.

A FastCGI process is launched by a web server like a CGI binary; fd=0 (STDIN) is initialised with a bi-directional communication channel, fd=1 and fd=2 (STDOUT/STDERR) are closed; the program then receives requests on fd=0, which it accept()s and subsequently processes

A simple request taken from the FastCGI specifications is in the form: { TYPE, REQUESTID, CONTENTDATA }

Here's a very simple example in Ruby of a client-side use of FastCGI

require "fcgi"

FCGI.each {|request|
  out = request.out
  out.print "Content-Type: text/plain\r\n"
  out.print "\r\n"
  out.print Time.now.to_s
  request.finish
}

Difference between CGI AND FastCGI

The problem FastCGI was designed to solve was that CGI wasted resources spawning a new process every time a web service resource behind the CGI was accessed. Process creation sounds negligible, but often these CGI binaries were things like perl scripts, which meant that every single time a request was to be handled a fully-blown script interpreter was launched, the script was compiled and run - or interpreted - and then the interpreter instance was killed off. This imposes a natural limit on how many simultaneous connections a web server can process.

FastCGI's solution to this is to allow the interpreter - or proper program - to remain in memory, waiting for an incoming network connection to handle. The solution is quite sound, especially compared to the other typical solution at the time, which was to use an extension API provided by the web server you're using... With old CGI scripts designed as a plugin to the Apache server, their poor functioning could nuke apache.

Alternative ways of doing things

mod_php - runs PHP as an Apache module. I.e. PHP code is run under the Apache process, with its permissions, config, etc.

PHP example

PHP-FPM - PHP's fast CGI implementation. Runs a standalone FastCGI server. Apache connects to the server using Apache's module, usually mod_fcgid or mod_fastcgi. By contrast with mod_php, this approach allows you to use PHP's config, permissions, etc. (instead of being stuck with Apache's).

Also allows for there to be a pool of PHP servers and for them to even be on different machines to the web server.

Some features of PHP-FPM seem to be a Frankenstein job:

Ruby example?

There used to be Phusion Passenger and all, but my impression is that thanks to puma, WEBrick, etc. people now just use a Ruby server as a replacement for CGI and instead communicate over unix sockets or HTTP.

References