[Catalyst-dev] nginx patch to Engine::FastCGI?

J. Shirley jshirley at gmail.com
Fri Oct 31 19:52:14 GMT 2008


On Thu, Oct 30, 2008 at 6:16 PM, Chris Carline <chris at carline.org> wrote:
> On Thu, Oct 30, 2008 at 8:35 PM, J. Shirley <jshirley at gmail.com> wrote:
>> I am working on a new nginx+fastcgi deployment, and this time the
>> Catalyst app is not at "/" like my previous other deployments.  It
>> seems that nginx doesn't quite jive with Catalyst out of the box in
>> this case.
>>
>> I'm going to just describe the problem, as my solution is far from
>> elegant, and hope that more Engine-centric folks can chime in with
>> better ideas.
>>
>> nginx doesn't distinguish the request path any different than the
>> subsequent path info (appended to the end of the path).  So,
>> $env{SCRIPT_NAME} and $env{PATH_INFO} are effectively the same value.
>> In the case of "/" this doesn't present any problem, but if your
>> application is at a different path ("/myapp" for example) then it
>> break.s
>>
>> The good thing is nginx allows for arbitrary variables to be set in
>> the FastCGI config space, so you can explicitly set SCRIPT_NAME or
>> PATH_INFO.  This doesn't help though with PATH_INFO always contains
>> information for $c->req->base to be built though.
>>
>> The solution I came up with is to tell nginx to define the variables as such:
>>
>> fastcgi_param  SCRIPT_NAME        /ems/;
>> fastcgi_param  PATH_INFO          $fastcgi_script_name; # Effectively
>> /ems/{PATH_INFO}
>>
>> And then, in Engine::FastCGI I have this small patch, to remove the duplication:
>>        if ( $env{SERVER_SOFTWARE} && $env{SERVER_SOFTWARE} =~ /nginx/ ) {
>>            $env{PATH_INFO} =~ s/^$env{SCRIPT_NAME}//g;
>>        }
>>
>> This is the only way I could get the base URI to be constructed
>> properly.  I'm not that experienced with nginx, but I couldn't find
>> anything at all in their documentation to help with it.
>>
>> Hopefully someone has some better thoughts on this...
>
> I don't know if it's a better thought, but I subclassed the
> prepare_path method of Engine::CGI in an Engine::FastCGI::WithParams
> module that reads the values (for said environment variables) I need
> from the application yaml if they exist... (updating the target engine
> in the <app>_fastcgi.pl script is also required).
>
> This also plays nicely with catalyst server and mod_perl deployments
> as they use different engines.
>
> It's a simple solution, but works well for my purposes (I'd rather
> push this sort of thing through application config rather than env
> vars tied to specific instances of my catalyst apps, as it means I can
> use the same web server config to instantiate catalyst services for
> everything).
>
> I'm hoping for better thoughts too, but deadlines being what they are...
>

I see your point on this, but it's a slightly different issue.  The
issue isn't one of changing or overriding configuration, it's about
just base functionality ($c->req->base) that should work out of the
box.  In my opinion nginx is going to be one of the most common
deployment platforms, for many reasons, and it would be harmful to
Catalyst to not work out of the box with it.

If there was a way to get the anchor part of the confg and do the
variable substitution there, I would much prefer that and just have a
cookbook entry.  That isn't quite possible, though.

I'm not too worried about minor patches for upstream servers, as
lighttpd requires a slight tweak to work properly with Engine::FastCGI
too.


-J

-- 
J. Shirley :: jshirley at gmail.com :: Killing two stones with one bird...
http://www.coldhardcode.com/



More information about the Catalyst-dev mailing list