The implementation is aimed to be as simple as possible (maybe even "dumb") for better understanding and correctness.
ATTENTION, this software is "beta" quality, and the API is a subject to change!
Any feedback (especially results of testing) is highly appreciated!
Please note, there are official Dmitigr Fcgi documentation site. Because of the Dmitigr Fcgi documentation is generated by Doxygen, most of references to the classes and methods on the official documentation site are clickable, which makes the familiarization more convenient. Also there are overview class diagram of the API for better understanding.
Reliable and fast implementation of the FastCGI protocol.
- Easy to use API;
- High performance;
- Can be used as shared, static or "header-only" library.
#include <dmitigr/fcgi.hpp>
#include <iostream>
int main(int, char**)
{
#ifdef _WIN32
const char* const crlf = "\n";
const char* const crlfcrlf = "\n\n";
#else
const char* const crlf = "\r\n";
const char* const crlfcrlf = "\r\n\r\n";
#endif
try {
const auto port = 9000;
const auto backlog = 64;
const auto server = dmitigr::fcgi::Listener_options::make("0.0.0.0", port, backlog)->make_listener();
server->listen();
while (true) {
if (const auto conn = server->accept()) {
conn->out() << "Content-Type: text/plain" << crlfcrlf;
conn->out() << "Hello from dmitigr::fcgi!" << crlf;
}
}
} catch (const std::exception& e) {
std::cerr << "Oops: " << e.what() << std::endl;
return 1;
}
return 0;
}
#include <dmitigr/fcgi.hpp>
#include <iostream>
#include <thread>
#include <vector>
namespace fcgi = dmitigr::fcgi;
namespace {
constexpr auto pool_size = 64;
} // namespace
int main(int, char**)
{
#ifdef _WIN32
const char* const crlf = "\n";
const char* const crlfcrlf = "\n\n";
#else
const char* const crlf = "\r\n";
const char* const crlfcrlf = "\r\n\r\n";
#endif
try {
const auto serve = [crlf, crlfcrlf](auto* const server)
{
while (true) {
const auto conn = server->accept();
conn->out() << "Content-Type: text/plain" << crlfcrlf;
conn->out() << "Hello from dmitigr::fcgi!" << crlf;
conn->close(); // Optional.
}
};
const auto port = 9000;
const auto backlog = 64;
std::clog << "Multi-threaded FastCGI server started:\n"
<< " port = " << port << "\n"
<< " backlog = " << backlog << "\n"
<< " thread pool size = " << pool_size << std::endl;
const auto server = fcgi::Listener_options::make("0.0.0.0", port, backlog)->make_listener();
server->listen();
std::vector<std::thread> threads(pool_size);
for (auto& t : threads)
t = std::thread{serve, server.get()};
for (auto& t : threads)
t.join();
server->close(); // Optional.
} catch (const std::exception& e) {
std::cerr << "error: " << e.what() << std::endl;
return 1;
} catch (...) {
std::cerr << "unknown error" << std::endl;
return 2;
}
return 0;
}
Client programs that use Dmitigr Fcgi must include header file dmitigr/fcgi.hpp
.
and must link with dmitigr_fcgi
(or the debug build - dmitigr_fcgid
) if Dmitigr
Fcgi is used as a regular library. (There is no need in linkage if the header-only
version is used.)
WARNING Headers other than dmitigr/fcgi.hpp
should be avoided to use in
applications since that headers are subject to reorganize. Also the namespace
dmitigr::fcgi::detail
consists of the implementation details and should not
be used in the client code.
The Dmitigr Fcgi repository is located at Github here.
- CMake build system version 3.13+;
- C++17 compiler (GCC 7.3+ or Microsoft Visual C++ 15.7+);
- dmitigr_common library.
Settings that may be specified at build time by using CMake variables are:
- the type of the build (only meaningful to single-configuration generators);
- the flag to build the shared library (default is on);
- the flag to only install the header-only library (default is off);
- the flag to build the tests (default is on);
- installation directories.
Details:
CMake variable | Possible values | Default on Unix | Default on Windows |
---|---|---|---|
The type of the build | |||
CMAKE_BUILD_TYPE | Debug | Release | RelWithDebInfo | MinSizeRel | Debug | Debug |
The flag to build the shared library | |||
BUILD_SHARED_LIBS | On | Off | On | On |
The flag to only install the header-only library | |||
DMITIGR_FCGI_HEADER_ONLY | On | Off | Off | Off |
The flag of building the tests | |||
DMITIGR_FCGI_BUILD_TESTS | On | Off | On | On |
Installation directories | |||
CMAKE_INSTALL_PREFIX | an absolute path | "/usr/local" | "%ProgramFiles%\dmitigr_fcgi" |
DMITIGR_FCGI_CMAKE_INSTALL_DIR | a path relative to CMAKE_INSTALL_PREFIX | "share/dmitigr_fcgi/cmake" | "cmake" |
DMITIGR_FCGI_DOC_INSTALL_DIR | a path relative to CMAKE_INSTALL_PREFIX | "share/dmitigr_fcgi/doc" | "doc" |
DMITIGR_FCGI_LIB_INSTALL_DIR | a path relative to CMAKE_INSTALL_PREFIX | "lib" | "lib" |
DMITIGR_FCGI_INCLUDE_INSTALL_DIR | a path relative to CMAKE_INSTALL_PREFIX | "include" | "include" |
Dmitigr Fcgi is depends on dmitigr_common.
WARNING It's highly recommended to update the dmitigr_common library (just pull and reinstall) before every build of the Dmitigr Fcgi library!
$ git clone https://github.com/dmitigr/fcgi.git
$ mkdir -p fcgi/build
$ cd fcgi/build
$ cmake -DCMAKE_BUILD_TYPE=Debug ..
$ make
$ sudo make install
Run the Developer Command Prompt for Visual Studio and type:
> git clone https://github.com/dmitigr/fcgi.git
> mkdir fcgi\build
> cd fcgi\build
> cmake -G "Visual Studio 15 2017 Win64" ..
> cmake --build . --config Debug
Next, run the Elevated Command Prompt (i.e. the command prompt with administrator privileges) and type:
> cd fcgi\build
> cmake -DBUILD_TYPE=Debug -P cmake_install.cmake
To make the installed DLL available for any application that depends on it, the symbolic link to the dmitigr_fcgi.dll (or to the debug version - dmitigr_fcgid.dll) should be created:
- in %SYSTEMROOT%\System32 for the 64-bit DLL on 64-bit host (or for 32-bit DLL on 32-bit host);
- in %SYSTEMROOT%\SysWOW64 for the 32-bit DLL on 64-bit host.
To create the symbolic link run the Elevated Command Prompt and use mklink
command, for example:
> cd /d %SYSTEMROOT%\System32
> mklink dmitigr_fcgid.dll "%ProgramFiles%\dmitigr_fcgi\lib\dmitigr_fcgid.dll"
If you are using CMake the consuming of the Dmitigr Fcgi library is quite simple. For example:
cmake_minimum_required(VERSION 3.13)
project(foo)
find_package(dmitigr_fcgi REQUIRED) # find shared version of the Dmitigr Fcgi library
set(CMAKE_CXX_STANDARD 17)
set(CXX_STANDARD_REQUIRED ON)
add_executable(foo foo.cpp)
target_link_libraries(foo dmitigr_fcgi)
The above code snippet is minimal CMakeLists.txt that enough to build the
application foo
that depends on the Dmitigr Fcgi library.
To consume the header-only version of the Dmitigr Fcgi library just specify it by using
CONFIGS
option of find_package:
find_package(dmitigr_fcgi REQUIRED CONFIGS dmitigr_fcgi_interface-config.cmake)
# ...
target_link_libraries(foo dmitigr_fcgi_interface)
Dmitigr Fcgi is distributed under zlib license. For conditions of distribution and use,
see file LICENSE.txt
.
Dmitigr Fcgi has been developed on the own funds. Donations are welcome! To make a donation, please go here.
Any feedback are welcome. Contact us.
Copyright (C) Dmitry Igrishin