Hmmmm, the do does seem a little inefficient. I solved this problem in the
past by intiating a subrequest and changing the stack handler to
cgi-script right before running the cgi. something like this:

$subr = $r->lookup_uri($uri);
if($r->filename =~ /\.(cgi|pl)$)/o) {
    $subr->handler('cgi-script');
}
$subr->run();

you might get into some trouble with headers if your cgi's return
http headers other than just Content-type like Location. If they don't go 
ahead and add $r->send_http_header right before the run command. If they
do send other headers, you will need a patch for Apache.xs in the mod_perl
src. I have it and can give it to you if you are interested.

-amen

On Wed, 23 Aug 2000, Todd Finney wrote:

> Hi,
> 
> I'm building a simple templating system.   The major 
> requirement of the system is that allow custom dynamic 
> headers, footers, and toolbars based upon the identity of 
> the user.
> 
> The system so far works like this:
>          - a user enters the site and logs in.  The names 
> of the user's default
>          template, header, footer, and toolbar are placed 
> into a cookie
>          (via Apache::Session).
>          - when the user requests a page, my handler 
> intercepts that request, and
>          looks at the user's cookie.  Based upon the 
> information in it, it grabs the
>          appropriate template and components from the 
> filesystem along with the
>          requested page, rolls them together, and serves 
> the result.
> 
> A sample template file looks like this:
> 
> <html>
> <head><title>Standard Template</title></head>
> <body bgcolor="#ffffff">
> <table width="650" cellspacing="0" cellpadding="0" 
> border="0">
> <tr><td colspan="2" width="650" align="left"><!-- 
> Wrapper:header --><br></td></tr>
> <tr>
>   <td width="150" align="left" valign="top"><!-- 
> Wrapper:toolbar --><br></td>
>   <td width="500" align="left" valign="top"><!-- Content 
> --><br></td></tr>
> <tr><td colspan="2" width="650" align="left"><!-- 
> Wrapper:footer --><br></td></tr>
> </table>
> </body></html>
> 
> Component files, such as the header, footer and toolbar, 
> are by convention self-contained html tables, ala
> 
> # file components/tool/standard
> 
> <table width="100%">
> <tr><td align="center"><a href="/wrapped/one.html">Link 
> One</a><br></td></tr>
> <tr><td align="center"><a href="/wrapped/two.html">Link 
> Two</a><br></td></tr>
> <tr><td align="center"><a href="/wrapped/three.html">Link 
> Three</a><br></td></tr>
> <tr><td align="center"><a href="/wrapped/four.html">Link 
> Four</a><br></td></tr>
> <tr><td align="center"><a href="/wrapped/five.html">Link 
> Five</a><br></td></tr>
> <tr><td align="center"><a 
> href="/wrapped/cgi-bin/test.pl">CGI</a><br></td></tr></table>
> 
> I have a working version of this handler, but I think that 
> there's a better way to do it, specifically the part that 
> manages the content return part of the request.   Static 
> files are simple enough; I open the file and print it to 
> STDOUT.  Scripts, however, need to be handled 
> differently.   The way I'm doing it now works, but it 
> strikes me as inefficient.
> 
> package My::Wrapper;
> 
> use strict;
> use Apache::Constants qw(:common DONE);
> use Apache::Log ();
> 
> sub handler {
>      my ( $r ) = shift;
>      my ( $log ) = $r->log;
>      $log->info("Wrapper: Inside Wrapper.");
>      my ( $template_directory ) = "/www/html/templates/";
>      my ( $components_directory ) = 
> '/www/html/components/';
>      #
>      # these next four variables will come from the cookie, 
> they are
>      # set manually for now.
>      #
>      my ( $template ) = $template_directory.'standard';
>      my ( $header ) = 
> $components_directory.'head/'.'standard';
>      my ( $toolbar ) = 
> $components_directory.'tool/'.'standard';
>      my ( $footer ) = 
> $components_directory.'feet/'.'standard';
>      $r->send_http_header;
>      if ( -e $template ) {
>          open( TEMPLATE, "$template" ) or die "Failed to 
> open template $template: $!";
>          while (<TEMPLATE>) {
>              if ( $_ =~ 
> /(.*)<\!--\sWrapper:(\w+)\s-->(.*)/o ) {
>                  my ( $before ) = $1;
>                  my ( $component ) = $2;
>                  my ( $after ) = $3;
>                  my ( $name );
>                  $name = $header if $component eq 'header';
>                  $name = $toolbar if $component eq 
> 'toolbar';
>                  $name = $footer if $component eq 'footer';
>                  print $before; &print_component($name); 
> print $after;
>              } elsif ( $_ =~ /(.*)<\!--\sContent\s-->(.*)/o 
> ) {
>                  my ( $before ) = $1;
>                  my ( $after ) = $2;
>                  my ( $file ) = $r->filename;
>                  print $before;
>                  if ( -e $file ) {
>                      if ( $file =~ /(?:cgi|pl)$/ ) {
>                          $log->info("Wrapper: cgi script 
> requested.");
>                          do $file;
>                      } else {
>                          $log->info("Wrapper: static file 
> requested.");
>                          open(CONTENT, "$file" ) or die 
> "Failed to open content file $file: $!";
>                          while (<CONTENT>) {
>                              print $_;
>                          }
>                          close(CONTENT);
>                      }
>                  }
>                  print $after;
>              } else {
>                  print $_;
>              }
>          }
>          close( TEMPLATE );
>      }
>      $log->info("Wrapper: Exiting Wrapper.");
>      return DONE;
> }
> 
> sub print_component {
>      my ( $component ) = shift;
>      if ( -e $component ) {
>          open(IN, "$component" ) or die "Failed to open 
> component $component: $!";
>          while (<IN>) {
>              print $_;
>          }
>          close(IN);
>          return 1;
>      } else {
>          print "Failed to open component $component.";
>          return 0;
>      }
> }
> 1;
> __END__
> 
> I have experimented with various ways of handling this, 
> such as printing a redirect, but this is the only way I 
> could get it to work.  I suspect that there is a better way 
> to do it.   I'd rather not `` the script, because of 
> efficiency worries and the desire to maintain some process 
> environment variables used in our authentication systems.
> 
> Thanks a bunch,
> Todd
> 
> 
> 

Reply via email to