[cgiapp] cgi::application::dispatch under PSGI
Kurt Lidl
kurt.lidl at cello.com
Fri Mar 2 16:20:41 EST 2012
On 2/28/2012 2:33 PM, Rhesa Rozendaal wrote:
> On 02/28/2012 05:45 PM, Kurt Lidl wrote:
>> Greetings.
>>
>> I've got a large application that is running under mod_perl, running on
>> Apache 2.2.22.
>> Everything is working OK there. It uses CGI::Application::Dispatch as
>> its invocation
>> method.
> I'm using roughly the same stack, though I use starman in dev, and
> intend to do so in prod as well (behind an apache reverse proxy).
>
>> I became interested in making that application work under PSGI. Since
>> that is
>> now supported natively by modern versions of CGI::Application, I figured
>> it shouldn't
>> be too hard to make this work.
> It's not hard, but I found out it takes jumping through some hoops.
>
>> I've got a dead-simple .psgi file:
>>
>> --- snip, snip ---
>> use lib ('..');
>>
>> use Data::Dump qw(dump ddx);
>> use CWS1::Dispatch;
>>
>> CWS1::Dispatch->as_psgi;
>> --- snip, snip ---
> Here's mine, using your class name as example:
>
> --- snip, snip ---
> use CWS1::Dispatch;
> use CGI::PSGI;
>
> my $cgiapp = sub {
> my $env = shift;
> CWS1::Dispatch->as_psgi(
> args_to_new => {
> QUERY => CGI::PSGI->new($env),
> })->($env);
> };
> --- snip, snip ---
>
> The key here is that I found I needed to make sure each request gets a
> fresh instance of a CGI::PSGI object.
This was part of the problem I was having. Thanks for that tip. I am
now using
a .psgi file just like the one you constructed.
>> In my Dispatch.pm file, I have this:
> Mine is the same (in structure).
>
> There's nothing specific in my regular apps, and I do receive params
> from CA::Dispatch. So I think you'll get it working in your situation
> too, as long as you make sure you pass in a fresh CGI::PSGI object every
> time.
>
>
The trickier part to debug was this -- why I wasn't getting parameters
passed into
my application.
As it turns out, the LocationMatch directive I had was the problem:
<LocationMatch "^/cws1/(?!static/).*$">
SetHandler perl-script
PerlHandler Plack::Handler::Apache2
PerlSetVar psgi_app /path/to/websvc/CWS1/CWS1.psgi
Order allow,deny
Allow from all
</LocationMatch>
The Plack::Handler::Apache2 code whacks the PATH_INFO of the environment
after striping off the components of the original PATH_INFO that match the
regular expression in the LocationMatch.
Normally, you might have something like <LocationMatch "^/cws/foo">.
The problem with the regex I was using that it matched everything in the
PATH_INFO,
so the Apache2 handler was changing PATH_INFO into just "/", rather than
leaving
it as "/cws1".
I changed my LocationMatch directive to merely be: "^/cws1/(?!static/)"
and that works
just fine now.
I think, in my reading about this, that this is still subtly wrong, and
it really should be
"/+cws1/+(?!static/+)/". Because LocationMatch doesn't collapse multiple
slash
characters together. So /cws1//static would still be dispatched,
whereas /cws1/static
would not. (See the special "Note about / (slash)" section in the
Apache core module
documentation on the "Location" header, for the gory details.)
-Kurt
More information about the cgiapp
mailing list