[Catalyst] Serving server-dependent static content

Valentin Tumarkin valentin-lists at fuzzycow.org
Thu Aug 16 15:44:09 GMT 2007


A project that I'm working on requires mix-and-mash of dynamic and
static content delivered from the same base path. My first priority
was not speed/performance, but flexibility and control. To be more
specific - in my case Catalyst-based application is the one that
decides, based on misc BL, which requests should be served by
Catalyst, and which by Apache.

Below is a description of how my solution to "$c->res->status(-1)" looks.

If anyone thinks this solution could be useful for other
Catalyst-based applications - I could write a more detailed HOWTO on
the subject.

Apache
------
Catalyst on top of Apache/mod_perl, via Engine::Apache module

<Location /dynamic_and_static>
   SetHandler modperl
   PerlFixupHandler MyApp::ModPerl::DirFix
   PerlResponseHandler MyApp::CatalystApp
   ....
</Location>

<Location /static_only>
   SetHandler default-hanlder
   ...
</Location

Catalyst
---------
In Catalyst I created a dedicated
MyApp::CatalystApp::View::Transparent view, to which I direct requests
that should be served by Apache.

In the "Transparent" View's process() method I set:

$c->engine->return( Apache2::Const::DECLINED );

This causes Catalyst to return "DECLINE" to Apache, forcing Apache to
handle the request itself.

Special considerations
----------------------
* Fix for directory handling, when using "DECLINE" (non-original -
slightly modified version of an example found on one of Apache-related
sites. I'm afraid I do not remember the URL or Author's name)

package MyApp::ModPerl::DirFix;

use strict;
use warnings FATAL => qw(all);
use Apache2::Const -compile => qw(DIR_MAGIC_TYPE OK DECLINED);
use Apache2::RequestRec;

sub handler {
        my $r = shift;
        if ( ! $r->is_initial_req) {
                 return Apache2::Const::DECLINED;
        }
        if ( ! ( $r->handler eq 'modperl' or $r->handler eq 'perl-script' ) ) {
                return Apache2::Const::DECLINED;
        }
        if ( ! -d $r->filename ) {
                return Apache2::Const::DECLINED;
        }
        $r->handler(Apache2::Const::DIR_MAGIC_TYPE);

        return Apache2::Const::OK;
}


* Catalyst::Plugin::Session:
If using Catalyst::Plugin::Session - install the latest version.
Versions 0.15-0.17 had a bug which prevented Catalyst from returning
DECLINE to Apache.


Regards,
Valentin


On 8/12/07, mreece at vinq.com <mreece at vinq.com> wrote:
> > On 8/12/07, Peter Lytle <pete at bluecampaigns.com> wrote:
> >> If someone has a  solution from the Apache side, that's fine but I
> >> suspect that it might be
> >> easier  to do this with Catalyst::Plugin::Static::Simple
> >
> > Don't serve static content through perl.  Let your webserver do it.
> > Usually people just set up virtual hosts with different
> > DOCUMENT_ROOTs.  Is there a reason that won't work for you?
> >
> > - Perrin
>
> a lot of times, 'static' content is found via database queries.  and
> sometimes that content needs to be protected from unauthorized viewers,
> and your authorization mechanisms are already built into your application,
> so you can't just use Alias/Rewrite directives to still have apache serve
> up that tree.
>
> that said, is there a way to have catalyst defer back to the web server,
> after deciding not to issue a 403?  has anyone experimented with using
> $c->res->status(-1) for this purpose?
>
>
> _______________________________________________
> List: Catalyst at lists.rawmode.org
> Listinfo: http://lists.rawmode.org/mailman/listinfo/catalyst
> Searchable archive: http://www.mail-archive.com/catalyst@lists.rawmode.org/
> Dev site: http://dev.catalyst.perl.org/
>



More information about the Catalyst mailing list