The http class provides methods for generating HTTP headers. Two common applications of this class are No Parsed Header CGI's and Server-Push Multipart Documents.
When a cgi sends a response to the browser, it sends an http header followed by some data. The most common header is:
Content-type: text/html
This header indicates that the data will be an html page.
If you could see what headers the browser actually receives, you would see something like this:
HTTP/1.1 200 OK
Date: Fri, 09 Nov 2001 03:42:35 GMT
Server: Apache/1.3.12 (Unix) (Red Hat/Linux)
Connection: close
Content-type: text/html
The cgi sent Content-type: text/html and the web server sent the other headers. Browsers require the HTTP version and status, Server and Content-type headers. The web server sends whatever headers the cgi didn't send.
Since it's possible for cgi's to send any valid http headers, the web server has to parse the headers that the cgi sends so it can figure out exactly which headers were left out and insert them into the response without sending any of the same headers that the cgi sent. This takes time and would be unnecessary if the cgi just generated all of the headers and told the web server not to parse them.
Generating the headers requires invocation of a few http class methods. The web server knows not to parse the headers if the name of the cgi starts with "nph-". For example, mycgi.cgi might send a simple header which would need be parsed and completed by the web server but nph-mycgi.cgi would have to send a complete header because the nph- in the beginning of the name would instruct the web server not to parse or complete the header.
A regular CGI:
#include <groundwork/http.h>
#include <groundwork/cgimodule.h>
MAIN {
http h(APISTRUCT);
h.contentType("text","html",NULL);
h.cr();
... send some data ...
}
An nph CGI:
#include <groundwork/http.h>
#include <groundwork/cgimodule.h>
MAIN {
http h(APISTRUCT);
h.status("HTTP","1.1",http::ok);
h.server("Apache","1.13.19");
h.contentType("text","html",NULL);
h.cr();
... send some data ...
}
Most data served from web-based applications is served in single-part documents. Single-part documents consist of an http header followed by some data. Pages of html or text, images or movies are all single-part documents.
Multipart documents consist of an http header indicating that it is a multipart document followed by a boundary string, another header, some data, another boundary string, another header, more data, and so on, ultimately terminated by a terminating boundary string.
The most common use for multipart documents is server-push animation. Most browsers support this feature. Here's an example:
The following cgi serves a series of images named image0.gif through image9.gif, sleeping for 1 second between images. The sequence is repeated 5 times.
#include <groundwork/http.h>
#include <groundwork/cgimodule.h>
#include <unistd.h>
MAIN {
http h(APISTRUCT);
// send http header
h.multiPartContentType("x-mixed-replace",NULL,h.boundaryString());
// loop, sending the series of images 5 times
for (int i=0; i<5; i++) {
for (int j=0; j<10; j++) {
// send the a boundary string
h.multiPartBoundary(NULL);
if (i>0) {
sleep(1);
}
h.contentType("image","gif",NULL);
h.cr();
// send the image
strstream imagename;
imagename << "image" << j;
imagename << ".gif" << ends;
ifstream imagefile(imagename.str());
h.output(APISTRUCT,NULL,imagefile.rdbuf());
}
}
// send the final boundary string
h.multiPartEnd(NULL);
}
Now, in an html page, use an img tag with a src attribute that refers to the cgi instead of to a static image file.
<img src="serverpush.cgi">
This is the most common use for multipart documents but you could use them for other things. In our example, each part of the multipart document is the same type of data (an image) and we used mime-type multipart/x-mixed-replace to tell the browser to replace each image with the next image. But these are not requirements. Each part of a multipart document can be a different type of data, as long as the type of data matches the mime-type sent in that part's header. The mime type of the entire document doesn't have to be multipart/x-mixed-replace either. It could simply be multipart/mixed. For example, if you want to serve a word-processor document with external images linked into it, you could send the document and images in seperate parts of the same multipart document. Of course, the browser would have to know what to do with the multipart document. You could potentially write an application that knows how to parse such a document and configure your browser to hand off documents with mime-type multipart/mixed to that application.