atento has asked for the wisdom of the Perl Monks concerning the following question:

Hello, I'm porting CGI web application to mod_perl 2.0 So I wrote PerlResponseHandler for whole site and now I want to exclude some URL-locations like images, styles, etc from processing by mod_perl. I thinking now how to do it more efficiently and have no ideas now. Now I have this environment handles entire site by mod_perl: httpd.conf:
<VirtualHost> ... PerlOptions +Parent +GlobalRequest +Autoload PerlSwitches -I/some/path/lib SetHandler perl-script PerlResponseHandler My::Apache::Main </VirtualHost>
I prefer to write perl code instead of using config directives for more flexibility. I guess to write one additional handler module but cant choose which handler will help me from mod_perl api ? Any ideas how to exclude from mod_perl static content like
/images/*.* /css/*.* ...

Replies are listed 'Best First'.
Re: mod_perl how to process static content
by locked_user sundialsvc4 (Abbot) on Mar 24, 2008 at 17:07 UTC

    Each "virtual host" in the Apache environment is described by a series of directives, in this case particularly including Alias, ScriptAlias, and Directory. These directives tell Apache what to do with each URI.

    If you are using mod_rewrite, these rules are applied to the rewritten URI.

    In this case, you want certain aliases such as images/blah to simply be served from a certain existing disk-directory. The Alias directive can do that. (If you're using mod_rewrite, the rules must also allow these URIs to pass-through unchanged.) For these aliases, Apache is just doing what Apache normally does:   scooping-up the content of a file and shoving it down the pipe. The browser's also doing what it does best, caching things and not asking for them a second time unless it thinks it has to.

    You control what actually gets sent to (Perl), and this should be:   only the content that truly must be generated by a (Perl) program.

    What you are shooting-for is definitely a good thing, by-the-way. Let Apache do what it already knows how to do best, whenever possible. Bring Perl into the picture only for things that require a programmed response. Use custom error-documents to keep the overall site look-and-feel consistent while still letting Apache itself do a portion of the “heavy lifting.” Be aware of the natural caching behavior of browsers, also, and make sure that this too is working to your advantage as designed.

      Thanks for your wide answer. I'll keep in mind some of your tips. Yes, I researched documentation of mod_rewrite and LocationMatch configuration directive may be useful for. But I founded in google impossible to invert the whole regex in this directive. Eg this code is impossible as I understood:
      <LocationMatch <B>!~</B> /^(images|styles|js)/ > PerlOptions +Parent +GlobalRequest +Autoload PerlSwitches -I/some/path/lib SetHandler perl-script PerlResponseHandler My::Apache::Main </Location>
Re: mod_perl how to process static content
by perrin (Chancellor) on Mar 24, 2008 at 18:14 UTC
    Usually I just target specific URLs with mod_perl, by using Location blocks. However, if you really want to handle everything except some specific directories with mod_perl, you can use default-handler:
    SetHandler default-handler
    That tells apache to use the normal HTTP handler.
      Yeah, I know it but forget.

      Thanks!

      So now I will try to write PerlTransHandler which fired before PerlContentHandler and this code will set up default handler for location matches... hope it helps.
      Fuck, there are configuration directive and I have no ideas how to manipulate this from runtime.

      Meditating the Apache2::Const module got no results how to revert the default-handler :(
      Seems that apache "Handlers" are used to replace only "default-handler"s


      I've tried to set PerlResponseHandler at runtime in PerlTransHandler which rises before one.

      Apache config:
      <VirtualHost> SetHandler perl-script PerlTransHandler My::Apache::Rewrite </VirtualHost>

      My/Apache/Rewrite.pm
      -------------------------
      package My::Apache::Rewrite; use strict; use warnings; use Apache2::RequestRec (); use Apache2::Const -compile => qw(FORBIDDEN DECLINED OK DONE); sub handler { my $r = shift; unless(($r->uri ne '/' && !$r->args) && (-d $r->filename || -f $r- +>filename)) { $r->set_handlers(PerlResponseHandler => 'My::Apache::Main'); } return Apache2::Const::OK; } 1;
      No results because main handler is always set :(
        I don't see any good reason to do this anywhere but your conf file. However, if you really want to do it, look at the example here.
        GUYS! I FOUNDED THE SHORTEST WAY!

        Here addition to my original post:

        Add just only one line to handler's code begin in file:
        My/Apache/Main.pm ----------------
        sub handler { my $r = shift; return Apache2::Const::DECLINED if (-d $r->filename || -f $r->filename); ...
        Since now I'll smoke mod_perl api guide till it ends...