FastCGI Deployments

The target system will be OpenBSD. Our FastCGI script will be deployed using the socket interface, which is the default on OpenBSD and supported on other web servers, such as Apache, as well. In this method, the FastCGI application creates a socket that listens for connections. The web server maps a web page to a socket, then connects to the socket and transmits requests.

Source Code

Let's start with the server itself. This will be brutally simple: it will respond to all requests and simply print Hello, World and nothing more. The difference between this and the usual CGI method is that all processing occurs in a loop instead of as the entire body of the program.

#include <sys/types.h> /* size_t, ssize_t */
#include <stdarg.h> /* va_list */
#include <stddef.h> /* NULL */
#include <stdint.h> /* int64_t */
#include <kcgi.h>

int
main(void)
{
  struct kreq req;
  struct kfcgi *fcgi;

  if (KCGI_OK != khttp_fcgi_init
     (&fcgi, NULL, 0, NULL, 0, 0))
    return 0;

  while (KCGI_OK == khttp_fcgi_parse(fcgi, &req)) {
    khttp_head(&req, kresps[KRESP_STATUS], 
      "%s", khttps[KHTTP_200]);
    khttp_head(&req, kresps[KRESP_CONTENT_TYPE], 
      "%s", kmimetypes[KMIME_TEXT_PLAIN]);
    khttp_body(&req);
    khttp_puts(&req, "Hello, world!\n");
    khttp_free(&req);
  }

  khttp_fcgi_free(fcgi);
  return 0;
}

This example doesn't do any real error checking or content validation, so it's pretty easy to understand. Consult the khttp_fcgi_init(3), khttp_fcgi_parse(3), and khttp_fcgi_free(3) manpages to see how these work properly. Next comes the more tricky part: deploying as a FastCGI application.

Compile and Link

Compiling and linking follow the same logic as in the Getting Started with CGI in C. Since we're going to install our application in a file-system jail, we'll statically compile it. If your operating system doesn't support static linking, you won't be able to run your application with a file-system jail unless you copy over all libraries into the jail. (This is not covered by this tutorial.)

% cc -I/usr/local/include -c -o tutorial2.o tutorial2.c
% cc -static -L/usr/local/lib -o tutorial2 tutorial2.o -lkcgi -lz

Install

Our installation process will look a great deal like that of Getting Started with CGI in C except that we'll change our paths around a bit. First, let's configure the web server. I'll assume this is OpenBSD's httpd(8). The file-format documentation is httpd.conf(5).

server "me.local" {
  listen on * port 80
  location "/fcgi-bin/*" {
    fastcgi socket "/run/httpd.sock"
    root "/"
  }
}

This will cause CGI requests to /fcgi-bin to be routed into the socket at /run/httpd.sock, which is relative to the server root /var/www. Let's first install our web application within the server root.

% doas mkdir -p /var/www/fcgi-bin
% doas install -m 0555 tutorial2 /var/www/fcgi-bin

We must now set up the socket by executing our server. We do this by using the kfcgi(8) utility, which will securely create the FastCGI socket, enact the file-system jail, then execute a pool of applications.

% doas kfcgi -U www -u www -- /fcgi-bin/tutorial2

That's it! At this point, the web application (running as user www) is executing under the kfcgi(8) daemon within the file-system jail at /var/www. It has created the socket in /var/www/run/httpd.sock as user www. The web server will now be able to connect to this socket for its requests.