|  | Home | Libraries | People | FAQ | More | 
| ![[Tip]](../../../doc/html/images/tip.png) | Tip | 
|---|---|
| If you are familiar with the CGI protocol, you can skip straight to the 10 Minute Intro. | 
CGI is a simple protocol for writing dynamic web-enabled applications. The protocol's simplicity is key to its success, but the simplicity brings with it some limitations.
By far the most significant limitation is that a CGI program handles one request before exiting. If handling a request involves resources that are expensive to initialise (eg. opening a database), then CGI may not scale as well as you would like. For true scalability, you may want FastCGI.
The following example is generated from the linked source file.
#include <boost/cgi/cgi.hpp> namespace cgi = boost::cgi;
int handle_request(cgi::request& req, cgi::response& resp) {
if (req.cookies.count("user_name")) {
if (req.get.pick<std::string>("reset", "") == "1") { resp<< cgi::cookie("user_name")
<< cgi::redirect(req, req.script_name())
<< cgi::content_type("text/plain"); } else { std::string user_name( req.cookies["user_name"] );
if (!user_name.empty()) { resp<< cgi::content_type("text/html") << "<p>Hello there, " << req.cookies["user_name"] << ". How are you?</p>" << "<a href=\"" << req.script_name() << "?reset=1\">Reset</a>"; } }
} else
if (req.form.count("user_name")) { std::string user_name (req.form["user_name"]);
resp<< cgi::cookie("user_name", user_name) << cgi::header("Date", "Tue, 15 Nov 1994 08:12:31 GMT") << cgi::content_type("text/html") << "Hello there, " << user_name << ". You're new around here." << "user_name.length() = " << user_name.length() ; } else {
resp<< cgi::content_type("text/html") << "Hello there. What's your name?" "<p />" "<form method='POST'>" "<input type='text' name='user_name' />" "<input type='submit' />"; }
return cgi::commit(req, resp); }
int main(int, char**) { cgi::request req;
cgi::response resp;
return handle_request(req, resp); }
| A catch-all header is available which includes all of the headers you should need for CGI. 
          For the sake of clarity we alias the  
 | ||||||||||||||||||||||
| The first thing to do is write a handler function which takes a request and a response and does all request-specific work. Later, we will look at writing the code that calls this function. 
 | ||||||||||||||||||||||
| 
In our request handler, we will assume that the request has been fully-parsed
          and we can access all of the request data. The request data is available
          using public members of a  
          A CGI request has several types of variables available. These are listed
          in the table below, assuming that  
 Let's assume you now want to check if the user has a cookie, "user_name", set. We can check if a user has a cookie set like this: 
 | ||||||||||||||||||||||
| 
First, we need to be able to clear the cookie we are setting. We will reset
          the cookie if the user navigates to  
          The  
          One of them is  The default value can be any type that supports Boost.Lexical_cast. If the key isn't found in the map, or the value cannot be cast to the type of the default value, the default is returned. 
 | ||||||||||||||||||||||
| Set a cookie with no value to delete it. 
 | ||||||||||||||||||||||
| 
The  
 | ||||||||||||||||||||||
| 
Looking up a request cookie in  The lookup is case-insensitive, so "USER_NAME" and "User_Name" would be equivalent lookup keys. If the cookie is set, we'll be polite and say hello before quitting. 
 | ||||||||||||||||||||||
| That's all we want to say for now, so we can return. 
          If you are familiar with CGI programming, you will notice the lack of any
          HTTP headers in the response. A  
          If you don't explicitly set any response headers, a default header  
 | ||||||||||||||||||||||
| 
If the cookie isn't set, we will check if the user has posted a  
 | ||||||||||||||||||||||
| If they have told us their name, we should set a cookie so we remember it next time. Then we can say hello and exit. 
          There are two ways to set a cookie: either directly using  
          Again, the request object isn't buffered, so we are going to keep using
          the  This time, we shall send a Date header. If we do this (ie. send a header ourselves), we must also set the Content-type header, like below. 
 | ||||||||||||||||||||||
| 
Now, if we have no idea who they are, we'll send a form asking them for
          their name. As the default  
 | ||||||||||||||||||||||
| A CGI program will handle one request each time it is invoked. Returning a non-zero status to the OS indicates an error handling the request. I don't know that HTTP servers treat non-zero exit codes specially. [3] 
          To send the response back to the request, use  
 | ||||||||||||||||||||||
| We now have a request handler in all of it's contrived glory. 
          The program's  
 | ||||||||||||||||||||||
| 
At this point, the environment variables are accessible. This includes
          cookie and form variables too, which are all parsed by default-constructing
          a  
 | ||||||||||||||||||||||
| 
The  
          Writing to a  
          Not only does buffering avoid network latency issues, but being able to
          cancel the response and send another is much cleaner than sending half
          a response, followed by "...Ooops". A  When sending a response that is large relative to the amount of memory available to the program, you may want to write unbuffered. 
 |