Beefy Boxes and Bandwidth Generously Provided by pair Networks
Welcome to the Monastery
 
PerlMonks  

SOLVED: Limit URL length with Dancer/Starman

by gsiems (Deacon)
on Nov 07, 2013 at 21:05 UTC ( [id://1061626]=perlquestion: print w/replies, xml ) Need Help??

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

Brethren,

Using Apache, if submit a way-too-long request URL the server will respond with a 414 "Request-URI Too Large" error. If I try submitting a way-too-long URL to my Dancer application it causes the worker process to go to 100% CPU and (within a few seconds) the request fails. Is there a way to throw a 414 and avoid this behavior when Dancer running under Starman?

Many thanks for your input.

Update: The application is a restful service that supports multiple (read-only) web reporting applications and consists of one primary perl module and several additional "business" modules (one business module for each web-app). The main module takes care of all the database access, rendering, etc. and the "business" modules define the routes and configuration for each of the web-apps and are 90+% configuration. Each route consists of the base URL for that route plus query parameters for filtering the data to be returned.

Because of the way things are built it makes it easy to add new "business" modules; it also seems to mean that adding a "it's too long" route to the beginning of the primary module doesn't works as it appears that it is not necessarily the first route checked.

So far the effort has been in building the routes, making them work, and ensuring that things are secure. Reading Blog post on hardening Perl's hash function reminded me that I should also be spending a bit more time on making things robust to intentionally bad input. Currently, valid input parameters are un-tainted prior to using and invalid input parameters get dropped on the floor-- but what happens if/when a valid route with hundreds/thousands of invalid parameters are submitted?

Adding a "it's too long" route to the beginning of the primary module appears to only work if the route submitted doesn't match any of the business routes-- as such, it doesn't catch the case of the way-too-many intentionally mischevious input parameters. It also only catches the "too-long-invalid-route" after it's spent however much time looking at it.

I've tried using a "before hook" but I can't for the life of me figure out how to short-circuit the request at that point.

  • Comment on SOLVED: Limit URL length with Dancer/Starman

Replies are listed 'Best First'.
Re: Limit URL length with Dancer/Starman ( Plack::Middleware::ProhibitRequestUri8190 )
by Anonymous Monk on Nov 08, 2013 at 00:51 UTC
    How big is this URL you request?

    Is there a way to throw a 414 and avoid this behavior when Dancer running under Starman?

    Sure, add a check for URI size first in line :) http://search.cpan.org/dist/Dancer/lib/Dancer/Cookbook.pod#Default_route

    (untested)

    any qr{.{8190}.*} => sub { status '414'; # 414 - Request-URI Too Long };

    Or make a Plack::Middleware to do the check

    (untested)

    package Plack::Middleware::ProhibitRequestUri8190; use parent qw(Plack::Middleware); use Plack::Util; sub call { my($self, $env) = @_; my $res = $self->app->($env); if( length $res->{REQUEST_URI} > 8190 ){ Plack::Util::response_cb($res, sub { my $res = shift; $res->[0] = 414; return; }); } }

    plack middleware 414 request uri too large

      Thanks.

      The default route doesn't appear to do the trick (see the updated question).

      So far I've had no luck with the plack middleware, although http://advent.perldancer.org/2010/22 looks promising (towards the bottom where they wrap the app).

Re: Limit URL length with Dancer/Starman
by dasgar (Priest) on Nov 08, 2013 at 00:39 UTC

    Although I have used Dancer, I definitely don't consider myself to be an "expert" on Dancer.

    Looking through the Dancer documentation, here's one (untested) idea that might work.

    use Dancer; my $max_url_length = 100; # change this to what you want # first route handler any ['get', 'post'] => '.*' => sub { if ((length request->request_uri) > $max_url_length) { # do the 414 error page } else {pass(...);} }; # create other routes dance;

    The basic idea that I was trying to do in the above code was to have the first route handler that will catch everything and check the URL length. If it's above the max limit, give the 414 error page. Otherwise, pass the request on to the next matching route handler. Again, I haven't tested that code, so I can't guarantee that I'm reading documentation correctly.

      Thanks for the suggestion. It appears that, because of how things are written, I can't rely on the first route handler being the first one processed... at least it doesn't appear to work that way (see the updated question).

Re: Limit URL length with Dancer/Starman
by gsiems (Deacon) on Nov 14, 2013 at 21:39 UTC

    Solved.

    I was able to get the desired behavior by wrapping things in app.pl

    #!/usr/bin/env perl use Dancer; use REST_App; #dance; use Plack::Builder; my $app = sub { my $env = shift; if (length ($env->{REQUEST_URI}) > 1000) { return [ '414', [ 'Content-Type' => 'text/html' ], [ get_414_page() ], # HTML for the error page ]; } my $request = Dancer::Request->new(env => $env); Dancer->dance($request); }; builder { $app; };

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://1061626]
Approved by Old_Gray_Bear
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others wandering the Monastery: (5)
As of 2024-04-19 22:08 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found