package Apache::AccessLimitNum;
use strict;
use Apache::Constants ':common';
use NDBM_File;
use Fcntl qw(&O_RDWR &O_CREAT);
my $Flags = O_RDWR|O_CREAT;
sub handler {
my($r) = @_;
return OK unless $r->is_initial_req; #only first internal request
my $limit_num = $r->dir_config("AccessLimitNum") or
return DECLINED;
my $dbm_file = $r->dir_config("AccessLimitNumFile") or
return DECLINED;
my %AccessNum;
unless(tie(%AccessNum => 'NDBM_File', $dbm_file, $Flags, undef)) {
$r->log_reason("Can't open $dbm_file $!", $r->uri);
return SERVER_ERROR;
}
my $user = $r->connection->user;
return DECLINED unless $user;
my $status = OK;
if(++$AccessNum{$user} >= $limit_num) {
$r->log_reason("User $user access limit exceeded $limit_num", $r->uri);
$r->note_basic_auth_failure;
$status = FORBIDDEN;
}
untie %AccessNum;
return $status;
}
1;
__END__
=head1 NAME
Apache::AccessLimitNum - Limit user access by number of requests
=head1 SYNOPSIS
#server config or .htaccess
#use any authentication module
AuthName SomeRealm
Auth[DBM]UserFile /path/to/password/file
PerlAccessHandler Apache::AccessLimitNum
PerlSetVar AccessLimitNum 100
PerlSetVar AccessLimitFile /path/to/limit/file
require valid-user #or some such
=head1 DESCRIPTION
Decide if an authenticated user has exceeded an access limit for the
requested realm, if so, forbid access.
B is a dbm file consisting of I = I value
pairs. This file must be writeable by httpd server process.
=head1 SEE ALSO
Apache(3)
=head1 AUTHOR
Doug MacEachern