1=head1 NAME
2
3HTTP Handlers
4
5=head1 Description
6
7This chapter explains how to implement the HTTP protocol handlers in
8mod_perl.
9
10
11=head1 HTTP Request Handler Skeleton
12
13All HTTP Request handlers have the following structure:
14
15  package MyApache2::MyHandlerName;
16
17  # load modules that are going to be used
18  use ...;
19
20  # compile (or import) constants
21  use Apache2::Const -compile => qw(OK);
22
23  sub handler {
24      my $r = shift;
25
26      # handler code comes here
27
28      return Apache2::Const::OK; # or another status constant
29  }
30  1;
31
32First, the package is declared. Next, the modules that are going to be
33used are loaded and constants compiled.
34
35The handler itself coming next and usually it receives the only
36argument: the
37C<L<Apache2::RequestRec|docs::2.0::api::Apache2::RequestRec>> object.
38If the handler is declared as L<a method handler
39|docs::2.0::user::coding::coding/Method_Handlers>:
40
41  sub handler : method {
42      my ($class, $r) = @_;
43
44the handler receives two arguments: the class name and the
45C<L<Apache2::RequestRec|docs::2.0::api::Apache2::RequestRec>> object.
46
47The handler ends with L<a return
48code|docs::2.0::user::handlers::intro/Stacked_Handlers> and the file
49is ended with C<1;> to return true when it gets loaded.
50
51
52
53
54
55
56=head1 HTTP Request Cycle Phases
57
58Those familiar with mod_perl 1.0 will find the HTTP request cycle in
59mod_perl 2.0 to be almost identical to the mod_perl 1.0's model. The
60different things are:
61
62=over
63
64=item *
65
66a new directive C<L<PerlMapToStorageHandler|/PerlMapToStorageHandler>>
67was added to match the new phase I<map_to_storage> added by Apache
682.0.
69
70=item *
71
72the C<PerlHandler> directive has been renamed to
73C<PerlResponseHandler> to better match the corresponding Apache phase
74name (I<response>).
75
76=item *
77
78the I<response> phase now includes filtering.
79
80=back
81
82The following diagram depicts the HTTP request life cycle and
83highlights which handlers are available to mod_perl 2.0:
84
85=for html
86<img src="http_cycle.gif" width="600" height="560"
87 align="middle" alt="HTTP cycle"><br><br>
88
89From the diagram it can be seen that an HTTP request is processed by
9012 phases, executed in the following order:
91
92=over
93
94=item 1 PerlPostReadRequestHandler (PerlInitHandler)
95
96=item 2 PerlTransHandler
97
98=item 3 PerlMapToStorageHandler
99
100=item 4 PerlHeaderParserHandler (PerlInitHandler)
101
102=item 5 PerlAccessHandler
103
104=item 6 PerlAuthenHandler
105
106=item 7 PerlAuthzHandler
107
108=item 8 PerlTypeHandler
109
110=item 9 PerlFixupHandler
111
112=item 10 PerlResponseHandler
113
114=item 11 PerlLogHandler
115
116=item 12 PerlCleanupHandler
117
118=back
119
120It's possible that the cycle will not be completed if any of the
121phases terminates it, usually when an error happens. In that case
122Apache skips to the logging phase (mod_perl executes all registered
123C<PerlLogHandler> handlers) and finally the cleanup phase happens.
124
125Notice that when the response handler is reading the input data it can
126be filtered through request input filters, which are preceded by
127connection input filters if any. Similarly the generated response is
128first run through request output filters and eventually through
129connection output filters before it's sent to the client. We will talk
130about filters in detail later in L<the dedicated to filters
131chapter|docs::2.0::user::handlers::filters>.
132
133Before discussing each handler in detail remember that if you use
134L<the stacked handlers
135feature|docs::2.0::user::handlers::intro/Stacked_Handlers> all
136handlers in the chain will be run as long as they return C<Apache2::Const::OK>
137or C<Apache2::Const::DECLINED>. Because stacked handlers is a special case. So
138don't be surprised if you've returned C<Apache2::Const::OK> and the next
139handler was still executed. This is a feature, not a bug.
140
141Now let's discuss each of the mentioned handlers in detail.
142
143
144
145
146
147
148
149
150
151
152
153
154
155=head2 PerlPostReadRequestHandler
156
157The I<post_read_request> phase is the first request phase and happens
158immediately after the request has been read and HTTP headers were
159parsed.
160
161This phase is usually used to do processing that must happen once per
162request. For example C<Apache2::Reload> is usually invoked at this
163phase to reload modified Perl modules.
164
165This phase is of type
166C<L<RUN_ALL|docs::2.0::user::handlers::intro/item_RUN_ALL>>.
167
168The handler's configuration scope is
169C<L<SRV|docs::2.0::user::config::config/item_SRV>>, because at this
170phase the request has not yet been associated with a particular
171filename or directory.
172
173B<Arguments>
174
175See the L<HTTP Request Handler Skeleton|docs::2.0::user::handlers::http/HTTP_Request_Handler_Skeleton> for a description of handler arguments.
176
177B<Return>
178
179See L<Stacked Handlers|docs::2.0::user::handlers::intro/Stacked_Handlers>
180for a description of handler return codes.
181
182B<Examples>
183
184Now, let's look at an example. Consider the following registry script:
185
186  #file:touch.pl
187  #-------------
188  use strict;
189  use warnings;
190
191  use Apache2::ServerUtil ();
192  use Apache2::RequestIO ();
193  use File::Spec::Functions qw(catfile);
194
195  my $r = shift;
196  $r->content_type('text/plain');
197
198  my $conf_file = catfile Apache2::ServerUtil::server_root,
199    "conf", "httpd.conf";
200
201  printf "$conf_file is %0.2f minutes old\n", 60*24*(-M $conf_file);
202
203This registry script is supposed to print when the last time
204I<httpd.conf> has been modified, compared to the start of the request
205process time. If you run this script several times you might be
206surprised that it reports the same value all the time. Unless the
207request happens to be served by a recently started child process which
208will then report a different value. But most of the time the value
209won't be reported correctly.
210
211This happens because the C<-M> operator reports the difference between
212file's modification time and the value of a special Perl variable
213C<$^T>. When we run scripts from the command line, this variable is
214always set to the time when the script gets invoked. Under mod_perl
215this variable is getting preset once when the child process starts and
216doesn't change since then, so all requests see the same time, when
217operators like C<-M>, C<-C> and C<-A> are used.
218
219Armed with this knowledge, in order to make our code behave similarly
220to the command line programs we need to reset C<$^T> to the request's
221start time, before C<-M> is used. We can change the script itself, but
222what if we need to do the same change for several other scripts and
223handlers? A simple C<PerlPostReadRequestHandler> handler, which will
224be executed as the very first thing of each requests, comes handy
225here:
226
227  #file:MyApache2/TimeReset.pm
228  #--------------------------
229  package MyApache2::TimeReset;
230
231  use strict;
232  use warnings;
233
234  use Apache2::RequestRec ();
235
236  use Apache2::Const -compile => 'OK';
237
238  sub handler {
239      my $r = shift;
240      $^T = $r->request_time;
241      return Apache2::Const::OK;
242  }
243  1;
244
245We could do:
246
247  $^T = time();
248
249But to make things more efficient we use C<$r-E<gt>request_time> since
250the request object C<$r> already stores the request's start time, so
251we get it without performing an additional system call.
252
253To enable it just add to I<httpd.conf>:
254
255  PerlPostReadRequestHandler MyApache2::TimeReset
256
257either to the global section, or to the C<E<lt>VirtualHostE<gt>>
258section if you want this handler to be run only for a specific virtual
259host.
260
261
262
263
264
265
266=head2 PerlTransHandler
267
268The I<translate> phase is used to perform the manipulation of a
269request's URI. If no custom handler is provided, the server's standard
270translation rules (e.g., C<Alias> directives, mod_rewrite, etc.) will
271be used. A C<PerlTransHandler> handler can alter the default
272translation mechanism or completely override it. This is also a good
273place to register new handlers for the following phases based on the
274URI. C<L<PerlMapToStorageHandler|/PerlMapToStorageHandler>> is to be
275used to override the URI to filename translation.
276
277This phase is of type
278C<L<RUN_FIRST|docs::2.0::user::handlers::intro/item_RUN_FIRST>>.
279
280The handler's configuration scope is
281C<L<SRV|docs::2.0::user::config::config/item_SRV>>, because at this
282phase the request has not yet been associated with a particular
283filename or directory.
284
285B<Arguments>
286
287See the L<HTTP Request Handler Skeleton|docs::2.0::user::handlers::http/HTTP_Request_Handler_Skeleton> for a description of handler arguments.
288
289B<Return>
290
291See L<Stacked Handlers|docs::2.0::user::handlers::intro/Stacked_Handlers>
292for a description of handler return codes.
293
294B<Examples>
295
296There are many useful things that can be performed at this
297stage. Let's look at the example handler that rewrites request URIs,
298similar to what mod_rewrite does. For example, if your web-site was
299originally made of static pages, and now you have moved to a dynamic
300page generation chances are that you don't want to change the old
301URIs, because you don't want to break links for those who link to your
302site. If the URI:
303
304  http://example.com/news/20021031/09/index.html
305
306is now handled by:
307
308  http://example.com/perl/news.pl?date=20021031;id=09;page=index.html
309
310the following handler can do the rewriting work transparent to
311I<news.pl>, so you can still use the former URI mapping:
312
313  #file:MyApache2/RewriteURI.pm
314  #---------------------------
315  package MyApache2::RewriteURI;
316
317  use strict;
318  use warnings;
319
320  use Apache2::RequestRec ();
321
322  use Apache2::Const -compile => qw(DECLINED);
323
324  sub handler {
325      my $r = shift;
326
327      my ($date, $id, $page) = $r->uri =~ m|^/news/(\d+)/(\d+)/(.*)|;
328      $r->uri("/perl/news.pl");
329      $r->args("date=$date;id=$id;page=$page");
330
331      return Apache2::Const::DECLINED;
332  }
333  1;
334
335The handler matches the URI and assigns a new URI via C<$r-E<gt>uri()>
336and the query string via C<$r-E<gt>args()>. It then returns
337C<Apache2::Const::DECLINED>, so the next translation handler will get
338invoked, if more rewrites and translations are needed.
339
340Of course if you need to do a more complicated rewriting, this handler
341can be easily adjusted to do so.
342
343To configure this module simply add to I<httpd.conf>:
344
345  PerlTransHandler +MyApache2::RewriteURI
346
347
348
349
350
351
352=head2 PerlMapToStorageHandler
353
354The I<map_to_storage> phase is used to perform the translation of a
355request's URI into a corresponding filename. If no custom handler is
356provided, the server will try to walk the filesystem trying to find
357what file or directory corresponds to the request's URI. Since usually
358mod_perl handler don't have corresponding files on the filesystem, you
359will want to shortcut this phase and save quite a few CPU cycles.
360
361This phase is of type
362C<L<RUN_FIRST|docs::2.0::user::handlers::intro/item_RUN_FIRST>>.
363
364The handler's configuration scope is
365C<L<SRV|docs::2.0::user::config::config/item_SRV>>, because at this
366phase the request has not yet been associated with a particular
367filename or directory.
368
369B<Arguments>
370
371See the L<HTTP Request Handler Skeleton|docs::2.0::user::handlers::http/HTTP_Request_Handler_Skeleton> for a description of handler arguments.
372
373B<Return>
374
375See L<Stacked Handlers|docs::2.0::user::handlers::intro/Stacked_Handlers>
376for a description of handler return codes.
377
378B<Examples>
379
380For example if you don't want Apache to try to attempt to translate
381URI into a filename, just add a handler:
382
383  PerlMapToStorageHandler MyApache2::NoTranslation
384
385using the following code:
386
387  #file:MyApache2/NoTranslation.pm
388  #------------------------------
389  package MyApache2::NoTranslation;
390
391  use strict;
392  use warnings FATAL => 'all';
393
394  use Apache2::Const -compile => qw(OK);
395
396  sub handler {
397      my $r = shift;
398
399      # skip ap_directory_walk stat() calls
400      return Apache2::Const::OK;
401  }
402  1;
403
404But this can be done from F<httpd.conf> too!
405
406  PerlMapToStorageHandler Apache2::Const::OK
407
408If you haven't already compiled C<Apache2::Const::OK> elsewhere, you
409should add:
410
411  <Perl>
412      use Apache2::Const -compile => qw(OK);
413  </Perl>
414
415Apache also uses this phase to handle C<TRACE> requests. So if you
416shortcut it, C<TRACE> calls will be not handled. In case you need to
417handle such, you may rewrite it as:
418
419  #file:MyApache2/NoTranslation2.pm
420  #-------------------------------
421  package MyApache2::NoTranslation2;
422
423  use strict;
424  use warnings FATAL => 'all';
425
426  use Apache2::RequestRec ();
427
428  use Apache2::Const -compile => qw(DECLINED OK M_TRACE);
429
430  sub handler {
431      my $r = shift;
432
433      return Apache2::Const::DECLINED
434          if $r->method_number == Apache2::Const::M_TRACE;
435
436      # skip ap_directory_walk stat() calls
437      return Apache2::Const::OK;
438  }
439  1;
440
441BTW, the HTTP TRACE method asks a web server to echo the contents of
442the request back to the client for debugging purposes. i.e., the
443complete request, including HTTP headers, is returned in the
444entity-body of a TRACE response. Attackers may abuse HTTP TRACE
445functionality to gain access to information in HTTP headers such as
446cookies and authentication data. In the presence of other cross-domain
447vulnerabilities in web browsers, sensitive header information could be
448read from any domains that support the HTTP TRACE method.
449
450Another way to prevent the core translation is to set
451C<$r-E<gt>filename()> to some value, which can also be done in the
452C<L<PerlTransHandler|/PerlTransHandler>>, if you are already using it.
453
454
455
456
457
458
459
460
461=head2 PerlHeaderParserHandler
462
463The I<header_parser> phase is the first phase to happen after the
464request has been mapped to its C<E<lt>LocationE<gt>> (or an equivalent
465container). At this phase the handler can examine the request headers
466and to take a special action based on these. For example this phase
467can be used to block evil clients targeting certain resources, while
468little resources were wasted so far.
469
470This phase is of type
471C<L<RUN_ALL|docs::2.0::user::handlers::intro/item_RUN_ALL>>.
472
473The handler's configuration scope is
474C<L<DIR|docs::2.0::user::config::config/item_DIR>>.
475
476B<Arguments>
477
478See the L<HTTP Request Handler Skeleton|docs::2.0::user::handlers::http/HTTP_Request_Handler_Skeleton> for a description of handler arguments.
479
480B<Return>
481
482See L<Stacked Handlers|docs::2.0::user::handlers::intro/Stacked_Handlers>
483for a description of handler return codes.
484
485B<Examples>
486
487This phase is very similar to
488C<L<PerlPostReadRequestHandler|/PerlPostReadRequestHandler>>, with the
489only difference that it's run after the request has been mapped to the
490resource. Both phases are useful for doing something once per request,
491as early as possible. And usually you can take any
492C<L<PerlPostReadRequestHandler|/PerlPostReadRequestHandler>> and turn
493it into C<L<PerlHeaderParserHandler|/PerlHeaderParserHandler>> by
494simply changing the directive name in I<httpd.conf> and moving it
495inside the container where it should be executed. Moreover, because of
496this similarity mod_perl provides a special directive
497C<L<PerlInitHandler|/PerlInitHandler>> which if found outside resource
498containers behaves as
499C<L<PerlPostReadRequestHandler|/PerlPostReadRequestHandler>>,
500otherwise as C<L<PerlHeaderParserHandler|/PerlHeaderParserHandler>>.
501
502You already know that Apache handles the C<HEAD>, C<GET>, C<POST> and
503several other HTTP methods. But did you know that you can invent your
504own HTTP method as long as there is a client that supports it. If you
505think of emails, they are very similar to HTTP messages: they have a
506set of headers and a body, sometimes a multi-part body. Therefore we
507can develop a handler that extends HTTP by adding a support for the
508C<EMAIL> method.  We can enable this protocol extension and push the
509real content handler during the
510C<L<PerlHeaderParserHandler|/PerlHeaderParserHandler>> phase:
511
512  <Location /email>
513      PerlHeaderParserHandler MyApache2::SendEmail
514  </Location>
515
516and here is the C<MyApache2::SendEmail> handler:
517
518  #file:MyApache2/SendEmail.pm
519  #--------------------------
520  package MyApache2::SendEmail;
521
522  use strict;
523  use warnings;
524
525  use Apache2::RequestRec ();
526  use Apache2::RequestIO ();
527  use Apache2::RequestUtil ();
528  use Apache2::ServerUtil ();
529  use Apache2::ServerRec ();
530  use Apache2::Process ();
531  use APR::Table ();
532
533  use Apache2::Const -compile => qw(DECLINED OK);
534
535  use constant METHOD        => 'EMAIL';
536  use constant SMTP_HOSTNAME => "localhost";
537
538  sub handler {
539      my $r = shift;
540
541      return Apache2::Const::DECLINED unless $r->method eq METHOD;
542
543      $r->server->method_register(METHOD);
544      $r->handler("perl-script");
545      $r->push_handlers(PerlResponseHandler => \&send_email_handler);
546
547      return Apache2::Const::OK;
548  }
549
550  sub send_email_handler {
551      my $r = shift;
552
553      my %headers = map {$_ => $r->headers_in->get($_)}
554		qw(To From Subject);
555
556	  my $content = content($r);
557
558      my $status = send_email(\%headers, \$content);
559
560      $r->content_type('text/plain');
561      $r->print($status ? "ACK" : "NACK");
562      return Apache2::Const::OK;
563  }
564
565  sub send_email {
566      my ($rh_headers, $r_body) = @_;
567
568      require MIME::Lite;
569      MIME::Lite->send("smtp", SMTP_HOSTNAME, Timeout => 60);
570
571      my $msg = MIME::Lite->new(%$rh_headers, Data => $$r_body);
572      #warn $msg->as_string;
573      $msg->send;
574  }
575
576  use APR::Brigade ();
577  use APR::Bucket ();
578
579  use Apache2::Const -compile => qw(MODE_READBYTES);
580  use APR::Const    -compile => qw(SUCCESS BLOCK_READ);
581
582  use constant IOBUFSIZE => 8192;
583
584  sub content {
585      my $r = shift;
586
587      my $bb = APR::Brigade->new($r->pool, $r->connection->bucket_alloc);
588
589      my $data = '';
590      my $seen_eos = 0;
591      do {
592          $r->input_filters->get_brigade($bb,
593			  Apache2::Const::MODE_READBYTES,
594              APR::Const::BLOCK_READ, IOBUFSIZE);
595
596          for (my $b = $bb->first; $b; $b = $bb->next($b)) {
597              if ($b->is_eos) {
598                  $seen_eos++;
599                  last;
600              }
601
602              if ($b->read(my $buf)) {
603                  $data .= $buf;
604              }
605
606              $b->remove; # optimization to reuse memory
607          }
608      } while (!$seen_eos);
609
610      $bb->destroy;
611
612      return $data;
613  }
614
615  1;
616
617Let's get the less interesting code out of the way. The function
618content() grabs the request body. The function send_email() sends the
619email over SMTP. You should adjust the constant C<SMTP_HOSTNAME> to
620point to your outgoing SMTP server. You can replace this function with
621your own if you prefer to use a different method to send email.
622
623Now to the more interesting functions. The function C<handler()>
624returns immediately and passes the control to the next handler if the
625request method is not equal to C<EMAIL> (set in the C<METHOD>
626constant):
627
628      return Apache2::Const::DECLINED unless $r->method eq METHOD;
629
630Next it tells Apache that this new method is a valid one and that the
631C<perl-script> handler will do the processing.
632
633      $r->server->method_register(METHOD);
634      $r->handler("perl-script");
635
636Finally it pushes the function C<send_email_handler()> to the
637C<PerlResponseHandler> list of handlers:
638
639      $r->push_handlers(PerlResponseHandler => \&send_email_handler);
640
641The function terminates the header_parser phase by:
642
643      return Apache2::Const::OK;
644
645All other phases run as usual, so you can reuse any HTTP protocol
646hooks, such as authentication and fixup phases.
647
648When the response phase starts C<send_email_handler()> is invoked,
649assuming that no other response handlers were inserted before it.  The
650response handler consists of three parts. Retrieve the email headers
651C<To>, C<From> and C<Subject>, and the body of the message:
652
653      my %headers = map {$_ => $r->headers_in->get($_)}
654	    qw(To From Subject);
655      my $content = $r->content;
656
657Then send the email:
658
659      my $status = send_email(\%headers, \$content);
660
661Finally return to the client a simple response acknowledging that
662email has been sent and finish the response phase by returning
663C<Apache2::Const::OK>:
664
665      $r->content_type('text/plain');
666      $r->print($status ? "ACK" : "NACK");
667      return Apache2::Const::OK;
668
669Of course you will want to add extra validations if you want to use
670this code in production. This is just a proof of concept
671implementation.
672
673As already mentioned when you extend an HTTP protocol you need to have
674a client that knows how to use the extension. So here is a simple
675client that uses C<LWP::UserAgent> to issue an C<EMAIL> method request
676over HTTP protocol:
677
678  #file:send_http_email.pl
679  #-----------------------
680  #!/usr/bin/perl
681
682  use strict;
683  use warnings;
684
685  require LWP::UserAgent;
686
687  my $url = "http://localhost:8000/email/";
688
689  my %headers = (
690      From    => 'example@example.com',
691      To      => 'example@example.com',
692      Subject => '3 weeks in Tibet',
693  );
694
695  my $content = <<EOI;
696  I didn't have an email software,
697  but could use HTTP so I'm sending it over HTTP
698  EOI
699
700  my $headers = HTTP::Headers->new(%headers);
701  my $req = HTTP::Request->new("EMAIL", $url, $headers, $content);
702  my $res = LWP::UserAgent->new->request($req);
703  print $res->is_success ? $res->content : "failed";
704
705most of the code is just a custom data. The code that does something
706consists of four lines at the very end. Create C<HTTP::Headers> and
707C<HTTP::Request> object. Issue the request and get the
708response. Finally print the response's content if it was successful or
709just I<"failed"> if not.
710
711Now save the client code in the file I<send_http_email.pl>, adjust the
712I<To> field, make the file executable and execute it, after you have
713restarted the server. You should receive an email shortly to the
714address set in the I<To> field.
715
716
717
718
719
720=head2 PerlInitHandler
721
722When configured inside any container directive, except
723C<E<lt>VirtualHostE<gt>>, this handler is an alias for
724C<L<PerlHeaderParserHandler|/PerlHeaderParserHandler>> described
725earlier.  Otherwise it acts as an alias for
726C<L<PerlPostReadRequestHandler|/PerlPostReadRequestHandler>> described
727earlier.
728
729It is the first handler to be invoked when serving a request.
730
731This phase is of type
732C<L<RUN_ALL|docs::2.0::user::handlers::intro/item_RUN_ALL>>.
733
734B<Arguments>
735
736See the L<HTTP Request Handler Skeleton|docs::2.0::user::handlers::http/HTTP_Request_Handler_Skeleton> for a description of handler arguments.
737
738B<Return>
739
740See L<Stacked Handlers|docs::2.0::user::handlers::intro/Stacked_Handlers>
741for a description of handler return codes.
742
743B<Examples>
744
745The best example here would be to use
746C<L<Apache2::Reload|docs::2.0::api::Apache2::Reload>> which takes the
747benefit of this directive. Usually
748C<L<Apache2::Reload|docs::2.0::api::Apache2::Reload>> is configured
749as:
750
751  PerlInitHandler Apache2::Reload
752  PerlSetVar ReloadAll Off
753  PerlSetVar ReloadModules "MyApache2::*"
754
755which during the current HTTP request will monitor and reload all
756C<MyApache2::*> modules that have been modified since the last HTTP
757request. However if we move the global configuration into a
758C<E<lt>LocationE<gt>> container:
759
760  <Location /devel>
761      PerlInitHandler Apache2::Reload
762      PerlSetVar ReloadAll Off
763      PerlSetVar ReloadModules "MyApache2::*"
764      SetHandler perl-script
765      PerlResponseHandler ModPerl::Registry
766      Options +ExecCGI
767  </Location>
768
769C<L<Apache2::Reload|docs::2.0::api::Apache2::Reload>> will reload the
770modified modules, only when a request to the I</devel> namespace is
771issued, because C<L<PerlInitHandler|/PerlInitHandler>> plays the role
772of C<L<PerlHeaderParserHandler|/PerlHeaderParserHandler>> here.
773
774
775
776
777
778=head2 PerlAccessHandler
779
780The I<access_checker> phase is the first of three handlers that are
781involved in what's known as AAA: Authentication, Authorization, and
782Access control.
783
784This phase can be used to restrict access from a certain IP address,
785time of the day or any other rule not connected to the user's
786identity.
787
788This phase is of type
789C<L<RUN_ALL|docs::2.0::user::handlers::intro/item_RUN_ALL>>.
790
791The handler's configuration scope is
792C<L<DIR|docs::2.0::user::config::config/item_DIR>>.
793
794B<Arguments>
795
796See the L<HTTP Request Handler Skeleton|docs::2.0::user::handlers::http/HTTP_Request_Handler_Skeleton> for a description of handler arguments.
797
798B<Return>
799
800See L<Stacked Handlers|docs::2.0::user::handlers::intro/Stacked_Handlers>
801for a description of handler return codes.
802
803B<Examples>
804
805The concept behind access checker handler is very simple, return
806C<Apache2::Const::FORBIDDEN> if the access is not allowed, otherwise
807return C<Apache2::Const::OK>.
808
809The following example handler denies requests made from IPs on the
810blacklist.
811
812
813  #file:MyApache2/BlockByIP.pm
814  #--------------------------
815  package MyApache2::BlockByIP;
816
817  use strict;
818  use warnings;
819
820  use Apache2::RequestRec ();
821  use Apache2::Connection ();
822
823  use Apache2::Const -compile => qw(FORBIDDEN OK);
824
825  my %bad_ips = map {$_ => 1} qw(127.0.0.1 10.0.0.4);
826
827  sub handler {
828      my $r = shift;
829
830      return exists $bad_ips{$r->connection->remote_ip}
831          ? Apache2::Const::FORBIDDEN
832          : Apache2::Const::OK;
833  }
834
835  1;
836
837The handler retrieves the connection's IP address, looks it up in the
838hash of blacklisted IPs and forbids the access if found. If the IP is
839not blacklisted, the handler returns control to the next access
840checker handler, which may still block the access based on a different
841rule.
842
843To enable the handler simply add it to the container that needs to be
844protected. For example to protect an access to the registry scripts
845executed from the base location I</perl> add:
846
847  <Location /perl/>
848      SetHandler perl-script
849      PerlResponseHandler ModPerl::Registry
850      PerlAccessHandler MyApache2::BlockByIP
851      Options +ExecCGI
852  </Location>
853
854It's important to notice that C<PerlAccessHandler> can be configured
855for any subsection of the site, no matter whether it's served by a
856mod_perl response handler or not. For example to run the handler from
857our example for all requests to the server simply add to
858I<httpd.conf>:
859
860  <Location />
861      PerlAccessHandler MyApache2::BlockByIP
862  </Location>
863
864
865
866
867
868
869=head2 PerlAuthenHandler
870
871The I<check_user_id> (I<authen>) phase is called whenever the
872requested file or directory is password protected.  This, in turn,
873requires that the directory be associated with C<AuthName>,
874C<AuthType> and at least one C<require> directive.
875
876This phase is usually used to verify a user's identification
877credentials. If the credentials are verified to be correct, the
878handler should return C<Apache2::Const::OK>.  Otherwise the handler
879returns C<Apache2::Const::HTTP_UNAUTHORIZED> to indicate that the user
880has not authenticated successfully.  When Apache sends the HTTP header
881with this code, the browser will normally pop up a dialog box that
882prompts the user for login information.
883
884This phase is of type
885C<L<RUN_FIRST|docs::2.0::user::handlers::intro/item_RUN_FIRST>>.
886
887The handler's configuration scope is
888C<L<DIR|docs::2.0::user::config::config/item_DIR>>.
889
890B<Arguments>
891
892See the L<HTTP Request Handler Skeleton|docs::2.0::user::handlers::http/HTTP_Request_Handler_Skeleton> for a description of handler arguments.
893
894B<Return>
895
896See L<Stacked Handlers|docs::2.0::user::handlers::intro/Stacked_Handlers>
897for a description of handler return codes.
898
899B<Examples>
900
901The following handler authenticates users by asking for a username and
902a password and lets them in only if the length of a string made from
903the supplied username and password and a single space equals to the
904secret length, specified by the constant C<SECRET_LENGTH>.
905
906  #file:MyApache2/SecretLengthAuth.pm
907  #---------------------------------
908  package MyApache2::SecretLengthAuth;
909
910  use strict;
911  use warnings;
912
913  use Apache2::Access ();
914  use Apache2::RequestUtil ();
915
916  use Apache2::Const -compile => qw(OK DECLINED HTTP_UNAUTHORIZED);
917
918  use constant SECRET_LENGTH => 14;
919
920  sub handler {
921      my $r = shift;
922
923      my ($status, $password) = $r->get_basic_auth_pw;
924      return $status unless $status == Apache2::Const::OK;
925
926      return Apache2::Const::OK
927          if SECRET_LENGTH == length join " ", $r->user, $password;
928
929      $r->note_basic_auth_failure;
930      return Apache2::Const::HTTP_UNAUTHORIZED;
931  }
932
933  1;
934
935First the handler retrieves the status of the authentication and the
936password in plain text. The status will be set to
937C<Apache2::Const::OK> only when the user has supplied the username and
938the password credentials. If the status is different, we just let
939Apache handle this situation for us, which will usually challenge the
940client so it'll supply the credentials.
941
942Note that C<get_basic_auth_pw()> does a few things behind the scenes,
943which are important to understand if you plan on implementing your own
944authentication mechanism that does not use C<get_basic_auth_pw()>.
945First, is checks the value of the configured C<AuthType> for the
946request, making sure it is C<Basic>.  Then it makes sure that the
947Authorization (or Proxy-Authorization) header is formatted for
948C<Basic> authentication.  Finally, after isolating the user and
949password from the header, it populates the I<ap_auth_type> slot in the
950request record with C<Basic>.  For the first and last parts of this
951process, mod_perl offers an API. C<$r-E<gt>auth_type> returns the
952configured authentication type for the current request - whatever was
953set via the C<AuthType> configuration directive.
954C<$r-E<gt>ap_auth_type> populates the I<ap_auth_type> slot in the
955request record, which should be done after it has been confirmed that
956the request is indeed using C<Basic> authentication.  (Note:
957C<$r-E<gt>ap_auth_type> was C<$r-E<gt>connection-E<gt>auth_type> in
958the mod_perl 1.0 API.)
959
960Once we know that we have the username and the password supplied by
961the client, we can proceed with the authentication. Our authentication
962algorithm is unusual. Instead of validating the username/password pair
963against a password file, we simply check that the string built from
964these two items plus a single space is C<SECRET_LENGTH> long (14 in
965our example). So for example the pair I<mod_perl/rules> authenticates
966correctly, whereas I<secret/password> does not, because the latter
967pair will make a string of 15 characters. Of course this is not a
968strong authentication scheme and you shouldn't use it for serious
969things, but it's fun to play with. Most authentication validations
970simply verify the username/password against a database of valid pairs,
971usually this requires the password to be encrypted first, since
972storing passwords in clear is a bad idea.
973
974Finally if our authentication fails the handler calls
975note_basic_auth_failure() and returns
976C<Apache2::Const::HTTP_UNAUTHORIZED>, which sets the proper HTTP
977response headers that tell the client that its user that the
978authentication has failed and the credentials should be supplied
979again.
980
981It's not enough to enable this handler for the authentication to
982work. You have to tell Apache what authentication scheme to use
983(C<Basic> or C<Digest>), which is specified by the C<AuthType>
984directive, and you should also supply the C<AuthName> -- the
985authentication realm, which is really just a string that the client
986usually uses as a title in the pop-up box, where the username and the
987password are inserted. Finally the C<Require> directive is needed to
988specify which usernames are allowed to authenticate. If you set it to
989C<valid-user> any username will do.
990
991Here is the whole configuration section that requires users to
992authenticate before they are allowed to run the registry scripts from
993I</perl/>:
994
995  <Location /perl/>
996      SetHandler perl-script
997      PerlResponseHandler ModPerl::Registry
998      PerlAuthenHandler MyApache2::SecretLengthAuth
999      Options +ExecCGI
1000
1001      AuthType Basic
1002      AuthName "The Gate"
1003      Require valid-user
1004  </Location>
1005
1006Just like C<PerlAccessHandler> and other mod_perl handlers,
1007C<PerlAuthenHandler> can be configured for any subsection of the site,
1008no matter whether it's served by a mod_perl response handler or
1009not. For example to use the authentication handler from the last
1010example for any requests to the site, simply use:
1011
1012  <Location />
1013      PerlAuthenHandler MyApache2::SecretLengthAuth
1014      AuthType Basic
1015      AuthName "The Gate"
1016      Require valid-user
1017  </Location>
1018
1019
1020
1021
1022
1023
1024
1025=head2 PerlAuthzHandler
1026
1027The I<auth_checker> (I<authz>) phase is used for authorization
1028control. This phase requires a successful authentication from the
1029previous phase, because a username is needed in order to decide
1030whether a user is authorized to access the requested resource.
1031
1032As this phase is tightly connected to the authentication phase, the
1033handlers registered for this phase are only called when the requested
1034resource is password protected, similar to the auth phase. The handler
1035is expected to return C<Apache2::Const::DECLINED> to defer the
1036decision, C<Apache2::Const::OK> to indicate its acceptance of the
1037user's authorization, or C<Apache2::Const::HTTP_UNAUTHORIZED> to
1038indicate that the user is not authorized to access the requested
1039document.
1040
1041This phase is of type
1042C<L<RUN_FIRST|docs::2.0::user::handlers::intro/item_RUN_FIRST>>.
1043
1044The handler's configuration scope is
1045C<L<DIR|docs::2.0::user::config::config/item_DIR>>.
1046
1047B<Arguments>
1048
1049See the L<HTTP Request Handler Skeleton|docs::2.0::user::handlers::http/HTTP_Request_Handler_Skeleton> for a description of handler arguments.
1050
1051B<Return>
1052
1053See L<Stacked Handlers|docs::2.0::user::handlers::intro/Stacked_Handlers>
1054for a description of handler return codes.
1055
1056B<Examples>
1057
1058Here is the C<MyApache2::SecretResourceAuthz> handler which grants
1059access to certain resources only to certain users who have already
1060properly authenticated:
1061
1062  #file:MyApache2/SecretResourceAuthz.pm
1063  #------------------------------------
1064  package MyApache2::SecretResourceAuthz;
1065
1066  use strict;
1067  use warnings;
1068
1069  use Apache2::Access ();
1070  use Apache2::RequestUtil ();
1071
1072  use Apache2::Const -compile => qw(OK HTTP_UNAUTHORIZED);
1073
1074  my %protected = (
1075      'admin'  => ['stas'],
1076      'report' => [qw(stas boss)],
1077  );
1078
1079  sub handler {
1080      my $r = shift;
1081
1082      my $user = $r->user;
1083      if ($user) {
1084          my ($section) = $r->uri =~ m|^/company/(\w+)/|;
1085          if (defined $section && exists $protected{$section}) {
1086              my $users = $protected{$section};
1087              return Apache2::Const::OK if grep { $_ eq $user } @$users;
1088          }
1089          else {
1090              return Apache2::Const::OK;
1091          }
1092      }
1093
1094      $r->note_basic_auth_failure;
1095      return Apache2::Const::HTTP_UNAUTHORIZED;
1096  }
1097
1098  1;
1099
1100This authorization handler is very similar to the authentication
1101handler L<from the previous section|/PerlAuthenHandler>. Here we rely
1102on the previous phase to get users authenticated, and now as we have
1103the username we can make decisions whether to let the user access the
1104resource it has asked for or not. In our example we have a simple hash
1105which maps which users are allowed to access what resources. So for
1106example anything under I</company/admin/> can be accessed only by the
1107user I<stas>, I</company/report/> can be accessed by users I<stas> and
1108I<boss>, whereas any other resources under I</company/> can be
1109accessed by everybody who has reached so far. If for some reason we
1110don't get the username, we or the user is not authorized to access the
1111resource the handler does the same thing as it does when the
1112authentication fails, i.e, calls:
1113
1114      $r->note_basic_auth_failure;
1115      return Apache2::Const::HTTP_UNAUTHORIZED;
1116
1117The configuration is similar to the one in L<the previous
1118section|/PerlAuthenHandler>, this time we just add the
1119C<PerlAuthzHandler> setting. The rest doesn't change.
1120
1121  Alias /company/ /home/httpd/httpd-2.0/perl/
1122  <Location /company/>
1123      SetHandler perl-script
1124      PerlResponseHandler ModPerl::Registry
1125      PerlAuthenHandler MyApache2::SecretLengthAuth
1126      PerlAuthzHandler  MyApache2::SecretResourceAuthz
1127      Options +ExecCGI
1128
1129      AuthType Basic
1130      AuthName "The Secret Gate"
1131      Require valid-user
1132  </Location>
1133
1134And if you want to run the authentication and authorization for the
1135whole site, simply add:
1136
1137  <Location />
1138      PerlAuthenHandler MyApache2::SecretLengthAuth
1139      PerlAuthzHandler  MyApache2::SecretResourceAuthz
1140      AuthType Basic
1141      AuthName "The Secret Gate"
1142      Require valid-user
1143  </Location>
1144
1145
1146
1147=head2 PerlTypeHandler
1148
1149The I<type_checker> phase is used to set the response MIME type
1150(C<Content-type>) and sometimes other bits of document type
1151information like the document language.
1152
1153For example C<mod_autoindex>, which performs automatic directory
1154indexing, uses this phase to map the filename extensions to the
1155corresponding icons which will be later used in the listing of files.
1156
1157Of course later phases may override the mime type set in this phase.
1158
1159This phase is of type
1160C<L<RUN_FIRST|docs::2.0::user::handlers::intro/item_RUN_FIRST>>.
1161
1162The handler's configuration scope is
1163C<L<DIR|docs::2.0::user::config::config/item_DIR>>.
1164
1165B<Arguments>
1166
1167See the L<HTTP Request Handler Skeleton|docs::2.0::user::handlers::http/HTTP_Request_Handler_Skeleton> for a description of handler arguments.
1168
1169B<Return>
1170
1171See L<Stacked Handlers|docs::2.0::user::handlers::intro/Stacked_Handlers>
1172for a description of handler return codes.
1173
1174B<Examples>
1175
1176The most important thing to remember when overriding the default
1177I<type_checker> handler, which is usually the mod_mime handler, is
1178that you have to set the handler that will take care of the response
1179phase and the response callback function or the code won't
1180work. mod_mime does that based on C<SetHandler> and C<AddHandler>
1181directives, and file extensions. So if you want the content handler to
1182be run by mod_perl, set either:
1183
1184  $r->handler('perl-script');
1185  $r->set_handlers(PerlResponseHandler => \&handler);
1186
1187or:
1188
1189  $r->handler('modperl');
1190  $r->set_handlers(PerlResponseHandler => \&handler);
1191
1192depending on which type of response handler is wanted.
1193
1194Writing a C<PerlTypeHandler> handler which sets the content-type value
1195and returns C<Apache2::Const::DECLINED> so that the default handler
1196will do the rest of the work, is not a good idea, because mod_mime
1197will probably override this and other settings.
1198
1199Therefore it's the easiest to leave this stage alone and do any
1200desired settings in the I<fixups> phase.
1201
1202
1203
1204
1205=head2 PerlFixupHandler
1206
1207The I<fixups> phase is happening just before the content handling
1208phase. It gives the last chance to do things before the response is
1209generated. For example in this phase C<mod_env> populates the
1210environment with variables configured with I<SetEnv> and I<PassEnv>
1211directives.
1212
1213This phase is of type
1214C<L<RUN_ALL|docs::2.0::user::handlers::intro/item_RUN_ALL>>.
1215
1216The handler's configuration scope is
1217C<L<DIR|docs::2.0::user::config::config/item_DIR>>.
1218
1219B<Arguments>
1220
1221See the L<HTTP Request Handler Skeleton|docs::2.0::user::handlers::http/HTTP_Request_Handler_Skeleton> for a description of handler arguments.
1222
1223B<Return>
1224
1225See L<Stacked Handlers|docs::2.0::user::handlers::intro/Stacked_Handlers>
1226for a description of handler return codes.
1227
1228B<Examples>
1229
1230The following fixup handler example tells Apache at run time which
1231handler and callback should be used to process the request based on
1232the file extension of the request's URI.
1233
1234  #file:MyApache2/FileExtDispatch.pm
1235  #--------------------------------
1236  package MyApache2::FileExtDispatch;
1237
1238  use strict;
1239  use warnings;
1240
1241  use Apache2::RequestIO ();
1242  use Apache2::RequestRec ();
1243  use Apache2::RequestUtil ();
1244
1245  use Apache2::Const -compile => 'OK';
1246
1247  use constant HANDLER  => 0;
1248  use constant CALLBACK => 1;
1249
1250  my %exts = (
1251      cgi => ['perl-script',     \&cgi_handler],
1252      pl  => ['modperl',         \&pl_handler ],
1253      tt  => ['perl-script',     \&tt_handler ],
1254      txt => ['default-handler', undef        ],
1255  );
1256
1257  sub handler {
1258      my $r = shift;
1259
1260      my ($ext) = $r->uri =~ /\.(\w+)$/;
1261      $ext = 'txt' unless defined $ext and exists $exts{$ext};
1262
1263      $r->handler($exts{$ext}->[HANDLER]);
1264
1265      if (defined $exts{$ext}->[CALLBACK]) {
1266          $r->set_handlers(PerlResponseHandler => $exts{$ext}->[CALLBACK]);
1267      }
1268
1269      return Apache2::Const::OK;
1270  }
1271
1272  sub cgi_handler { content_handler($_[0], 'cgi') }
1273  sub pl_handler  { content_handler($_[0], 'pl')  }
1274  sub tt_handler  { content_handler($_[0], 'tt')  }
1275
1276  sub content_handler {
1277      my ($r, $type) = @_;
1278
1279      $r->content_type('text/plain');
1280      $r->print("A handler of type '$type' was called");
1281
1282      return Apache2::Const::OK;
1283  }
1284
1285  1;
1286
1287In the example we have used the following mapping.
1288
1289  my %exts = (
1290      cgi => ['perl-script',     \&cgi_handler],
1291      pl  => ['modperl',         \&pl_handler ],
1292      tt  => ['perl-script',     \&tt_handler ],
1293      txt => ['default-handler', undef        ],
1294  );
1295
1296So that I<.cgi> requests will be handled by the C<perl-script> handler
1297and the C<cgi_handler()> callback, I<.pl> requests by C<modperl> and
1298C<pl_handler()>, I<.tt> (template toolkit) by C<perl-script> and the
1299C<tt_handler()>, finally I<.txt> request by the C<default-handler>
1300handler, which requires no callback.
1301
1302Moreover the handler assumes that if the request's URI has no file
1303extension or it does, but it's not in its mapping, the
1304C<default-handler> will be used, as if the I<txt> extension was used.
1305
1306After doing the mapping, the handler assigns the handler:
1307
1308      $r->handler($exts{$ext}->[HANDLER]);
1309
1310and the callback if needed:
1311
1312      if (defined $exts{$ext}->[CALLBACK]) {
1313          $r->set_handlers(
1314			  PerlResponseHandler => $exts{$ext}->[CALLBACK]);
1315      }
1316
1317In this simple example the callback functions don't do much but
1318calling the same content handler which simply prints the name of the
1319extension if handled by mod_perl, otherwise Apache will serve the
1320other files using the default handler. In real world you will use
1321callbacks to real content handlers that do real things.
1322
1323Here is how this handler is configured:
1324
1325  Alias /dispatch/ /home/httpd/httpd-2.0/htdocs/
1326  <Location /dispatch/>
1327      PerlFixupHandler MyApache2::FileExtDispatch
1328  </Location>
1329
1330Notice that there is no need to specify anything, but the fixup
1331handler. It applies the rest of the settings dynamically at run-time.
1332
1333
1334
1335
1336
1337
1338=head2 PerlResponseHandler
1339
1340The I<handler> (I<response>) phase is used for generating the
1341response. This is arguably the most important phase and most of the
1342existing Apache modules do most of their work at this phase.
1343
1344This is the only phase that requires two directives under
1345mod_perl. For example:
1346
1347  <Location /perl>
1348     SetHandler perl-script
1349     PerlResponseHandler MyApache2::WorldDomination
1350  </Location>
1351
1352C<SetHandler> set to
1353C<L<perl-script|docs::2.0::user::config::config/C_perl_script_>> or
1354C<L<modperl|docs::2.0::user::config::config/C_modperl_>> tells Apache
1355that mod_perl is going to handle the response
1356generation. C<PerlResponseHandler> tells mod_perl which callback is
1357going to do the job.
1358
1359This phase is of type
1360C<L<RUN_FIRST|docs::2.0::user::handlers::intro/item_RUN_FIRST>>.
1361
1362The handler's configuration scope is
1363C<L<DIR|docs::2.0::user::config::config/item_DIR>>.
1364
1365B<Arguments>
1366
1367See the L<HTTP Request Handler Skeleton|docs::2.0::user::handlers::http/HTTP_Request_Handler_Skeleton> for a description of handler arguments.
1368
1369B<Return>
1370
1371See L<Stacked Handlers|docs::2.0::user::handlers::intro/Stacked_Handlers>
1372for a description of handler return codes.
1373
1374B<Examples>
1375
1376Most of the C<Apache::> modules on CPAN are dealing with this
1377phase. In fact most of the developers spend the majority of their time
1378working on handlers that generate response content.
1379
1380Let's write a simple response handler, that just generates some
1381content. This time let's do something more interesting than printing
1382I<"Hello world">. Let's write a handler that prints itself:
1383
1384  #file:MyApache2/Deparse.pm
1385  #------------------------
1386  package MyApache2::Deparse;
1387
1388  use strict;
1389  use warnings;
1390
1391  use Apache2::RequestRec ();
1392  use Apache2::RequestIO ();
1393  use B::Deparse ();
1394
1395  use Apache2::Const -compile => 'OK';
1396
1397  sub handler {
1398      my $r = shift;
1399
1400      $r->content_type('text/plain');
1401      $r->print('sub handler ', B::Deparse->new->coderef2text(\&handler));
1402
1403      return Apache2::Const::OK;
1404  }
1405  1;
1406
1407To enable this handler add to I<httpd.conf>:
1408
1409  <Location /deparse>
1410      SetHandler modperl
1411      PerlResponseHandler MyApache2::Deparse
1412  </Location>
1413
1414Now when the server is restarted and we issue a request to
1415I<http://localhost/deparse> we get the following response:
1416
1417  sub handler {
1418      package MyApache2::Deparse;
1419      use warnings;
1420      use strict 'refs';
1421      my $r = shift @_;
1422      $r->content_type('text/plain');
1423      $r->print('sub handler ', 'B::Deparse'->new->coderef2text(\&handler));
1424      return 0;
1425  }
1426
1427If you compare it to the source code, it's pretty much the same
1428code. C<B::Deparse> is fun to play with!
1429
1430
1431
1432
1433
1434
1435
1436=head2 PerlLogHandler
1437
1438The I<log_transaction> phase happens no matter how the previous phases
1439have ended up. If one of the earlier phases has aborted a request,
1440e.g., failed authentication or 404 (file not found) errors, the rest of
1441the phases up to and including the response phases are skipped. But
1442this phase is always executed.
1443
1444By this phase all the information about the request and the response
1445is known, therefore the logging handlers usually record this
1446information in various ways (e.g., logging to a flat file or a
1447database).
1448
1449This phase is of type
1450C<L<RUN_ALL|docs::2.0::user::handlers::intro/item_RUN_ALL>>.
1451
1452The handler's configuration scope is
1453C<L<DIR|docs::2.0::user::config::config/item_DIR>>.
1454
1455B<Arguments>
1456
1457See the L<HTTP Request Handler Skeleton|docs::2.0::user::handlers::http/HTTP_Request_Handler_Skeleton> for a description of handler arguments.
1458
1459B<Return>
1460
1461See L<Stacked Handlers|docs::2.0::user::handlers::intro/Stacked_Handlers>
1462for a description of handler return codes.
1463
1464B<Examples>
1465
1466Imagine a situation where you have to log requests into individual
1467files, one per user. Assuming that all requests start with
1468I</~username/>, so it's easy to categorize requests by the
1469username. Here is the log handler that does that:
1470
1471  #file:MyApache2/LogPerUser.pm
1472  #---------------------------
1473  package MyApache2::LogPerUser;
1474
1475  use strict;
1476  use warnings;
1477
1478  use Apache2::RequestRec ();
1479  use Apache2::Connection ();
1480
1481  use Fcntl qw(:flock);
1482  use File::Spec::Functions qw(catfile);
1483
1484  use Apache2::Const -compile => qw(OK DECLINED);
1485
1486  sub handler {
1487      my $r = shift;
1488
1489      my ($username) = $r->uri =~ m|^/~([^/]+)|;
1490      return Apache2::Const::DECLINED unless defined $username;
1491
1492      my $entry = sprintf qq(%s [%s] "%s" %d %d\n),
1493          $r->connection->remote_ip, scalar(localtime),
1494          $r->uri, $r->status, $r->bytes_sent;
1495
1496      my $log_path = catfile Apache2::ServerUtil::server_root,
1497          "logs", "$username.log";
1498      open my $fh, ">>$log_path" or die "can't open $log_path: $!";
1499      flock $fh, LOCK_EX;
1500      print $fh $entry;
1501      close $fh;
1502
1503      return Apache2::Const::OK;
1504  }
1505  1;
1506
1507First the handler tries to figure out what username the request is
1508issued for, if it fails to match the URI, it simply returns
1509C<Apache2::Const::DECLINED>, letting other log handlers to do the
1510logging. Though it could return C<Apache2::Const::OK> since all other
1511log handlers will be run anyway.
1512
1513Next it builds the log entry, similar to the default I<access_log>
1514entry. It's comprised of remote IP, the current time, the uri, the
1515return status and how many bytes were sent to the client as a response
1516body.
1517
1518Finally the handler appends this entry to the log file for the user
1519the request was issued for. Usually it's safe to append short strings
1520to the file without being afraid of messing up the file, when two
1521files attempt to write at the same time, but just to be on the safe
1522side the handler exclusively locks the file before performing the
1523writing.
1524
1525To configure the handler simply enable the module with the
1526C<PerlLogHandler> directive, for the desired URI namespace (starting
1527with : I</~> in our example):
1528
1529  <LocationMatch "^/~">
1530      SetHandler perl-script
1531      PerlResponseHandler ModPerl::Registry
1532      PerlLogHandler MyApache2::LogPerUser
1533      Options +ExecCGI
1534  </LocationMatch>
1535
1536After restarting the server and issuing requests to the following
1537URIs:
1538
1539  http://localhost/~stas/test.pl
1540  http://localhost/~eric/test.pl
1541  http://localhost/~stas/date.pl
1542
1543The C<MyApache2::LogPerUser> handler will append to I<logs/stas.log>:
1544
1545  127.0.0.1 [Sat Aug 31 01:50:38 2002] "/~stas/test.pl" 200 8
1546  127.0.0.1 [Sat Aug 31 01:50:40 2002] "/~stas/date.pl" 200 44
1547
1548and to I<logs/eric.log>:
1549
1550  127.0.0.1 [Sat Aug 31 01:50:39 2002] "/~eric/test.pl" 200 8
1551
1552It's important to notice that C<PerlLogHandler> can be configured for
1553any subsection of the site, no matter whether it's served by a
1554mod_perl response handler or not. For example to run the handler from
1555our example for all requests to the server, simply add to
1556I<httpd.conf>:
1557
1558  <Location />
1559      PerlLogHandler MyApache2::LogPerUser
1560  </Location>
1561
1562Since the C<PerlLogHandler> phase is of type
1563C<L<RUN_ALL|docs::2.0::user::handlers::intro/item_RUN_ALL>>, all other
1564logging handlers will be called as well.
1565
1566
1567
1568
1569
1570
1571
1572=head2 PerlCleanupHandler
1573
1574There is no I<cleanup> Apache phase, it exists only inside mod_perl.
1575It is used to execute some code immediately after the request has been
1576served (the client went away) and before the request object is
1577destroyed.
1578
1579There are several usages for this use phase. The obvious one is to run
1580a cleanup code, for example removing temporarily created files. The
1581less obvious is to use this phase instead of
1582C<L<PerlLogHandler|/PerlLogHandler>> if the logging operation is time
1583consuming. This approach allows to free the client as soon as the
1584response is sent.
1585
1586This phase is of type
1587C<L<RUN_ALL|docs::2.0::user::handlers::intro/item_RUN_ALL>>.
1588
1589The handler's configuration scope is
1590C<L<DIR|docs::2.0::user::config::config/item_DIR>>.
1591
1592B<Arguments>
1593
1594See the L<HTTP Request Handler Skeleton|docs::2.0::user::handlers::http/HTTP_Request_Handler_Skeleton> for a description of handler arguments.
1595
1596B<Return>
1597
1598See L<Stacked Handlers|docs::2.0::user::handlers::intro/Stacked_Handlers>
1599for a description of handler return codes.
1600
1601B<Examples>
1602
1603There are two ways to register and run cleanup handlers:
1604
1605=over
1606
1607=item 1 Using the C<PerlCleanupHandler> phase
1608
1609  PerlCleanupHandler MyApache2::Cleanup
1610
1611or:
1612
1613  $r->push_handlers(PerlCleanupHandler => \&cleanup);
1614
1615This method is identical to all other handlers.
1616
1617In this technique the C<cleanup()> callback accepts C<$r> as its only
1618argument.
1619
1620=item 2 Using C<cleanup_register()> acting on the request object's pool
1621
1622Since a request object pool is destroyed at the end of each request,
1623we can use
1624C<L<cleanup_register|docs::2.0::api::APR::Pool/C_cleanup_register_>>
1625to register a cleanup callback which will be executed just before the
1626pool is destroyed. For example:
1627
1628    $r->pool->cleanup_register(\&cleanup, $arg);
1629
1630The important difference from using the C<PerlCleanupHandler> handler,
1631is that here you can pass an optional arbitrary argument to the
1632callback function, and no C<$r> argument is passed by
1633default. Therefore if you need to pass any data other than C<$r> you
1634may want to use this technique.
1635
1636=back
1637
1638Here is an example where the cleanup handler is used to delete a
1639temporary file. The response handler is running C<ls -l> and stores
1640the output in temporary file, which is then used by
1641C<$r-E<gt>sendfile> to send the file's contents. We use
1642C<push_handlers()> to push C<PerlCleanupHandler> to unlink the file at
1643the end of the request.
1644
1645  #file:MyApache2/Cleanup1.pm
1646  #-------------------------
1647  package MyApache2::Cleanup1;
1648
1649  use strict;
1650  use warnings FATAL => 'all';
1651
1652  use File::Spec::Functions qw(catfile);
1653
1654  use Apache2::RequestRec ();
1655  use Apache2::RequestIO ();
1656  use Apache2::RequestUtil ();
1657
1658  use Apache2::Const -compile => qw(OK DECLINED);
1659  use APR::Const    -compile => 'SUCCESS';
1660
1661  my $file = catfile "/tmp", "data";
1662
1663  sub handler {
1664      my $r = shift;
1665
1666      $r->content_type('text/plain');
1667
1668      local @ENV{qw(PATH BASH_ENV)};
1669      qx(/bin/ls -l > $file);
1670
1671      my $status = $r->sendfile($file);
1672      die "sendfile has failed" unless $status == APR::Const::SUCCESS;
1673
1674      $r->push_handlers(PerlCleanupHandler => \&cleanup);
1675
1676      return Apache2::Const::OK;
1677  }
1678
1679  sub cleanup {
1680      my $r = shift;
1681
1682      die "Can't find file: $file" unless -e $file;
1683      unlink $file or die "failed to unlink $file";
1684
1685      return Apache2::Const::OK;
1686  }
1687  1;
1688
1689Next we add the following configuration:
1690
1691  <Location /cleanup1>
1692      SetHandler modperl
1693      PerlResponseHandler MyApache2::Cleanup1
1694  </Location>
1695
1696Now when a request to I</cleanup1> is made, the contents of the
1697current directory will be printed and once the request is over the
1698temporary file is deleted.
1699
1700This response handler has a problem of running in a multi-process
1701environment, since it uses the same file, and several processes may
1702try to read/write/delete that file at the same time, wrecking
1703havoc. We could have appended the process id C<$$> to the file's name,
1704but remember that mod_perl 2.0 code may run in the threaded
1705environment, meaning that there will be many threads running in the
1706same process and the C<$$> trick won't work any longer. Therefore one
1707really has to use this code to create unique, but predictable, file
1708names across threads and processes:
1709
1710  sub unique_id {
1711      require Apache2::MPM;
1712      require APR::OS;
1713      return Apache2::MPM->is_threaded
1714          ? "$$." . ${ APR::OS::current_thread_id() }
1715          : $$;
1716  }
1717
1718In the threaded environment it will return a string containing the
1719process ID, followed by a thread ID. In the non-threaded environment
1720only the process ID will be returned. However since it gives us a
1721predictable string, they may still be a non-satisfactory
1722solution. Therefore we need to use a random string. We can either
1723either Perl's C<rand>, some CPAN module or the APR's C<APR::UUID>:
1724
1725 sub unique_id {
1726  require APR::UUID;
1727  return APR::UUID->new->format;
1728 }
1729
1730Now the problem is how do we tell the cleanup handler what file should
1731be cleaned up? We could have stored it in the C<$r-E<gt>notes> table
1732in the response handler and then retrieve it in the cleanup
1733handler. However there is a better way - as mentioned earlier, we can
1734register a callback for request pool cleanup, and when using this
1735method we can pass an arbitrary argument to it. Therefore in our case
1736we choose to pass the file name, based on random string. Here is a
1737better version of the response and cleanup handlers, that uses this
1738technique:
1739
1740 #file:  MyApache2/Cleanup2.pm
1741 #-------------------------
1742 package MyApache2::Cleanup2;
1743
1744 use strict;
1745 use warnings FATAL => 'all';
1746
1747 use File::Spec::Functions qw(catfile);
1748
1749 use Apache2::RequestRec ();
1750 use Apache2::RequestIO ();
1751 use Apache2::RequestUtil ();
1752 use APR::UUID ();
1753 use APR::Pool ();
1754
1755 use Apache2::Const -compile => qw(OK DECLINED);
1756 use APR::Const    -compile => 'SUCCESS';
1757
1758 my $file_base = catfile "/tmp", "data-";
1759
1760 sub handler {
1761         my $r = shift;
1762
1763     $r->content_type('text/plain');
1764     my $file = $file_base . APR::UUID->new->format;
1765
1766     local @ENV{qw(PATH BASH_ENV)};
1767     qx(/bin/ls -l > $file);
1768
1769     my $status = $r->sendfile($file);
1770     die "sendfile has failed" unless $status == APR::Const::SUCCESS;
1771
1772     $r->pool->cleanup_register(\&cleanup, $file);
1773
1774     return Apache2::Const::OK;
1775 }
1776
1777 sub cleanup {
1778     my $file = shift;
1779
1780     die "Can't find file: $file" unless -e $file;
1781     unlink $file or die "failed to unlink $file";
1782
1783     return Apache2::Const::OK;
1784 }
1785 1;
1786
1787Similarly to the first handler, we add the configuration:
1788
1789 <Location /cleanup2>
1790     SetHandler modperl
1791     PerlResponseHandler MyApache2::Cleanup2
1792 </Location>
1793
1794And now when requesting I</cleanup2> we still get the same output --
1795the listing of the current directory -- but this time this code will
1796work correctly in the multi-processes/multi-threaded environment and
1797temporary files get cleaned up as well.
1798
1799
1800=head3 Possible Caveats
1801
1802C<PerlCleanupHandler> may fail to be completed on server
1803shutdown/graceful restart since Apache will kill the registered
1804handlers via SIGTERM, before they had a chance to run or even in the
1805middle of its execution. See:
1806http://marc.theaimsgroup.com/?t=106387845200003&r=1&w=2
1807http://marc.theaimsgroup.com/?l=apache-modperl-dev&m=106427616108596&w=2
1808
1809
1810
1811
1812
1813
1814
1815=head1 Miscellaneous Issues
1816
1817
1818=head2 Handling HEAD Requests
1819
1820In order to avoid the overhead of sending the data to the client when
1821the request is of type HEAD in mod_perl 1.0 we L<used to return
1822early|docs::1.0::guide::porting/Generating_correct_HTTP_Headers> from
1823the handler:
1824
1825 return Apache2::Const::OK if $r->header_only;
1826
1827This logic should not be used in mod_perl 2.0, because Apache 2.0
1828automatically discards the response body for HEAD requests. It expects
1829the full body to generate the correct set of response headers, if you
1830don't send the body you may encounter problems.
1831
1832(You can also read the comment in for C<ap_http_header_filter()> in
1833I<modules/http/http_protocol.c> in the Apache 2.0 source.)
1834
1835
1836
1837
1838
1839=head2 C<Content-Length> Response Header
1840
1841You may encounter some issues with the C-L (C<Content-Length>)
1842header. Some of them are discussed here.
1843
1844=over
1845
1846=item * The special case of C<Content-Length: 0>
1847
1848Since Apache proclaims itself governor of the C-L header via the C-L
1849filter (ap_content_length_filter at F<httpd-2.0/server/protocol.c>),
1850for the most part C<GET> and C<HEAD> behave exactly the same.
1851However, when Apache sees a C<HEAD> request with a C-L header of zero
1852it takes special action and removes the C-L header.  This is done to
1853protect against handlers that called C<$r-E<gt>header_only> (L<which
1854was ok in 1.3 but is not in 2.0|/Handling_HEAD_Requests>).  Therefore,
1855C<GET> and C<HEAD> behave identically, except when the content
1856handler (and/or filters) end up sending no content.  For more details
1857refer to the lengthy comments in C<ap_http_header_filter()> in
1858F<httpd-2.0/modules/http/http_protocol.c>).
1859
1860For more discussion on why it is important to get HEAD requests right,
1861see these threads from the mod_perl list:
1862
1863 http://marc.theaimsgroup.com/?l=apache-modperl&m=108647669726915&w=2
1864 http://marc.theaimsgroup.com/?t=109122984600001&r=1&w=2
1865
1866as well as this bug report from mozilla, which shows how C<HEAD>
1867requests are used in the wild:
1868
1869 http://bugzilla.mozilla.org/show_bug.cgi?id=245447
1870
1871=item * Not getting C<Content-Length> header with C<HEAD> requests
1872
1873Even though the spec says that content handlers should send an
1874identical response for GET and HEAD requests, some folks try to
1875L<avoid the overhead of generating the response
1876body|/Handling_HEAD_Requests>, which Apache is going to discard anyway
1877for HEAD requests. The following discussion assumes that we deal with
1878a HEAD request.
1879
1880When Apache sees EOS and no headers and no response body were sent,
1881C<ap_content_length_filter()> (F<httpd-2.0/server/protocol.c>) sets
1882C-L to 0. Later on C<ap_http_header_filter()>
1883(F<httpd-2.0/modules/http/http_protocol.c>) removes the C-L header for
1884the HEAD requests.
1885
1886The workaround is to force the sending of the response headers, before
1887C<EOS> was sent (which happens when the response handler returns). The
1888simplest solution is to use rflush():
1889
1890 if ($r->header_only) { # HEAD
1891     $body_len = calculate_body_len();
1892     $r->set_content_length($body_len);
1893     $r->rflush;
1894 }
1895 else {                 # GET
1896     # generate and send the body
1897 }
1898
1899now if the handler sets the C-L header it'll be delivered to the
1900client unmodified.
1901
1902=back
1903
1904
1905
1906=head1 Misc Notes
1907
1908These items will need to be extended and integrated in this or other
1909HTTP related documents:
1910
1911=over
1912
1913=item * front-end back-end setup: mod_proxy+X-Forwarded-For
1914
1915apache-1.3:
1916
1917frontend: mod_proxy_add_forward http://develooper.com/code/mpaf/
1918
1919backend: mod_rpaf (reverse proxy add forward):
1920http://stderr.net/apache/rpaf/
1921
1922apache-2.x:
1923
1924frontend: mod_proxy
1925
1926backend: mod_rpaf: http://stderr.net/apache/rpaf/
1927
1928=back
1929
1930
1931
1932=head1 Extending HTTP Protocol
1933
1934Extending HTTP under mod_perl is a trivial task.  Look at L<the
1935example of adding a new method C<EMAIL>|/PerlHeaderParserHandler> for
1936details.
1937
1938
1939=head1 HTTP Status Codes
1940
1941The Hypertext Transfer Protocol (HTTP) is an application-level
1942protocol for distributed, collaborative, hypermedia information
1943systems. It is a generic, stateless, protocol which can be used for
1944many tasks beyond its use for hypertext, such as name servers and
1945distributed object management systems, through extension of its
1946request methods, error codes and headers. A feature of HTTP is the
1947typing and negotiation of data representation, allowing systems to be
1948built independently of the data being transferred.
1949
1950HTTP 1.0 is described in Requests For Comments (RFC) 1945. HTTP 1.1 is
1951the latest version of the specifications and as of this writing HTTP
19521.1 is covered in RFC 2616.
1953
1954When writing mod_perl applications, usually only a small subset of HTTP
1955response codes is used, but sometimes you need to know others as
1956well. We will give a short description of each code and you will find
1957the extended explanation in the appropriate RFC. (Section 9 in RFC
19581945 and section 10 in RFC 2616). You can always find the latest link
1959to these RFCs at the Web Consortium site,
1960I<http://www.w3.org/Protocols/>.
1961
1962While HTTP 1.1 is widely supported, HTTP 1.0 still remains the
1963mainstream standard. Therefore we will supply a summary of the both
1964versions including the corresponding Apache constants.
1965
1966In mod_perl these constants can be accessed the
1967C<L<Apache::Constants|docs::1.0::api::Apache::Constants>>
1968package (e.g., to access the HTTP_OK constant use
1969C<Apache::Constants::HTTP_OK>). See the
1970C<L<Apache::Constants|docs::1.0::api::Apache::Constants>> manpage
1971for more information.
1972
1973In mod_perl2 these constants can be accessed the
1974C<L<Apache2::Const|docs::2.0::api::Apache2::Const>>
1975package (e.g., to access the HTTP_OK constant use
1976C<Apache2::Const::HTTP_OK>). See the
1977C<L<Apache2::Const|docs::2.0::api::Apache2::Const>> manpage
1978for more information.
1979
1980=head2 HTTP 1.0 Status Codes
1981
1982=over 4
1983
1984=item *
1985
1986Successful 2xx:
1987
1988 200 HTTP_OK                    OK
1989 201 HTTP_CREATED               Created
1990 202 HTTP_ACCEPTED              Accepted
1991 204 HTTP_NO_CONTENT            No Content
1992
1993=item *
1994
1995Redirection 3xx:
1996
1997 301 HTTP_MOVED_PERMANENTLY     Multiple Choices
1998 302 HTTP_MOVED_TEMPORARILY     Moved Permanently
1999 303 HTTP_SEE_OTHER             Moved Temporarily
2000 304 HTTP_NOT_MODIFIED          Not Modified
2001
2002=item *
2003
2004Client Error 4xx:
2005
2006 400 HTTP_BAD_REQUEST           Bad Request
2007 401 HTTP_UNAUTHORIZED          Unauthorized
2008 403 HTTP_FORBIDDEN             Forbidden
2009 404 HTTP_NOT_FOUND             Not Found
2010
2011=item *
2012
2013Server Error 5xx:
2014
2015 500 HTTP_INTERNAL_SERVER_ERROR Internal Server Error
2016 501 HTTP_NOT_IMPLEMENTED       Not Implemented
2017 502 HTTP_BAD_GATEWAY           Bad Gateway
2018 503 HTTP_SERVICE_UNAVAILABLE   Service UnavailableStatus Codes
2019
2020=back
2021
2022=head2 HTTP 1.1 Status Codes
2023
2024=over 4
2025
2026=item *
2027
2028Informational 1xx:
2029
2030 100 HTTP_CONTINUE                        Continue
2031 101 HTTP_SWITCHING_PROTOCOLS             Switching Protocols
2032
2033=item *
2034
2035Successful 2xx:
2036
2037 200 HTTP_OK                              OK
2038 201 HTTP_CREATED                         Created
2039 202 HTTP_ACCEPTED                        Accepted
2040 203 HTTP_NON_AUTHORITATIVE               Non-Authoritative Information
2041 204 HTTP_NO_CONTENT                      No Content
2042 205 HTTP_RESET_CONTENT                   Reset Content
2043 206 HTTP_PARTIAL_CONTENT                 Partial Content
2044
2045=item *
2046
2047Redirection 3xx:
2048
2049 300 HTTP_MULTIPLE_CHOICES                Multiple Choices
2050 301 HTTP_MOVED_PERMANENTLY               Moved Permanently
2051 302 HTTP_MOVED_TEMPORARILY               Found
2052 303 HTTP_SEE_OTHER                       See Other
2053 304 HTTP_NOT_MODIFIED                    Not Modified
2054 305 HTTP_USE_PROXY                       Use Proxy
2055 306                                      (Unused)
2056 307 HTTP_TEMPORARY_REDIRECT              Temporary Redirect
2057
2058=item *
2059
2060Client Error 4xx:
2061
2062 400 HTTP_BAD_REQUEST                     Bad Request
2063 401 HTTP_UNAUTHORIZED                    Unauthorized
2064 402 HTTP_PAYMENT_REQUIRED                Payment Required
2065 403 HTTP_FORBIDDEN                       Forbidden
2066 404 HTTP_NOT_FOUND                       Not Found
2067 405 HTTP_METHOD_NOT_ALLOWED              Method Not Allowed
2068 406 HTTP_NOT_ACCEPTABLE                  Not Acceptable
2069 407 HTTP_PROXY_AUTHENTICATION_REQUIRED   Proxy Authentication Required
2070 408 HTTP_REQUEST_TIMEOUT                 Request Timeout
2071 409 HTTP_CONFLICT                        Conflict
2072 410 HTTP_GONE                            Gone
2073 411 HTTP_LENGTH REQUIRED                 Length Required
2074 412 HTTP_PRECONDITION_FAILED             Precondition Failed
2075 413 HTTP_REQUEST_ENTITY_TOO_LARGE        Request Entity Too Large
2076 414 HTTP_REQUEST_URI_TOO_LARGE           Request-URI Too Long
2077 415 HTTP_UNSUPPORTED_MEDIA_TYPE          Unsupported Media Type
2078 416 HTTP_RANGE_NOT_SATISFIABLE           Requested Range Not Satisfiable
2079 417 HTTP_EXPECTATION_FAILED              Expectation Failed
2080
2081=item *
2082
2083Server Error 5xx:
2084
2085 500 HTTP_INTERNAL_SERVER_ERROR           Internal Server Error
2086 501 HTTP_NOT IMPLEMENTED                 Not Implemented
2087 502 HTTP_BAD_GATEWAY                     Bad Gateway
2088 503 HTTP_SERVICE_UNAVAILABLE             Service Unavailable
2089 504 HTTP_GATEWAY_TIME_OUT                Gateway Timeout
2090 505 HTTP_VERSION_NOT_SUPPORTED           HTTP Version Not Supported
2091
2092=back
2093
2094=head2 References
2095
2096All the information related to web protocols can be found at the World
2097Wide Web Consortium site, I<http://www.w3.org/Protocols/>.
2098
2099There are many mirrors of the RFCs all around the world. One of the
2100good starting points might be I<http://www.rfc-editor.org/>.
2101
2102The Eagle Book provided much of the HTTP constants material shown here
2103I<http://www.modperl.com/book/chapters/ch9.html#The_Apache_Constants_Class>
2104
2105=head1 Maintainers
2106
2107Maintainer is the person(s) you should contact with updates,
2108corrections and patches.
2109
2110=over
2111
2112=item *
2113
2114L<The mod_perl development team and numerous
2115contributors|about::contributors::people>.
2116
2117
2118=back
2119
2120
2121=head1 Authors
2122
2123=over
2124
2125=item *
2126
2127Stas Bekman [http://stason.org/]
2128
2129=back
2130
2131Only the major authors are listed above. For contributors see the
2132Changes file.
2133
2134
2135
2136=cut
2137
2138