In this post I will show you how to process HTML forms easily using CGIs in C++. I assume you have already basic knowledge of writing CGIs in C++, if you don’t go a head and read Introduction to C++ CGI.
Processing forms is the basic function of any CGI script and the main purpose of CGIs. As you probably know there are two common ways to send form data back to the web server: “post” and “get”. When form data is sent with the “get” method it is appended to the URL string of the form submission URL. The “post” method is much like the “get” except the data is transmitted via http headers and not via the URL itself. When a form uses “get” it allows the user to easily bookmark the query created by the form as the data is transmitted in URL itself, on the other hand the “post” method allows to send much more data and spares to user from seeing the data in the URL.
Getting the “post” and “get” data is relatively easy. To get the data sent by “get” you can just call getenv("QUERY_STRING") and you will receive a pointer to null-terminated string containing the “get” data. Reading the “post” data is a bit more complicated. The data needs to be read from the standard input, but the program won’t receive an EOF when it reaches the end of the data but instead it should stop reading after reading a specified amount of bytes, which is defined in the environment variable “CONTENT_LENGTH“. So you should read getenv("CONTENT_LENGTH") bytes from the standard input to receive the “post” data.
But here it’s get tricky. The data is received in an encoded way. The data for both “post” and “get” is a string in the form of “var1=value1&var2=value2&var3=value3” and so on, where the “var*” is the names of the submitted form elements and “value*” is their values respectively. And now it gets a bit more tricky, both the elements’ names and values are url-encoded. That means that almost every non alphanumeric character will be encoded as %XX, where XX represents its ASCII value (see the linked Wikipedia article for more information and extra reading). So to sum up the process of processing forms in CGI you should do the following:
Get the data (either by “post” or “get”).
Parse the data to get key-value pairs.
Decode the url-encoded key-value pairs.
Process the data.
Getting the first and last step done is easy. The second and third step require some work, but fortunately when done properly they should only have to be done once, as you will create functions/classes to handle those, so it is really only a one time job. That leaves you only to do yourself the first and last steps.
As I said the second and third steps are troublesome only when not done before. Here is an implementation for those steps that I’ve written as a part of (yet unreleased) CGI library for C++. It implements functions that take the care of the first three steps and return to the user an STL map containing the form elements’ names in the key and their value in the map pair’s value. This functions allows to process forms in a similar way to processing forms in PHP using $_GET and $_POST.
Here is a simple example of processing a “get” form using the above getpost.h header file.
Processing forms is the basic function of any CGI script and the main purpose of CGIs. As you probably know there are two common ways to send form data back to the web server: “post” and “get”. When form data is sent with the “get” method it is appended to the URL string of the form submission URL. The “post” method is much like the “get” except the data is transmitted via http headers and not via the URL itself. When a form uses “get” it allows the user to easily bookmark the query created by the form as the data is transmitted in URL itself, on the other hand the “post” method allows to send much more data and spares to user from seeing the data in the URL.
Getting the “post” and “get” data is relatively easy. To get the data sent by “get” you can just call getenv("QUERY_STRING") and you will receive a pointer to null-terminated string containing the “get” data. Reading the “post” data is a bit more complicated. The data needs to be read from the standard input, but the program won’t receive an EOF when it reaches the end of the data but instead it should stop reading after reading a specified amount of bytes, which is defined in the environment variable “CONTENT_LENGTH“. So you should read getenv("CONTENT_LENGTH") bytes from the standard input to receive the “post” data.
But here it’s get tricky. The data is received in an encoded way. The data for both “post” and “get” is a string in the form of “var1=value1&var2=value2&var3=value3” and so on, where the “var*” is the names of the submitted form elements and “value*” is their values respectively. And now it gets a bit more tricky, both the elements’ names and values are url-encoded. That means that almost every non alphanumeric character will be encoded as %XX, where XX represents its ASCII value (see the linked Wikipedia article for more information and extra reading). So to sum up the process of processing forms in CGI you should do the following:
Get the data (either by “post” or “get”).
Parse the data to get key-value pairs.
Decode the url-encoded key-value pairs.
Process the data.
Getting the first and last step done is easy. The second and third step require some work, but fortunately when done properly they should only have to be done once, as you will create functions/classes to handle those, so it is really only a one time job. That leaves you only to do yourself the first and last steps.
As I said the second and third steps are troublesome only when not done before. Here is an implementation for those steps that I’ve written as a part of (yet unreleased) CGI library for C++. It implements functions that take the care of the first three steps and return to the user an STL map containing the form elements’ names in the key and their value in the map pair’s value. This functions allows to process forms in a similar way to processing forms in PHP using $_GET and $_POST.
Here is a simple example of processing a “get” form using the above getpost.h header file.
- Code:
#include <iostream>
#include <string>
#include <map>
#include "getpost.h"
using namespace std;
int main()
{
map<string,string> Get;
initializeGet(Get); //notice that the variable is passed by reference!
cout<<"Content-type: text/html"<<endl<<endl;
cout<<"<html><body>"<<endl;
cout<<"<h1>Processing forms</h1>"<<endl;
cout<<"<form method=\"get\">"<<endl;
cout<<" <label for=\"fname\">First name: </label>"<<endl;
cout<<" <input type=\"text\" name=\"fname\" id=\"fname\"><br>"<<endl;
cout<<" <label for=\"lname\">Last name: </label>"<<endl;
cout<<" <input type=\"text\" name=\"lname\" id=\"lname\"><br>"<<endl;
cout<<" <input type=\"submit\" />"<<endl;
cout<<"</form>
"<<endl;
if (Get.find("fname")!=Get.end() && Get.find("lname")!=Get.end()) {
cout<<"Hello "<<Get["fname"]<<" "<<Get["lname"]<<", isn\'t "
"processing CGI forms with C++ quite easy?"<<endl;
} else {
cout<<"Fill up the above from and press submit"<<endl;
}
cout<<"</body></html>"<<endl;
return 0;
}
While this is a simple example, it’s enough to demonstarte how stuff is done. The same way you can process the “post” variables. Feel free to take a look at the getpost.h source-code to see how the URL decoding and the other implementation aspects were done.