root/trunk/lib/Perlbal/Plugin/MaxContentLength.pm

Revision 811, 2.1 kB (checked in by athomason, 12 months ago)

Add MaxContentLength plugin

Line 
1package Perlbal::Plugin::MaxContentLength;
2
3=head1 NAME
4
5Perlbal::Plugin::MaxContentLength - Reject large requests
6
7=head1 SYNOPSIS
8
9    LOAD MaxContentLength
10    CREATE SERVICE cgilike
11        # define a service...
12        SET max_content_length  = 100000
13        SET plugins             = MaxContentLength
14    ENABLE cgilike
15
16=head1 DESCRIPTION
17
18This module rejects requests that are larger than a configured limit. If a
19request bears a Content-Length header whose value exceeds the
20max_content_length value, the request will be rejected with a 413 "Request
21Entity Too Large" error.
22
23=head1 AUTHOR
24
25Adam Thomason, E<lt>athomason@sixapart.comE<gt>
26
27=head1 COPYRIGHT AND LICENSE
28
29Copyright 2008 Six Apart Ltd.
30
31This module is part of the Perlbal distribution, and as such can be distributed
32under the same licence terms as the rest of Perlbal.
33
34=cut
35
36use strict;
37use warnings;
38
39use Perlbal;
40
41sub load {
42    Perlbal::Service::add_tunable(
43        max_content_length => {
44            check_role => '*',
45            check_type => 'int',
46            des => "maximum Content-Length allowed, in bytes. 0 for no limit",
47            default => 0,
48        },
49    );
50    return 1;
51}
52
53use constant HANDLE_REQUEST => 0;
54use constant IGNORE_REQUEST => 1;
55
56sub register {
57    my ($class, $svc) = @_;
58
59    my $cfg = $svc->{extra_config};
60    return unless $cfg;
61
62    $svc->register_hook('MaxContentLength', 'start_http_request' => sub {
63        my $client = shift;
64        return IGNORE_REQUEST unless $client;
65
66        # allow request if max is disabled
67        return HANDLE_REQUEST unless $cfg->{max_content_length};
68
69        my $headers = $client->{req_headers};
70        return HANDLE_REQUEST unless $headers;
71
72        # allow requests which don't have a Content-Length header
73        my $length = $headers->header('content-length');
74        return HANDLE_REQUEST unless $length;
75
76        # allow requests under the cap
77        return HANDLE_REQUEST if $length <= $cfg->{max_content_length};
78
79        $client->send_response(413, "Content too long.\n");
80        return IGNORE_REQUEST;
81    });
82}
83
84sub unregister {
85    my ($class, $svc) = @_;
86
87    $svc->unregister_hooks('MaxContentLength');
88    return 1;
89}
90
911;
Note: See TracBrowser for help on using the browser.