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 .