1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434
|
=head1 NAME
Introducing mod_perl Handlers
=head1 Description
This chapter provides an introduction into mod_perl handlers.
=head1 What are Handlers?
Apache distinguishes between numerous phases for which it provides
hooks (because the C functions are called
I<ap_hook_E<lt>phase_nameE<gt>>) where modules can plug various
callbacks to extend and alter the default behavior of the webserver.
mod_perl provides a Perl interface for most of the available hooks, so
mod_perl modules writers can change the Apache behavior in Perl. These
callbacks are usually referred to as I<handlers> and therefore the
configuration directives for the mod_perl handlers look like:
C<PerlFooHandler>, where C<Foo> is one of the handler names. For
example C<PerlResponseHandler> configures the response callback.
A typical handler is simply a perl package with a I<handler>
subroutine. For example:
file:MyApache2/CurrentTime.pm
----------------------------
package MyApache2::CurrentTime;
use strict;
use warnings;
use Apache2::RequestRec ();
use Apache2::RequestIO ();
use Apache2::Const -compile => qw(OK);
sub handler {
my $r = shift;
$r->content_type('text/plain');
$r->print("Now is: " . scalar(localtime) . "\n");
return Apache2::Const::OK;
}
1;
This handler simply returns the current date and time as a
response.
Since this is a response handler, we configure it as a such in
I<httpd.conf>:
PerlResponseHandler MyApache2::CurrentTime
Since the response handler should be configured for a specific
location, let's write a complete configuration section:
PerlModule MyApache2::CurrentTime
<Location /time>
SetHandler modperl
PerlResponseHandler MyApache2::CurrentTime
</Location>
Now when a request is issued to I<http://localhost/time> this response
handler is executed and a response that includes the current time is
returned to the client.
=head1 Handler Return Values
Different handler groups are supposed to return different values.
Make sure that you B<always> explicitly return a wanted value and
don't rely on the result of last expression to be used as the return
value -- things will change in the future and you won't know why
things aren't working anymore.
The only value that can be returned by all handlers is
C<Apache2::Const::OK>, which tells Apache that the handler has
successfully finished its execution.
C<Apache2::Const::DECLINED> is another return value that indicates
success, but it's only relevant for
L<phases|docs::2.0::user::handlers::intro/Stacked_Handlers> of type
C<L<RUN_FIRST|/RUN_FIRST>>.
L<HTTP handlers|docs::2.0::user::handlers::http> may also return
C<Apache2::Const::DONE> which tells Apache to stop the normal L<HTTP
request
cycle|docs::2.0::user::handlers::http/HTTP_Request_Cycle_Phases> and
fast forward to the
C<L<PerlLogHandler|docs::2.0::user::handlers::http/PerlLogHandler>>,
followed by
C<L<PerlCleanupHandler|docs::2.0::user::handlers::http/PerlCleanupHandler>>.
L<HTTP handlers|docs::2.0::user::handlers::http> may return any HTTP
status, which similarly to C<Apache2::Const::DONE> will cause an abort
of the request cycle, by also will be interpreted as an
error. Therefore you don't want to return C<Apache2::Const::HTTP_OK>
from your HTTP response handler, but C<Apache2::Const::OK> and Apache
will send the C<200 OK> status by itself.
L<Filter handlers|docs::2.0::user::handlers::filters> return
C<Apache2::Const::OK> to indicate that the filter has successfully
finished. If the return value is C<Apache2::Const::DECLINED>, mod_perl
will read and forward the data on behalf of the filter. Please notice
that this feature is specific to mod_perl. If there is some problem
with obtaining or sending the bucket brigades, or the buckets in it,
filters need to return the error returned by the method that tried to
manipulate the bucket brigade or the bucket. Normally it'd be an
C<L<APR::|docs::2.0::api::APR::Const>> constant.
L<Protocol handler|docs::2.0::user::handlers::protocols> return values
aren't really handled by Apache, the handler is supposed to take care
of any errors by itself. The only special case is the
C<L<PerlPreConnectionHandler|docs::2.0::user::handlers::protocols/PerlPreConnectionHandler>>
handler, which, if returning anything but C<Apache2::Const::OK> or
C<Apache2::Const::DONE>, will prevent from
C<L<PerlConnectionHandler|docs::2.0::user::handlers::protocols/PerlConnectionHandler>>
to be run.
C<L<PerlPreConnectionHandler|docs::2.0::user::handlers::protocols/PerlPreConnectionHandler>>
handlers should always return C<Apache2::Const::OK>.
=head1 mod_perl Handlers Categories
The mod_perl handlers can be divided by their application scope in
several categories:
=over
=item * L<Server life cycle|docs::2.0::user::handlers::server/>
=over
=item * C<L<PerlOpenLogsHandler|docs::2.0::user::handlers::server/C_PerlOpenLogsHandler_>>
=item * C<L<PerlPostConfigHandler|docs::2.0::user::handlers::server/C_PerlPostConfigHandler_>>
=item * C<L<PerlChildInitHandler|docs::2.0::user::handlers::server/C_PerlChildInitHandler_>>
=item * C<L<PerlChildExitHandler|docs::2.0::user::handlers::server/C_PerlChildExitHandler_>>
=back
=item * L<Protocols|docs::2.0::user::handlers::protocols/>
=over
=item * C<L<PerlPreConnectionHandler|docs::2.0::user::handlers::protocols/PerlPreConnectionHandler>>
=item * C<L<PerlProcessConnectionHandler|docs::2.0::user::handlers::protocols/PerlProcessConnectionHandler>>
=back
=item * L<Filters|docs::2.0::user::handlers::filters/>
=over
=item * C<L<PerlInputFilterHandler|docs::2.0::user::handlers::filters/C_PerlInputFilterHandler_>>
=item * C<L<PerlOutputFilterHandler|docs::2.0::user::handlers::filters/C_PerlOutputFilterHandler_>>
=back
=item * L<HTTP Protocol|docs::2.0::user::handlers::http/>
=over
=item * C<L<PerlPostReadRequestHandler|docs::2.0::user::handlers::http/PerlPostReadRequestHandler>>
=item * C<L<PerlTransHandler|docs::2.0::user::handlers::http/PerlTransHandler>>
=item * C<L<PerlMapToStorageHandler|docs::2.0::user::handlers::http/PerlMapToStorageHandler>>
=item * C<L<PerlInitHandler|docs::2.0::user::handlers::http/PerlInitHandler>>
=item * C<L<PerlHeaderParserHandler|docs::2.0::user::handlers::http/PerlHeaderParserHandler>>
=item * C<L<PerlAccessHandler|docs::2.0::user::handlers::http/PerlAccessHandler>>
=item * C<L<PerlAuthenHandler|docs::2.0::user::handlers::http/PerlAuthenHandler>>
=item * C<L<PerlAuthzHandler|docs::2.0::user::handlers::http/PerlAuthzHandler>>
=item * C<L<PerlTypeHandler|docs::2.0::user::handlers::http/PerlTypeHandler>>
=item * C<L<PerlFixupHandler|docs::2.0::user::handlers::http/PerlFixupHandler>>
=item * C<L<PerlResponseHandler|docs::2.0::user::handlers::http/PerlResponseHandler>>
=item * C<L<PerlLogHandler|docs::2.0::user::handlers::http/PerlLogHandler>>
=item * C<L<PerlCleanupHandler|docs::2.0::user::handlers::http/PerlCleanupHandler>>
=back
=back
=head1 Stacked Handlers
For each phase there can be more than one handler assigned (also known
as I<hooks>, because the C functions are called
I<ap_hook_E<lt>phase_nameE<gt>>). Phases' behavior varies when there
is more then one handler registered to run for the same phase. The
following table specifies each handler's behavior in this situation:
Directive Type
--------------------------------------
PerlOpenLogsHandler RUN_ALL
PerlPostConfigHandler RUN_ALL
PerlChildInitHandler VOID
PerlChildExitHandler VOID
PerlPreConnectionHandler RUN_ALL
PerlProcessConnectionHandler RUN_FIRST
PerlPostReadRequestHandler RUN_ALL
PerlTransHandler RUN_FIRST
PerlMapToStorageHandler RUN_FIRST
PerlInitHandler RUN_ALL
PerlHeaderParserHandler RUN_ALL
PerlAccessHandler RUN_ALL
PerlAuthenHandler RUN_FIRST
PerlAuthzHandler RUN_FIRST
PerlTypeHandler RUN_FIRST
PerlFixupHandler RUN_ALL
PerlResponseHandler RUN_FIRST
PerlLogHandler RUN_ALL
PerlCleanupHandler RUN_ALL
PerlInputFilterHandler VOID
PerlOutputFilterHandler VOID
Note:
C<L<PerlChildExitHandler|docs::2.0::user::handlers::http/C_PerlChildExitHandler_>>
and
C<L<PerlCleanupHandler|docs::2.0::user::handlers::http/PerlCleanupHandler>>
are not real Apache hooks, but to mod_perl users they behave as all
other hooks.
And here is the description of the possible types:
=head2 C<VOID>
Handlers of the type C<VOID> will be I<all> executed in the order they
have been registered disregarding their return values. Though in
mod_perl they are expected to return C<Apache2::Const::OK>.
=head2 C<RUN_FIRST>
Handlers of the type C<RUN_FIRST> will be executed in the order they
have been registered until the first handler that returns something
other than C<Apache2::Const::DECLINED>. If the return value is
C<Apache2::Const::DECLINED>, the next handler in the chain will be run. If the
return value is C<Apache2::Const::OK> the next phase will start. In all other
cases the execution will be aborted.
=head2 C<RUN_ALL>
Handlers of the type C<RUN_ALL> will be executed in the order they
have been registered until the first handler that returns something
other than C<Apache2::Const::OK> or C<Apache2::Const::DECLINED>.
For C API declarations see I<include/ap_config.h>, which includes
other types which aren't exposed by mod_perl handlers.
Also see L<mod_perl Directives Argument Types and Allowed
Location|docs::2.0::user::config::config/mod_perl_Directives_Argument_Types_and_Allowed_Location>
=head1 Hook Ordering (Position)
The following constants specify how the new hooks (handlers) are
inserted into the list of hooks when there is at least one hook
already registered for the same phase.
META: Not working yet.
META: need to verify the following:
=over
=item * C<APR::Const::HOOK_REALLY_FIRST>
run this hook first, before ANYTHING.
=item * C<APR::Const::HOOK_FIRST>
run this hook first.
=item * C<APR::Const::HOOK_MIDDLE>
run this hook somewhere.
=item * C<APR::Const::HOOK_LAST>
run this hook after every other hook which is defined.
=item * C<APR::Const::HOOK_REALLY_LAST>
run this hook last, after EVERYTHING.
=back
META: more information in mod_example.c talking about
position/predecessors, etc.
=head1 Bucket Brigades
Apache 2.0 allows multiple modules to filter both the request and the
response. Now one module can pipe its output as an input to another
module as if another module was receiving the data directly from the
TCP stream. The same mechanism works with the generated response.
With I/O filtering in place, simple filters, like data compression and
decompression, can be easily implemented and complex filters, like
SSL, are now possible without needing to modify the the server code
which was the case with Apache 1.3.
In order to make the filtering mechanism efficient and avoid
unnecessary copying, while keeping the data abstracted, the I<Bucket
Brigades> technology was introduced. It's also used in L<protocol
handlers|docs::2.0::user::handlers::protocols>.
A bucket represents a chunk of data. Buckets linked together comprise
a brigade. Each bucket in a brigade can be modified, removed and
replaced with another bucket. The goal is to minimize the data copying
where possible. Buckets come in different types, such as files, data
blocks, end of stream indicators, pools, etc. To manipulate a bucket
one doesn't need to know its internal representation.
The stream of data is represented by bucket brigades. When a filter
is called it gets passed the brigade that was the output of the
previous filter. This brigade is then manipulated by the filter (e.g.,
by modifying some buckets) and passed to the next filter in the stack.
The following figure depicts an imaginary bucket brigade:
=for html
<img src="bucket_brigades.gif" width="590" height="400"
align="middle" alt="bucket brigades"><br><br>
The figure tries to show that after the presented bucket brigade has
passed through several filters some buckets were removed, some
modified and some added. Of course the handler that gets the brigade
cannot tell the history of the brigade, it can only see the existing
buckets in the brigade.
Bucket brigades are discussed in detail in the L<protocol
handlers|docs::2.0::user::handlers::protocols> and L<I/O
filtering|docs::2.0::user::handlers::filters> chapters.
=head1 Maintainers
Maintainer is the person(s) you should contact with updates,
corrections and patches.
=over
=item *
Stas Bekman [http://stason.org/]
=back
=head1 Authors
=over
=item *
=back
Only the major authors are listed above. For contributors see the
Changes file.
=cut
|