home *** CD-ROM | disk | FTP | other *** search
/ PC Professionell 2004 December / PCpro_2004_12.ISO / files / webserver / tsw / TSW_3.4.0.exe / Apache2 / perl / Apache.pm < prev    next >
Encoding:
Perl POD Document  |  2003-12-03  |  7.3 KB  |  225 lines

  1. #============================================================= -*-Perl-*-
  2. #
  3. # Template::Service::Apache
  4. #
  5. # DESCRIPTION
  6. #   Module subclassed from Template::Service which implements a service 
  7. #   specific to the Apache/mod_perl environment.
  8. #
  9. # AUTHOR
  10. #   Andy Wardley   <abw@kfs.org>
  11. #
  12. # COPYRIGHT
  13. #   Copyright (C) 1996-2001 Andy Wardley.  All Rights Reserved.
  14. #   Copyright (C) 1998-2001 Canon Research Centre Europe Ltd.
  15. #
  16. #   This module is free software; you can redistribute it and/or
  17. #   modify it under the same terms as Perl itself.
  18. #----------------------------------------------------------------------------
  19. #
  20. # $Id: Apache.pm,v 1.3 2002/03/12 14:08:29 abw Exp $
  21. #
  22. #============================================================================
  23.  
  24. package Template::Service::Apache;
  25.  
  26. require 5.004;
  27.  
  28. use strict;
  29. use vars qw( $VERSION $DEBUG $ERROR );
  30. use base qw( Template::Service );
  31. use Digest::MD5 qw( md5_hex );
  32. use Template::Config;
  33. use Template::Constants;
  34. use Template::Exception;
  35. use Template::Service;
  36.  
  37. $VERSION = sprintf("%d.%02d", q$Revision: 1.3 $ =~ /(\d+)\.(\d+)/);
  38. $DEBUG   = 0 unless defined $DEBUG;
  39.  
  40. use Apache::Util qw( escape_path format_time );
  41. use Apache::Const -compile => qw( DECLINED SERVER_ERROR);
  42. use Apache::Log ();
  43. use Apache::RequestRec ();
  44. use Apache::Request 2.02;
  45.  
  46. #========================================================================
  47. #                     -----  PUBLIC METHODS -----
  48. #========================================================================
  49.  
  50. #------------------------------------------------------------------------
  51. # template($request)
  52. #
  53. # Fetch root template document from the ROOT_PROVIDER using the 
  54. # request filename.  Returns a reference to a Template::Document
  55. # object on success or a DECLINED status code if not found.  On error,
  56. # the relevant error message is logged and SERVER_ERROR is returned.
  57. #------------------------------------------------------------------------
  58.  
  59. sub template {
  60.     my ($self, $r) = @_;
  61.     my $filename = $r->filename();
  62.     
  63.     return Apache::DECLINED unless -f $filename;
  64.     $self->{ TEMPLATE_ERROR } = undef;
  65.  
  66.     my ($template, $error) = $self->{ ROOT_PROVIDER }->fetch($filename);
  67.     if ($error && $error == &Template::Constants::STATUS_DECLINED) {
  68.         return Apache::DECLINED;
  69.     }
  70.     elsif ($error) {
  71.         # save error as exception for params() to add to template vars
  72.         $self->{ TEMPLATE_ERROR } = Template::Exception->new(
  73.             Template::Constants::ERROR_FILE, $template
  74.         );
  75.         
  76.         # if there is an ERROR template defined then we attempt to 
  77.         # fetch it as a substitute for the original template.  Note 
  78.         # that we must fetch it from the regular template providers
  79.         # in the Template::Context because they honour the INCLUDE_PATH 
  80.         # parameters whereas the ROOT_PROVIDER expects an absolute file
  81.         
  82.         if ($template = $self->{ ERROR }) {
  83.             eval { $template = $self->{ CONTEXT }->template($template) };
  84.             if ($@) {
  85.                 $r->log_error($self->{ TEMPLATE_ERROR } . " / $@", ' ', $filename);
  86.                 return Apache::SERVER_ERROR;
  87.             }
  88.         }
  89.         else {
  90.             $r->log_error($template, ' ', $filename);
  91.             return Apache::SERVER_ERROR;
  92.         }
  93.     }
  94.     
  95.     return $template;
  96. }
  97.  
  98.  
  99. #------------------------------------------------------------------------
  100. # params($request, $params)
  101. #
  102. # Create a set of processing parameters (i.e. template variables) for
  103. # the request.
  104. #------------------------------------------------------------------------
  105.  
  106. sub params {
  107.     my ($self, $request, $params) = @_;
  108.     $params ||= { };
  109.  
  110.     my $plist = $self->{ SERVICE_PARAMS };
  111.     my $all = $plist->{ all };
  112.  
  113.     return $params unless keys %$plist;
  114.     $request = Apache::Request->new($request);
  115.  
  116.     $params->{ env } = { %{ $request->subprocess_env() } }
  117.         if $all or $plist->{ env };
  118.  
  119.     $params->{ uri } = $request->subprocess_env('REDIRECT_URL') || $request->uri()
  120.         if $all or $plist->{ uri };
  121.  
  122.     $params->{ pnotes } = $request->pnotes()
  123.         if $all or $plist->{ pnotes };
  124.  
  125.     $params->{ params } = { %{ $request->parms() } }
  126.         if $all or $plist->{ params };
  127.  
  128.     $params->{ request } = $request
  129.         if $all or $plist->{ request };
  130.  
  131.     if ($all or $plist->{ uploads }) {
  132.         my @uploads = $request->upload;
  133.         $params->{ uploads } = \@uploads;
  134.     }
  135.  
  136.     $params->{ cookies } = { 
  137.         map { $1 => escape_path($2, $request->pool) if (/([^=]+)=(.*)/) }
  138.         grep(!/^$/, split(/;\s*/, $request->header_in('cookie'))),
  139.     } if $all or $plist->{ cookies };
  140.     
  141.     # add any error raised by main template failure
  142.     $params->{ error } = $self->{ TEMPLATE_ERROR };
  143.  
  144.     return $params;
  145. }
  146.  
  147.  
  148. #------------------------------------------------------------------------
  149. # headers($request, $template, $content_ref)
  150. #
  151. # Set and then send the required http headers.
  152. #------------------------------------------------------------------------
  153.  
  154. sub headers {
  155.     my ($self, $r, $template, $content) = @_;
  156.     my $headers = $self->{ SERVICE_HEADERS };
  157.     my $all = $headers->{ all };
  158.  
  159.     $r->content_type('text/html');
  160.     $r->headers_out->add('Content-Length' => length $$content)
  161.         if $all or $headers->{ length };
  162.     $r->headers_out->add('E-tag' => sprintf q{"%s"}, md5_hex($$content))
  163.         if $all or $headers->{ etag };
  164.  
  165.     if ($all or $headers->{ modified } and $template) {
  166.         my $fmt = '%a, %d %b %Y %H:%M:%S %Z';
  167.  
  168.         my $ht_time = Apache::Util::format_time($template->modtime(),
  169.                                                 $fmt, 1, $r->pool);
  170.  
  171.         $r->headers_out->add('Last-Modified'  => $ht_time)
  172.     }
  173. }
  174.  
  175.  
  176. #------------------------------------------------------------------------
  177. # _init()
  178. #
  179. # In additional to the regular template providers (Template::Provider
  180. # objects) created as part of the context initialisation and used to
  181. # deliver templates loaded via INCLUDE, PROCESS, etc., we also create
  182. # a single additional provider responsible for loading the main
  183. # template.  We do this so that we can enable its ABSOLUTE flag,
  184. # allowing us to specify a requested template by absolute filename (as
  185. # Apache provides for us in $r->filename()) but without forcing all
  186. # other providers to honour the ABSOLUTE flag.  We pre-create a PARSER
  187. # object (Template::Parser) which can be shared across all providers.
  188. #------------------------------------------------------------------------
  189.  
  190. sub _init {
  191.     my ($self, $config) = @_;
  192.  
  193.     # create a parser to be shared by all providers
  194.     $config->{ PARSER } ||= Template::Config->parser($config) 
  195.         || return $self->error(Template::Config->error());
  196.  
  197.     # create a provider for the root document
  198.     my $rootcfg = {
  199.         ABSOLUTE => 1,
  200.         map { exists $config->{ $_ } ? ($_, $config->{ $_ }) : () }
  201.         qw( COMPILE_DIR COMPILE_EXT CACHE_SIZE PARSER ),
  202.     };
  203.  
  204.     my $rootprov = Template::Config->provider($rootcfg)
  205.         || return $self->error(Template::Config->error());
  206.  
  207.     # now let the Template::Service superclass initialiser continue
  208.     $self->SUPER::_init($config)
  209.         || return undef;
  210.  
  211.     # save reference to root document provider
  212.     $self->{ ROOT_PROVIDER } = $rootprov;
  213.  
  214.     # extract other relevant SERVICE_* config items
  215.     foreach (qw( SERVICE_HEADERS SERVICE_PARAMS )) {
  216.         my $item = $config->{ $_ } || [ ];
  217.         $self->{ $_ } = { map { $_ => 1 } @$item };
  218.     }
  219.     
  220.     return $self;
  221. }
  222.     
  223. 1;
  224.