In a web world increasingly dominated by framework tools, it’s often less necessary to run one’s own web services and programmed/scripted pages directly. Even people comfortable with such technologies often opt for the convenience of outsourcing: this blog uses WordPress.
Sometimes you need to drop down low, however, as with my projects for https://sweptapp.com , which is a web and multiplatform development framework, or as for licensing my Rhino Plugin XRay, for which the need is dictated by the devs behind Rhino if I want to use the Cloud Zoo.
While some successor standards have come along which have improvements particularly under high web server loads, FASTCGI being the obvious example, even then we often still refer to what’s happening as CGI. It can be plugged into most webservers1 and allows the implementation of script or program-driven web pages, web page components, or web services utilizing similar communications but invisible to the user.
The most basic purpose of a web server is to take a request for a resource, such as https://softwaresideroads.com/about/, and map it to something it can serve, and present it to the user. This resource may be a simple file (html, png, etc.) or may be created upon this request solely for the purpose of returning to the user. Such creation may have a unique result or not, for example a user’s personal account page vs a home page. While technically a request for https://softwaresideroads.com/ goes to WordPress for creation, in practice various flags indicate that the resource won’t be changing rapidly so caching is possible.
The selection of a pair of tools to implement a web service is largely dictated by preference in language. Some of the scripting versions are basically built into many modern webservers (PHP being dominant) or ready to go in most hosting packages (such as Flask, a framework for Python).
In my immediate case, implementing licensing for Rhino plugins, McNeel provides samples in Python. Because of prior work, I have important parts of the toolchain already written in C and C++ such as database components.
That leads me to go back and reuse one of the first widespread CGI frameworks, CGIC by Thomas Boutell. His primary purpose was to support web forms and similar input/output with session management through cookies.
CGIC doesn’t do detailed processing on the detailed web service submissions and responses I need, which is this case are JSON-based, but it does provide a stable, tested interface to the web server and appropriate handling of the HTTP header (resource being requested, etc.) and response information (success, 404, etc.).
When it’s done reading the data it understands, it stops, accurately reporting the content type of the data block. That leaves the JSON or other data available for reading via scanf or cin. For the time being, I just write that to a file or std::string and then invoke a JSON processor on it.
CGIC compiles well under *nix or windows with minimal fiddling (more recent versions of Visual Studio can be slightly fussy about function names). It plays nicely with most web servers and frameworks by adding a minimum of requirements and overhead: there are no dependencies. CGIC became so widespread that it was tested with virtually all of the servers, caching tools, and web browsers out there.
For this dev stack, I have hosting at pair.com, cgic as the interface to http, Niels Lohmann’s JSON Parser, and sqlite for the database.
About the most I’ve had to do to cross-compile cgic has been something like the following:
#ifdef _WIN64
#define dup(a) _dup(a)
#define fdopen(a,b) _fdopen(a,b)
#define fileno(a) _fileno(a)
#define close(a) _close(a)
#define unlink(a) _unlink(a)
#define chmod(a,b) _chmod(a,b)
#endif
CGIC comes with its own main() function; your library provices a cgiMain() which it calls when it’s done processing the headers.
From there, all it takes is a web host ready to run CGI files. To avoid the (fictious example) http://example.com/cgi-bin/myscript.cgi look in browsers, the web host’s .htaccess file may be modified with a rewrite rule such as the following, which redirects any request within the domain to myprog.cgi, preserving the URL path when passed.
RewriteEngine On
RewriteRule ^([^/]+)$ /cgi-bin/myprog.cgi/$1
1 – The exceptions are mostly for very streamlined servers optimized for tasks such as image or stream hosting
Leave a Reply