<html><head><meta name="color-scheme" content="light dark"></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;">package Apache::AccessLimitNum;
use strict;
use Apache::Constants ':common';
use NDBM_File;
use Fcntl qw(&amp;O_RDWR &amp;O_CREAT);

my $Flags = O_RDWR|O_CREAT;
 
sub handler {
    my($r) = @_;

    return OK unless $r-&gt;is_initial_req; #only first internal request

    my $limit_num = $r-&gt;dir_config("AccessLimitNum") or
	return DECLINED;
    my $dbm_file = $r-&gt;dir_config("AccessLimitNumFile") or
	return DECLINED;

    my %AccessNum;
    unless(tie(%AccessNum =&gt; 'NDBM_File', $dbm_file, $Flags, undef)) {
	$r-&gt;log_reason("Can't open $dbm_file $!", $r-&gt;uri);
	return SERVER_ERROR;
    }

    my $user = $r-&gt;connection-&gt;user;
    return DECLINED unless $user;

    my $status = OK; 
    if(++$AccessNum{$user} &gt;= $limit_num) {
	$r-&gt;log_reason("User $user access limit exceeded $limit_num", $r-&gt;uri);
        $r-&gt;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

 &lt;Limit GET&gt;
 require valid-user #or some such
 &lt;/Limit&gt;

=head1 DESCRIPTION

Decide if an authenticated user has exceeded an access limit for the 
requested realm, if so, forbid access.

B&lt;AccessLimitFile&gt; is a dbm file consisting of I&lt;username&gt; = I&lt;number&gt; value 
pairs.  This file must be writeable by httpd server process.

=head1 SEE ALSO

Apache(3)

=head1 AUTHOR

Doug MacEachern &lt;dougm@osf.org&gt;




</pre></body></html>