App responding differently to ajax calls under plackup than Apache - possibly bug
Hi, I'm moving to plackup because of the well know contamination problem under Dancer when running multiple apps with Plack::Handler::Apache2. My app.psgi is basically a copy of the one in the documentation - ta for that. $ plackup -s Starman --workers=10 -p 5000 -a app.psgi My apache cfg is basically <VirtualHost *:80> ServerName www.app.new ServerAlias app.new DocumentRoot /home/stephen/app <Location /> SetHandler perl-script PerlHandler Plack::Handler::Apache2 PerlSetVar psgi_app /home/stephen/app/bin/app.pl </Location> </VirtualHost> The route: ajax '/locations/box/:nelat/:swlat/:nelng/:swlng' => sub { my ($locs) = Locations->new(); return $locs->search( { mode => 'box' } ); }; is used correctly by apache version, but starman gets: get '/locations/box/:nelat/:swlat/:nelng/:swlng' => sub { set serializer => 'JSON'; my ($locs) = Locations->new(); return $locs->search( { mode => 'box' } ); }; It can not see the ajax route. Examining the starman version's request I see "ajax => 0" because "headers => undef" and that is what Dancer::Request::is_ajax uses to determine whether the call is ajaxed or not. although the starman's version request does contain x_requested_with => "XMLHttpRequest" but it is not within 'headers' so it is not seen by is_ajax. I made this change to Dancer::Request sub is_ajax { my $self = shift; return 1 if (defined $self->{x_requested_with} && ( $self->{x_requested_with} eq "XMLHttpRequest") ); # new return 0 unless defined $self->headers; return 0 unless defined $self->header('X-Requested-With'); return 0 if $self->header('X-Requested-With') ne 'XMLHttpRequest'; return 1; } and it appears to work. Is this a sensible change?
On Tue, Nov 15, 2011 at 3:52 AM, Stephen Fenwick-Paul <stephen@activeg.org> wrote:
Hi, I'm moving to plackup because of the well know contamination problem under Dancer when running multiple apps with Plack::Handler::Apache2. My app.psgi is basically a copy of the one in the documentation - ta for that. $ plackup -s Starman --workers=10 -p 5000 -a app.psgi My apache cfg is basically <VirtualHost *:80>
ServerName www.app.new ServerAlias app.new DocumentRoot /home/stephen/app <Location /> SetHandler perl-script PerlHandler Plack::Handler::Apache2 PerlSetVar psgi_app /home/stephen/app/bin/app.pl </Location>
</VirtualHost> The route: ajax '/locations/box/:nelat/:swlat/:nelng/:swlng' => sub { my ($locs) = Locations->new(); return $locs->search( { mode => 'box' } ); }; is used correctly by apache version, but starman gets: get '/locations/box/:nelat/:swlat/:nelng/:swlng' => sub { set serializer => 'JSON'; my ($locs) = Locations->new(); return $locs->search( { mode => 'box' } ); }; It can not see the ajax route. Examining the starman version's request I see "ajax => 0" because "headers => undef" and that is what Dancer::Request::is_ajax uses to determine whether the call is ajaxed or not. although the starman's version request does contain x_requested_with => "XMLHttpRequest" but it is not within 'headers' so it is not seen by is_ajax.
I made this change to Dancer::Request
sub is_ajax { my $self = shift; return 1 if (defined $self->{x_requested_with} && ( $self->{x_requested_with} eq "XMLHttpRequest") ); # new return 0 unless defined $self->headers; return 0 unless defined $self->header('X-Requested-With'); return 0 if $self->header('X-Requested-With') ne 'XMLHttpRequest'; return 1; } and it appears to work. Is this a sensible change?
Thanks, that seems reasonable. I had the same problem except with plackup vs nginx. I got around it by replacing all of the: ajax '/foo' => sub { ... } with: get '/ajax/foo' => sub { ... } It took me a very long time to debug that. Hopefully your fix will solve and save others time. Also, your fix could be slightly shorter: return 1 if $self->{x_requested_with} and $self->{x_requested_with} eq "XMLHttpRequest"; -Naveed
participants (2)
-
Naveed Massjouni -
Stephen Fenwick-Paul