FastCGI C++ Class library (fcgicc)
Introduction
This is a simple C++ class library that provides FastCGI server functionality. FastCGI is a protocol for connecting web servers with programs that generate content. The protocol is described in more detail at the FastCGI website. This library provides a single class which handles FastCGI connections on TCP/IP or local domain sockets. Multiple connections are handled in a single thread using select(). When a request is ready, it is passed to an application-supplied callback for processing, after which the generated response is sent back to the client.
Project status
This is the first release of fcgicc, version 0.1.1. It provides a full implementation of the responder mode of FastCGI, but has undergone only limited testing. Use with care!
Licensing
fcgicc is free software, available under a BSD-style license. There is no warranty; not even for merchantability or fitness for a particular purpose. See the file LICENSE.txt in the distribution for complete information.
Download
Source code:
fcgicc-0.1.1.tar.bz2 (12.03 kB, 2009-08-12)
Installing
This library depends on the FastCGI Development Kit from the FastCGI website. For convenience the required part of it is included in this distribution and will be used if the development kit is not found on your system.
To build and install fcgicc as a standalone library you will need CMake, which is available from the CMake website.
cd fcgicc cmake . make install
— or —
cd fcgicc cmake -DPREFIX=$HOME/local . make install
Alternatively, it may be simpler to import the two source files into your project and build them as part of it.
Using
Here is how it works:
Client ------------> Web server ------> FastCGIServer ----------------. HTTP request params FastCGIRequest | stdin ' Application . | Client <------------ Web server <------ FastCGIServer <---------------' HTTP response stdout FastCGIRequest stderr
The web server, which is a client to the FastCGI server, forwards a request as a set of key-value parameter pairs and a standard input stream. The parameter pairs are the environment variables from plain CGI, and they include such important variables as REQUEST_URI. The standard input stream contains data from POST requests.
An instance of the FastCGIServer class listens for requests from the web server, builds a FastCGIRequest instance for each one, calls event handlers defined by the application to process them, and responds to the web server.
The application processes requests using event handlers like this:
… #include <fcgicc.h> … int handle_request(FastCGIRequest& request) { // This is always the first event to occur. It occurs when the // server receives all parameters. There may be more data coming on the // standard input stream. if (request.params.count("REQUEST_URI")) return 0; // OK, continue processing else return 1; // Stop processing and return error code } int handle_data(FastCGIRequest& request) { // This event occurs when data is received on the standard input stream. // A simple string is used to hold the input stream, so it is the // responsibility of the application to remember which data it has // processed. The application may modify it; new data will be appended // to it by the server. The same goes for the output and error streams: // the application should append data to them; the server will remove // all sent data from them. std::transform(request.stdin.begin(), request.stdin.end(), std::back_inserter(request.stderr), std::bind1st(std::plus<char>(), 1)); request.stdin.clear(); // don't process it again return 0; // still OK } class Application { public: int handle_complete(FastCGIRequest& request) { // The event handler can also be a class member function. This // event occurs when the parameters and standard input streams are // both closed, and thus the request is complete. request.stdout.append("Content-Type: text/plain\r\n\r\n"); request.stdout.append("You requested: "); request.stdout.append(request.params[std::string("REQUEST_URI")]); return 0; } }; …
The application sets up the FastCGI server like this:
… FastCGIServer server; // Instantiate a server // Set up our request handlers server.request_handler(&handle_request); server.data_handler(&handle_data); server.complete_handler(application, &Application::handle_complete); server.listen(7000); // Listen on a TCP port server.listen(7001); // ... or on two server.listen("./socket"); // ... and also on a local doman socket server.process(100); // Process some data, but don't wait more // than 100 ms for it to arrive. server.process(); // Process some data with no timeout server.process_forever(); // Process everything …
Updates and feedback
This library is hosted at http://althenia.net/fcgicc. It is programmed by Andrey Zholos. Comments, bug reports, testing results and feature requests are welcome.