Show Contents Previous Page Next Page
Chapter 10 - C API Reference Guide, Part I / Processing Requests Sending Files to the Client As we learned in Chapter 4, sending a plain
file over HTTP requires a few more considerations than one might think. Here
we list the C API functions upon which the Apache::File module is built:
int ap_set_content_length (request_rec *r, long length)
This method sets the outgoing Content-length
header based on the length argument. By using
this method, you avoid the hassle of converting the
long value to a string, along with saving a
few keystrokes. The return value is always zero and
can be safely ignored.
(void)ap_set_content_length(r, r->finfo.st_size);
void ap_set_etag (request_rec *r)
This method is used to set the outgoing ETag header, described
in Chapter 3 in the section "The
HTTP Protocol." Use this if your content handler is serving static files.
Sending the entity tag allows HTTP/1.1-compliant clients to intelligently
cache documents locally and only update them when they change on the server.
ap_set_etag(r);
time_t ap_update_mtime (request_rec *r, time_t dependency_mtime)
(Declared in the header file http_request.h.)
Browsers will cache static documents locally and update
them only when the server indicates they have changed.
They do this by comparing the current document's HTTP
Last-modified field to the value of this field
when the document was last cached. Apache derives the
Last-modified field from the request record's
mtime field, which by default is set to
the filesystem modification time of the requested file.
This default is appropriate for a document that is a
simple static file but not a document that is created
dynamically, for example, a server-side include file
that depends on one or more configuration files. In such cases, you can use this function to set the
mtime field to reflect the appropriate modification
time, taking into account any of the document's dependencies
on configuration files and other resources. Its two arguments
are the request record and dependency_mtime .
The mtime field will be updated if and only
if the current mtime is older than the dependency_mtime .
Therefore, if the final document depends on several configuration
files, it is safe to call ap_update_mtime() once
with the modification times of each configuration file.
At the end of this series of calls the mtime
field will be set to the most recent date, allowing the
Last-modified field to accurately reflect the
modification time of the requested document. Of course,
the true modification time of the requested file as reported
by the filesystem is unaffected by this maneuver. This function's return value is the value of the updated
mtime . If your handler is serving static files
without modifying them en route, you will not need to call
this function because Apache will already have set mtime
appropriately. Before sending the headers, you should also
be sure to call ap_set_last_modified() (discussed
next) in order to use the value of mtime to
create the Last-modified field in the outgoing
headers table. In the following example, we update the file's modification
time from a dependency on a configuration file named templates.conf:
struct stat conf_info;
char* conf_file = server_root_relative(r->pool, "conf/templates.conf");
if (stat(conf_file, &conf_info) == 0) {
ap_update_mtime(r, conf_info.st_mtime);
}
ap_set_last_modified(r);
void ap_set_last_modified (request_rec *r)
This method is used to set the Last-modified header
using the value of r->mtime . If mtime
is in the future, the header field will not be modified. This
function should be called whenever you are serving static
files or server-side include files and want the client to
be able to cache the document contents locally. You might
also want to use this function, in conjunction with ap_update_mtime(),
if you are creating documents from database records and have
some sort of timestamp in the records that enables you to
determine when the data was last changed.
ap_set_last_modified(r);
See also ap_update_mtime().
int ap_meets_conditions (request_rec *r)
As described in Chapter 9 in "The
Apache::File Class," the ap_meets_conditions() function is used
to implement "conditional GET" semantics.
if((rc = ap_meets_conditions(r) != OK) {
return rc;
}
int ap_discard_request_body (request_rec *r)
Also described in Chapter 9, this utility
function is used to throw away the request body.
if((rc = ap_discard_request_body(r) != OK) {
return rc;
}
long ap_send_ fd (FILE *f, request_rec *r)
The ap_send_ fd() function sends the
contents of the file pointed to by FILE * to the
client and returns the number of bytes transmitted. This is
a useful way to return a file to the client if you don't need
to modify it on the fly. In this example, we open the file
requested by the URI using the ap_pfopen() call.
If successful, we send its contents, then close the file.
FILE *f = ap_pfopen(r->pool, r->filename, "r");
if (f == NULL) {
return NOT_FOUND;
}
ap_send_fd(f, r);
ap_pfclose(r->pool, f);
long ap_send_ fd_length (FILE *f, request_rec *r, long length)
This function works like ap_send_fd(),
but only length bytes of data are sent. If you pass
a negative value for length, the entire file will
be sent, which, in fact, is what ap_send_fd()
does internally. The function result is the number of bytes
sent, or -1 if an error occurred before any bytes could be
sent. Show Contents Previous Page Next Page Copyright © 1999 by O'Reilly & Associates, Inc. |