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 .