Apache, fastcgi and c ++: "Hello, world"
Writing web applications in C / C ++ is a thankless task. Many say that this is completely crazy when there is PHP and Perl. And I agree with them. It's very easy to write a website in PHP (especially using frameworks like the Zend Framework).
But .. (there is always some kind of “but”).
Let's not forget that ease of use is not just about simple syntax. Many parameters are taken into account. And one of the significant parameters is the availability of articles “Get started with ...” with examples of “hello, world” programs. I am going to add a little simplicity to writing fastcgi in C / C ++. And if after reading this article at least one person says, “And it’s not so difficult,” then I will consider my mission accomplished.
To go all the way from the empty source to the inscription on the browser screen, we will have to configure the web server (in our case, Apache), install mod_fastcgi on it, select the libfcgi library and finally write a “Hello, world” program.
Intro: FastCGI
You can read about what fastcgi is here . In short, this is a CGI program that processes requests in a loop. Its advantage over a regular CGI program is that it runs once to process multiple requests.
Web server
Any web server supporting fastcgi interface is suitable for work.
It so happened that all my attempts to interact with the web were carried out using the Apache web server. His choice for this article is more likely due to his presence and the work of other projects on it than to some special characteristics.
Possible alternatives:
Nginx and Lighttpd have native support for the fastcgi interface and their use is more preferable on production servers. You can also use MS IIS.
Mod_fastcgi, mod_fcgid
I know of two modules that support fastcgi-interface in Apache, mod_fastcgi and mod_fcgid .
Mod_fastcgi has been developed by Open Market since 1997. The latest version 2.4.6 was updated on November 13th, 2007 and, as the authors assure, is very stable.
Mod_fcgi, judging by the domain, is developed by Chinese programmers. The latest version 2.2 is dated July 31, 2007. Distinctive features of mod_fastcgi are: a new model for managing fastcgi programs, error detection in fastcgi programs. The module has binary compatibility and therefore there is no need to recompile programs working under mod_fastсgi.
Using development kitwith fastcgi.com for program development, I decided that it would be more appropriate to use mod_fastcgi, as they use the shared libfcgi library.
To connect the mod_fastcgi module, you need to add it to httpd.conf:
LoadModule fastcgi_module modules/mod_fastcgi.so
AddHandler fastcgi-script .fcg .fcgi .exe
Types of launching fastcgi programs
Using mod_fastcgi, you can run programs in three different ways: dynamically, statically, and remotely.
Dynamic way to start: At the time of starting apache only creates a process manager (PM), waiting for incoming requests. As soon as the first request is received, the process manager creates an instance of the program to process it. Depending on the settings, after processing the request, the program can be terminated by PM, or it can be used to process subsequent requests. Using the settings, you can set many parameters of the created application pool, such as the minimum and maximum size, application lifetime, maximum request queue size, and others.
Directive:
FastCgiConfig option [option ...]
Static startup method:When it starts, apache creates PM, which in turn creates a given number of program instances to process incoming requests.
Directive:
FastCgiServer filename [option ...]
Remote start method: The application starts independently of apache and PM. PM acts as a proxy.
Directive:
FastCgiExternalServer filename -host hostname:port [option ...]
FastCgiExternalServer filename -socket filename [option ...]
Interaction Methods:
- Stdin
- Unix domain socket / named pipe
- TCP socket
Stdin: Used in the dynamic way to run fastcgi programs. Interaction occurs through Standard in file descriptor.
Unix domain socket / Named pipe: It can be used both in the static and in the remote way to run fastcgi programs. With the static method, socket is created by the process manager; with the remote method, socket must be created by a fastcgi program. To use this method, you must specify a parameter
–socket имя_сокета
. TCP Socket: It can be used in the same way as the Unix domain socket / named pipe, both in the static and remote mode of running fastcgi programs. For use in static mode, you must specify a parameter
-port номер_tcp_порта
. For remote use option -host имя_хоста:номер_tcp_порта
.What interests me first of all is working with tcp socket and the remote way to start a fastcgi program, because it gives compatibility with other web servers and also provides a simpler debugging feature.
Fastcgi libraries
There are not many libraries that help create fastcgi programs in C / C ++. The most popular is libfcgi.lib , which comes as part of the development kit from fastcgi.com. The library, frankly, provides a poor functionality for work.
There is also a Fastcgi ++ C ++ class library.
Since this is my first fastcgi program, I will use the old, proven libfcgi.lib library .
Hello_world.fcgi
The program uses TCP Socket for communication, opening port number 9000. The string “Fastcgi: Hello, world” is displayed in the browser.
Functions used:
int FCGX_Init (void);
- Initialization of the FCGX library
int FCGX_OpenSocket (const char * path, int backlog);
- Opens a listening socket (Options:)
path – имя сокета, backlog – глубина стека запросов
. int FCGX_InitRequest (FCGX_Request * request, int sock, int flags);
- Initialize the request structure for use inside FCGX_ Accept_r (Parameters:)
request – указатель на структуру запроса, sock – слушающий сокет используемый совместно с request, flags – флаг запроса (доступные флаги: FCGI_FAIL_ACCEPT_ON_INTR – не вызывать повторно accept при разрыве
. int FCGX_Accept_r (FCGX_Request * request);
- Receives a new request for processing.
Full text of the program:
#include
#include "fcgi_stdio.h"
#include
#pragma comment(lib, "libfcgi.lib")
int main(int argc, char* const argv[] )
{
std::string port=":9000"; //Задаем номер порта TCP
int listenQueueBacklog = 400; //Глубина стека запросов
FCGX_Stream *in, *out, *err;
FCGX_ParamArray envp;
if(FCGX_Init()) exit(1); //Инициализируем библиотеку перед работой.
int listen_socket = FCGX_OpenSocket(port.c_str(), listenQueueBacklog); //Открываем новый слушающий сокет
if(listen_socket < 0) exit(1);
FCGX_Request request;
if(FCGX_InitRequest(&request, listen_socket, 0)) exit(1); //Инициализируем структуру запроса
while(FCGX_Accept_r(&request) == 0)
{
FCGX_FPrintF(request.out, "Content-type: text/html\r\n\r\nfastcgi \nFastcgi: Hello world.
\n");
FCGX_Finish_r(&request);//Завершаем запрос
}
return 0;
}
Vhosts.conf
A piece of the vhost.conf configuration file responsible for helloworld.local :
NameVirtualHost 127.0.0.1:80
ServerAdmin mail @ localhost
DocumentRoot "C: / Apache2 / cgi-bin"
ServerName "helloworld.local"
Options Indexes FollowSymLinks MultiViews ExecCGI
AllowOverride all
Order Deny, Allow
Deny from all
Allow from 127.0.0.1
SetHandler fastcgi-script
FastCgiExternalServer C: /Apache2/cgi-bin/hello_world.exe -host 127.0.0.1:9000
In the folder “C: / Apache2 / cgi-bin” I have a .htaccess file that directs all requests to helloworld.local to hello_world.exe.
Ending
Well, that’s all, now in my browser the phrase “Fastcgi: Hello, world” is proudly displayed.