.TH "FBB::CGI" "3bobcat" "2005\-2023" "libbobcat\-dev_6\&.04\&.00" "CGI interface" .PP .SH "NAME" FBB::CGI \- handles GET and POST submitted form data .PP .SH "SYNOPSIS" \fB#include \fP .br Linking option: \fI\-lbobcat\fP .PP .SH "DESCRIPTION" .PP The class \fICGI\fP offers an interface to data submitted by web\-forms\&. The data is sent to a script handling the data using a \fI
\fP stanza\&. Very often this is indeed a script, like a Perl script, but there is no need to use a scripting language\&. The class \fICGI\fP allows \fBC++\fP programmers to process the form by an executable usually resulting in faster processing and in construction time benefits from the type safety offered by \fBC++\fP\&. The class \fICGI\fP automatically handles data submitted using the \fIGET\fP method as well as data submitted using the \fIPOST\fP method\&. .PP By default the class\(cq\&s constructor writes the customary \fIContent\-type\fP header lines to the standard output stream\&. Additional (html) output of a reply page must be provided by other code\&. Therefore, a program processing an uploaded form will have an organization comparable to the following basic setup: .nf // assume includes and namespace std/FBB were defined int main() { CGI cgi; cout << \(dq\&\en\(dq\&; if (parametersOK(cgi)) { process(cgi); generateReplyPage(); } else generateErrorPage(); cout << \(dq\&\en; } .fi .PP When errors in the received form\-data are detected an error message is written to the standard output stream and an \fIFBB::Exception\fP exception is thrown\&. .PP .SH "NAMESPACE" \fBFBB\fP .br All constructors, members, operators and manipulators, mentioned in this man\-page, are defined in the namespace \fBFBB\fP\&. .PP .SH "INHERITS FROM" \- .PP .SH "TYPEDEF" .IP o \fBCGI::MapStringVector\fP: .br A shorthand for \fIstd::unordered_map >\fP, which is the data type in which form\-variables are stored\&. .PP .SH "ENUMERATIONS" The \fICGI::Method\fP enumeration specifies values indicating the way the form\(cq\&s data were submitted: .IP o \fBCGI::UNDETERMINED\fP: .br Used internally indicating that the form\(cq\&s method was neither \fIGET\fP nor \fIPOST\fP\&. .IP o \fBCGI::GET\fP: .br Indicates that the \fIGET\fP method was used when submitting the form\(cq\&s data; .IP o \fBCGI::POST\fP: .br Indicates that the \fIPOST\fP method was used when submitting the form\(cq\&s data\&. .PP The \fICGI::Create\fP enumeration is used to request or suppress creation of the directory to contain any file uploaded by a form: .IP o \fBCGI::DONT_CREATE_PATH\fP: .br When uploading files, the destination directory must exist; .IP o \fBCGI::CREATE_PATH\fP: .br When uploading files, the destination directory will be created\&. .PP .SH "CONSTRUCTORS" .IP o \fBCGI(bool defaultEscape = true, char const *header = \(dq\&Content\-type: text/html\(dq\&, std::ostream &out = std::cout)\fP: .br The default constructor writes the standard content type header to the standard output stream and will use \fIstd::cout\fP for output\&. Specifying \fI0\fP as header suppresses outputting the \fIContent\-type\fP line\&. Otherwise the content type line is also followed by two \fI\er\en\fP character combinations\&. By default all characters in retrieved form\-variables are escaped\&. The overloaded insertion operators (see below) can be used to modify the default set of characters to escape\&. The backslash is used as the escape character\&. The escape\-prefix is not used if the \fIdefaultEscape\fP value is specified as \fIfalse\fP and if no insertions into the \fBCGI\fP object were performed\&. .PP Copy and move constructors (and assignment operators) are available\&. .PP .SH "OERLOADED OPERATORS" .PP \fBNote:\fP the following three insertion operators, defining sets of characters that should be escaped, can only be used before calling any of the \fIparam, begin\fP or \fIend\fP members\&. As soon as one of these latter three members has been called the set of characters to be escaped is fixed and attempts to modify that set is silently ignored\&. .PP .IP o \fBchar const *operator[](std::string const &key) const\fP: .br The index operator returns the value of the environment variable specified as the index\&. 0 is returned if the variable specified at \fIkey\fP is not defined\&. .IP .IP o \fBCGI &operator<<(std::string const &accept)\fP: .br This member\(cq\&s actions are suppressed once \fIparam, begin\fP or \fIend\fP (see below) has been called\&. .IP The insertion operator can be used to fine\-tune the set of characters that are escaped in strings returned by \fIparam\fP (see below)\&. Depending on the value of the constructor\(cq\&s \fIdefaultEscape\fP parameter characters inserted into the \fICGI\fP object will or will not be escaped by a backslash\&. .IP If the constructor\(cq\&s \fIdefaultEscape\fP parameter was specified as \fItrue\fP then the insertion operator can be used to define a set of characters that are \fInot\fP escaped\&. .IP If \fIdefaultEscape\fP was specified as \fIfalse\fP then the insertion operator will define a set of characters that \fIwill\fP be escaped\&. .IP The backlash itself is always escaped and a request to use it unescaped is silently ignored\&. .IP The \fIaccept\fP string can be specified as a regular expression character set, without the usual surrounding square brackets\&. E\&.g\&., an insertion like \fIcgi << \(dq\&\-a\-z0\-9\(dq\&\fP defines the set consisting of the dash, the lower case letters and the digits\&. .IP Individual characters, character ranges (using the dash to specify a range) and all standard character classes (\fI[:alnum:], [:alpha:], [:cntrl:], [:digit:], [:graph:], [:lower:], [:print:], [:punct:], [:space:], [:upper:]\fP, and \fI[:xdigit:]\fP) can be used to specify a set of characters\&. In addition to these standard character classes the class \fI[:cgi:]\fP can be used to define the set consisting of the characters \fI\(dq\& \(cq\& ` ;\fP and \fI\e\fP\&. .IP Note that standard and \fI[:cgi:]\fP character classes \fIdo\fP require square brackets\&. .IP When a series of insertions are performed then the union of the sets defined by these insertions are used\&. .IP \fBNote\fP: using unescaped single quotes, the double quotes, backtick characters and semicolons in CGI\-programs might be risky and is not advised\&. .IP .IP o \fBCGI &operator<<(int c)\fP: .br This member\(cq\&s actions are suppressed once \fIparam, begin\fP or \fIend\fP (see below) has been called\&. .IP This insertion operator is used to change the default escape handling of a single character \fIc\fP\&. The \fIint\fP parameter is cast internally to a \fIchar\fP\&. .IP .IP o \fBCGI &operator<<(std::pair range)\fP: .br This member\(cq\&s actions are suppressed once \fIparam, begin\fP or \fIend\fP (see below) has been called\&. .IP This insertion operator can be used to change the default escape handling of a range of characters\&. The pair\(cq\&s second character must be equal to or exceed the position of the pair\(cq\&s first character in the ASCII collating sequence or the member will have no effect\&. .IP .IP o \fBstd::ostream &std::operator<<(std::ostream &out, CGI const &cgi)\fP: .br \fICGI\fP objects can be inserted into \fIostreams\fP to display the characters that will appear escaped in strings returned by the \fIparam()\fP member function\&. Each character for which \fIisprint()\fP returns \fItrue\fP will be displayed as character, surrounded by single quotes\&. For all other characters their ASCII values are displayed\&. Each character is displayed on a line by itself\&. .IP .SH "MEMBER FUNCTIONS" .IP o \fBCGI::MapStringVector::const_iterator begin()\fP: .br Returns the begin iterator of the form\(cq\&s parameter map\&. Iterator values unequal to \fIend\fP (see below) point to a pair of values, the first of which is the name of a field defined by the form, the second is a vector of strings containing the field\(cq\&s value(s)\&. See also the description of the \fIparam\fP member below\&. .IP .IP o \fBCGI::MapStringVector::const_iterator end()\fP: .br Returns the end iterator of the form\(cq\&s parameter map\&. .IP .IP o \fBunsigned long long maxUploadSize() const\fP: .br Returns the current maximum file upload size in bytes\&. .IP .IP o \fBCGI::Method method() const\fP: .br Returns the method that was used when the form was submitted (either \fICGI::GET\fP or \fICGI::POST\fP)\&. .IP .IP o \fBstd::vector const ¶m(std::string const &variable)\fP: .br Returns the value of the form\-variable specified by the function\(cq\&s argument\&. An empty vector is returned if the variable was not provided by the form\(cq\&s data\&. .IP If the same variable was specified multiple times or if its value extends over multiple lines (only with \fImultipart/form\-data\fP) then the vector contains multiple strings\&. .IP With \fIGET\fP and \fIPOST\fP methods not using \fImultipart/form\-data\fP input fields extending over multiple lines are stored in one string, using \fI\er\en\fP combinations between those lines\&. .IP When files are uploaded the vectors contain sets of four strings\&. The first string provides the path nme of the uploaded file; the second string provides the file name specified in the form itself (so it is the name of the file at the remote location); the third string shows the content type specified by the remote browser (e\&.g\&., \fIapplication/octet\-stream\fP), the fourth string contains \fIOK\fP if the file was successfully uploaded and \fItruncated\fP if the file was truncated\&. Existing files will not be overwritten\&. When uploading a file a usable filename must be found within 100 trials\&. .IP .IP o \fBstd::string param1(std::string const &variable) const\fP: .br Returns the first element of the \fIvector\fP returned by the \fIparam\fP member or an empty string if \fIvariable\fP was not defined by the received form\&. .IP .IP o \fBstd::string const &query() const\fP: .br Returns the query\-string submitted with \fICGI::GET\fP or \fICGI::POST\fP forms (if the \fIPOST\fPed form specified \fIENCTYPE=\(dq\&multipart/form\-data\(dq\&\fP the query string is empty)\&. .IP .IP o \fBreport()\fP: .br The \fIreport\fP member silently returns if no errors were encountered while processing form\-data\&. Otherwise, the \fIhtml\fP file generated by the \fICGI\fP program displays a line starting with \fIFBB::CGI\fP, followed by the status report\&. .IP The following status report messages are presently defined: .IP \fIContent\-Disposition not recognized in:\fP, which is followed by the line where the \fIContent\-Disposition\fP was expected\&. This may occur when processing \fImultipart/form\fP data\&. .IP \fIInvalid multipart/form\-data\fP\&. This message can be generated when readling lines while processing \fImultipart/form\fP data\&. .IP \fIGET/POST REQUEST_METHOD not found\fP\&. This message is shown if the program couldn\(cq\&t find the form\(cq\&s \fIREQUEST_METHOD\fP type (i\&.e\&., \fIGET\fP or \fIPOST\fP)\&. .IP \fIInvalid CONTENT_LENGHT in POSTed form\fP\&. This message is shown if the content\-length header has an incorrect value\&. .IP \fIContent\-Type not found for file\-field\fP, followed by the file\(cq\&s field name\&. This message is shown if no \fIContent\-Type\fP specification was found in an uploaded form\&. .IP \fICan\(cq\&t open a file to write an uploaded file\fP\&. This message indicates that the CGI program was unable to open a file to write an uploaded file to\&. This can be caused by an overfull disk or partition or by incorrect write\-permissions\&. .IP \fImultipart/form\-data: no end\-boundary found\fP\&. This message is shown if the end\-boundary was missing in a \fImultipart/form\-data\fP form\&. .IP .IP o \fBvoid setFileDestination(std::string const &path, std::string const &prefix = \(dq\&\(dq\&, Create create = CREATE_PATH)\fP: .br This member is used to specify the path and prefix of uploaded files\&. Uploaded files will be stored at \fIpath/prefixNr\fP where \fINr\fP is an internally used number starting at one\&. When \fICREATE_PATH\fP is specified \fIpath\fP must be available or the \fBCGI\fP object must be able to create the path\&. If \fIDONT_CREATE_PATH\fP is specified the specified path must be available\&. If not, an \fIFBB::Exception\fP exception will be thrown\&. .IP .IP o \fBvoid setMaxUploadSize(size_t maxSize, int unit = \(cq\&M\(cq\&)\fP: .br This member can be used to change the maximum size of uploaded files\&. Its default value is 100Mb\&. The \fIunit\fP can be one of \fIb\fP (bytes, the default), \fIK\fP (Kbytes), \fIM\fP (Mbytes) or \fIG\fP (Gbytes)\&. Unit\-specifiers are interpreted case insensitively\&. File uploads will continue until the maximum upload size is exceeded, followed by discarding any remainder\&. .IP .IP o \fBvoid swap(CGI &other)\fP: .br The current and \fIother\fP object are swapped\&. The first time one of the \fIparam(), begin()\fP or \fIend()\fP members is called these members may detect errors in the the received form data\&. If so, an error message is written to the standard output stream and an \fIFBB::Exception\fP exception will be thrown\&. .PP .SH "STATIC MEMBERS" .IP o \fBstd::string dos2unix(std::string const &text)\fP: .br This member converts all \fI\er\en\fP character combinations in \fItext\fP into plain \fI\en\fP characters, returning the converted text\&. .IP .IP o \fBstd::string unPercent(std::string const &text)\fP: .br This member converts all \fI%xx\fP encoded characters into their corresponding ASCII values\&. Also, \fI+\fP characters are converted to single blank spaces\&. The converted string is returned\&. .PP .SH "EXAMPLE" .PP .nf #include \(dq\&main\&.ih\(dq\& void showParam(CGI::MapStringVector::value_type const &mapValue) { cout << \(dq\&Param: \(dq\& << mapValue\&.first << \(cq\&\en\(cq\&; for (auto &str: mapValue\&.second) cout << \(dq\& \(dq\& << CGI::dos2unix(str) << \(dq\&\en\(dq\& \(dq\& \(dq\&; cout << \(cq\&\en\(cq\&; } int main(int argc, char **argv) try { Arg &arg = Arg::initialize(\(dq\&evhm:\(dq\&, argc, argv); // usage and version are in the source archive in \&.\&.\&./cgi/driver // arg\&.versionHelp(usage, version, 2); ifstream in(arg[0]); string line; while (getline(in, line)) { size_t pos = line\&.find(\(cq\&=\(cq\&); if (pos == string::npos) continue; // set environment vars simulating // a GET form if (setenv(line\&.substr(0, pos)\&.c_str(), line\&.substr(pos + 1)\&.c_str(), true) == 0) { if (arg\&.option(\(cq\&e\(cq\&)) cout << line\&.substr(0, pos)\&.c_str() << \(cq\&=\(cq\& << line\&.substr(pos + 1)\&.c_str() << \(cq\&\en\(cq\&; } else cout << \(dq\&FAILED: setenv \(dq\& << line << \(cq\&\en\(cq\&; } CGI cgi(false); // chars are not escaped cgi << arg[1]; if (arg\&.option(&line, \(cq\&m\(cq\&)) cgi\&.setMaxUploadSize(stoul(line), *line\&.rbegin()); cout << \(dq\&Max upload size (b): \(dq\& << cgi\&.maxUploadSize() << \(cq\&\en\(cq\&; CGI::Method method = cgi\&.method(); cout << \(dq\&To escape:\en\(dq\& << cgi << \(dq\&\en\(dq\& \(dq\&Method: \(dq\& << (method == CGI::GET ? \(dq\&GET\(dq\& : \(dq\&POST\(dq\&) << \(cq\&\en\(cq\&; cout << \(dq\&Query string: \(dq\& << cgi\&.query() << \(cq\&\en\(cq\&; cout << \(dq\&Submit string: `\(dq\& << cgi\&.param1(\(dq\&submit\(dq\&) << \(dq\&\(cq\&\en\(dq\&; for (auto &mapElement: cgi) showParam(mapElement); cout << \(dq\&END OF PROGRAM\en\(dq\&; } catch (exception const &err) { cout << err\&.what() << \(cq\&\en\(cq\&; return 1; } catch (\&.\&.\&.) { return 1; } .fi .PP To test the program\(cq\&s \fIget\fP form processing, call it as \fIdriver get \(cq\&[:cgi:]\(cq\&\fP, with the file \fIget\fP containing: .nf INFO=This is an abbreviated set of environment variables SERVER_ADMIN=f\&.b\&.brokken@rug\&.nl GATEWAY_INTERFACE=CGI/1\&.1 SERVER_PROTOCOL=HTTP/1\&.1 REQUEST_METHOD=GET QUERY_STRING=hidden=hidval&submit=Submit+%20Query .fi .PP To test the program\(cq\&s \fIpost\fP form processing, call it as \fIdriver post1 \(cq\&[:cgi:]\(cq\&\fP, using \fIpost1\fP and \fIpost1\&.cin\fP found in Bobcat\(cq\&s source archive under \fI\&.\&./cgi/driver\fP\&. .PP .SH "FILES" \fIbobcat/cgi\fP \- defines the class interface .PP .SH "SEE ALSO" \fBbobcat\fP(7) .PP .SH "BUGS" None Reported\&. .PP .SH "BOBCAT PROJECT FILES" .PP .IP o \fIhttps://fbb\-git\&.gitlab\&.io/bobcat/\fP: gitlab project page; .IP o \fIbobcat_6\&.04\&.00\-x\&.dsc\fP: detached signature; .IP o \fIbobcat_6\&.04\&.00\-x\&.tar\&.gz\fP: source archive; .IP o \fIbobcat_6\&.04\&.00\-x_i386\&.changes\fP: change log; .IP o \fIlibbobcat1_6\&.04\&.00\-x_*\&.deb\fP: debian package containing the libraries; .IP o \fIlibbobcat1\-dev_6\&.04\&.00\-x_*\&.deb\fP: debian package containing the libraries, headers and manual pages; .PP .SH "BOBCAT" Bobcat is an acronym of `Brokken\(cq\&s Own Base Classes And Templates\(cq\&\&. .PP .SH "COPYRIGHT" This is free software, distributed under the terms of the GNU General Public License (GPL)\&. .PP .SH "AUTHOR" Frank B\&. Brokken (\fBf\&.b\&.brokken@rug\&.nl\fP)\&. .PP