Posted :
CGI stands for the common gateway interface . It is a way , for a web server to run external applications .
Each application or script or whatever , will have a process created and destroyed for each request . The web server is in charge of creating and destroying the processes , and is the owner of the process .
Messages are transferred from the web server , to the application , using environment variables . nginx does not actually support CGI .
FastCGI stands for the fast common gateway interface .
The basic concept to get , is that it is not the server who is responsible for creating , or owning the external application process . The external application is created once , is a long running process , is supposed to handle multiple requests , as for example in having a loop , which handles all the received requests .
Messages are also transferred using environment variables , through for example a pipe , or a unix socket , or TCP/IP .
This model of work allows caching , for example of database connections , and might help in the prevention of a denial of service , which might occur in the case of CGI .
To
use
fastCGI with nginx , two
software libraries can be used ,
fcgiwrap or the FastCGI Development Kit .
fcgiwrap is simply a
simple server ,
which acts as a wrapper
for CGI using fastCGI .
This enables nginx to
run any script or application , as if by
using the CGI specification , which is more
correctly put , as having CGI wrapped using fastCGI .
Install nginx , and fcgiwrap ,
using :
root$ pkg install nginx-full fcgiwrap # install nginx and fcgiwrap on FreeBSD . root$ apt-get install nginx-full fcgiwrap # install nginx and fcgiwrap on Debian .
Configure nginx , to add a location block , to the default server block , as in :
# For FreeBSD
root$ nano /usr/local/etc/nginx/nginx.conf
# ctrl-w to search for : server
# and add a location block under
# server as in :
server {
listen 80;
server_name localhost;
...
# add this location block
location /cgi/ {
gzip off;
root /home/difyel/;
fastcgi_pass unix:/var/run/fcgiwrap/fcgiwrap.sock;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
...
# For Debian
root$ nano /etc/nginx/sites-enabled/default
# ctrl-w to search for server {
# Add under server the content
server {
listen 80 default_server;
listen [::]:80 default_server;
...
# add this location block
location /cgi/ {
gzip off;
root /home/difyel/;
fastcgi_pass unix:/var/run/fcgiwrap.socket;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
...
# Finally for Debian , and FreeBSD
# Create a directory named cgi under
# the location you specified in the
# root directive , for example as
# a regular user , you can issue :
# mkdir -p /home/difyel/cgi/
# You can test the configuration for
# correctness using nginx -t
# for debian only , restart nginx
# using service nginx restart
For freeBSD additionally , fcgiwrap
and nginx
must be configured as follows :
root$ nano /etc/rc.conf # edit /etc/rc.conf , and add the following nginx_enable="yes" fcgiwrap_enable="yes" fcgiwrap_socket_owner="www" fcgiwrap_flags="-f -c 2" # -c 2 means prefork 2 fcgiwrap # processes , and -f means # redirect errors to web server # logs . # ctrl-x to exit and save when prompted root$ service nginx start # start the nginx service root$ service fcgiwrap start # start the fcgiwrap service
Test the programming languages
that you want , by placing your executables or scripts , in
the cgi folder which was just created , and visiting
the address localhost/cgi/your-program .
# example hello.lsp
# sbcl must be installed using
# debian : apt-get install sbcl
# freeBSD : pkg install sbcl
# The script must be made executable
# as in chmod +x hello.lsp
# note that the first line for debian
# must be #!/usr/bin/sbcl --script
#!/usr/local/bin/sbcl --script
(format t "Content-Type:text/html~%~%")
(format t "~a" (sb-unix::posix-getenv "HTTP_USER_AGENT"))
# example hello.bash
# For freeBSD bash must be
# installed , or another shell
# must be specified .
# Bash can be installed under
# freeBSD by using :
# pkg install bash
# The script must be made
# executable , as in :
# chmod+x hello.bash
# note that for debian , the
# first line of the script ,
# must be #!/usr/bin/bash
#!/usr/local/bin/bash
printf 'Content-type: text/html\n\n'
echo $HTTP_USER_AGENT
# example hello.out
# For c , just write a hello.c
# program and compile it , for example
# using gcc -o hello.out hello.c
#include <stdio.h>
#include <stdlib.h>
int
main
(void ) {
printf ("Content-type: text/html\n\n" );
printf ("%s\n" , getenv("HTTP_USER_AGENT" ) );}
The list of environment variables that can be used , can be found under the wikipedia cgi article .
Concerning
the
fastCGI specification , it
was created by
the
Open Market company
, and the official
website was
fastcgi.com ,
which is not operational nowadays , but can be accessed using
web archive , as in the provided link .
To install fastCGI , it can be done as follows :
root$ pkg install fcgi-devkit spawn-fcgi # For FreeBSD root$ apt-get install libfcgi-dev spawn-fcgi # For debian
Add an nginx location , which will be handled by a fastCGI application .
# For FreeBSD
root$ nano /usr/local/etc/nginx/nginx.conf
# ctrl-w to search for : server
# and add a location block under
# server as in :
server {
listen 80;
server_name localhost;
...
# add this location block
location /fcgi/ {
gzip off;
fastcgi_pass 127.0.0.1:9100;
include fastcgi_params;
}
...
# For Debian
root$ nano /etc/nginx/sites-enabled/default
# ctrl-w to search for server {
# Add under server the content
server {
listen 80 default_server;
listen [::]:80 default_server;
...
# add this location block
location /fcgi/ {
gzip off;
fastcgi_pass 127.0.0.1:9100;
include fastcgi_params;
}
...
# Finally for Debian , and FreeBSD
# Test the configuration for any
# error using nginx -t , and
# restart the server using
# service nginx restart
Now , for example , to create a fastCGI application using C , It can be done as follows :
# example /home/difyel/hello.c
# Create a C source file , for
# example hello.c
#include "fcgi_stdio.h"
#include <stdio.h>
#include <stdlib.h>
int
main
(void ){
while (FCGI_Accept ( ) >= 0 ){
printf ("Content-type: text/html;\n\n" );
printf ("%s\n" , getenv("HTTP_USER_AGENT" ) );}}
# Compile the C source file using the command
difyel$ gcc -lfcgi -o hello.out hello.c
# spawn a process using spawn-fcgi as in :
spawn-fcgi -a127.0.0.1 -p9100 ./hello.out
Now ,
if you
visit any page under
localhost/fcgi/ ,
the hello.out process will be in charge of
returning a response , in this example program , it
just returns the user agent .
Examples on fastcgi.com/devkit/doc/fcgi-tcl.htm , are provided on how to integrate the fastCGI library , with for example , the Tcl interpreter .