This bucket type
references a file on the disk. When reading from
this bucket,
a new bucket is created in front of
the file bucket. The data that was read from
the file is stored in the new bucket. This is
done so that we only read from
the file once.
When writing to the network, we determine how
much of the data can be sent using sendfile.
This bucket
references MMAPed files. The data is treated
much like heap buckets,
except the data can not
be modified in the bucket. If the data needs to
be
modified, a heap bucket must be created and
the data must be copied into that
bucket.
This bucket
type is a generic bucket. Any data type is valid
in this bucket,
but the data must be managed
some external entity. This is designed for data
that
a module will create and destroy. Perhaps
tha best way to describe this is with
an
example. Mod_mmap_static keeps a cache of
mmap’ed files available to increase
the
performance of Apache. The mmap entities would
be immortal buckets.
Mod_mmap_static is in
charge of creating and destroying the mmaps, the
immortal
buckets just reference it.
This bucket
references data allocated out of a pool. Pool
data is garaunteed to
be available as long as
the pool is available. When this bucket is
created, a
cleanup is registered so that when
the pool is cleared, if the data is still
required the bucket is converted into a heap
bucket.
This
bucket references a pipe. Pipes are interesting,
because they destroy
themselves as they are
read. This means that if I have a pipe and I
read data
from it, I must save
that data someplace or it will be lost. To
accomplish this, when pipe buckets are read, a
second bucket is created in front
of the current
bucket. The new bucket is used to store the data
read from the
pipe. This is very similar to
file buckets, except that sendfile can’t be used
with pipes. Pipe buckets are most commonly used
to return data from CGI
scripts.
This bucket does not
contain any data. It signals filters that there
is will be
no more data generated for
consumption. This tells filters that this is the
final
time they will be called, so they need to
send any data that they have saved in
previous
calls
All buckets include pointers
to their accessor functions. The details of
what
these functions do is specific to each
bucket type, but we can explain them
generally.
- read
- split
- setaside
- destroy
returns a pointer to the
data stored in the bucket and the amount
of data
returned. Depending on the type of bucket read
from, the data can be
modified in place.
takes one bucket and splits it in
two at the specified offset into
the bucket
data.
converts a bucket from
one type to another. The purpose of this
function pointer
is to ensure that the data is
still available on the next call to the filter
function. If the filter must set data aside,
then it should loop through the
bucket brigade
and call the setaside function for any bucket
that has one.
destroys the
current bucket and any data that it references
and has the rights
to destroy. For example,
destorying an immortal bucket just destroys the
bucket,
but leaves the data alone.
There are just a few more concepts that we need
to cover in this overview of
filtering. The
first is registering a filter with the server.
This is done with
ap_register_filter.
void ap_register_filter(const char *name,
ap_filter_func filter_func,
ap_filter_type ftype);