Beefy Boxes and Bandwidth Generously Provided by pair Networks
Don't ask to ask, just ask
 
PerlMonks  

comment on

( [id://3333]=superdoc: print w/replies, xml ) Need Help??
As suggested by a monk a few days past, to help put a stop to these bandwidth whores that are scraping my site for images, I was told to look at modperl http://www.modperl.com/book/chapters/ch6.html#Blocking_Greedy_Clients.

The code below is what they say I should use. I understand the code, but not where to use it. This is a module, is it not? Do I just save this as a .pm and use it in my .htaccess file? Or how do I go about getting this code to work?

package Apache::SpeedLimit; # file: Apache/SpeedLimit.pm use strict; use Apache::Constants qw(:common); use Apache::Log (); use IPC::Shareable (); use vars qw(%DB); sub handler { my $r = shift; return DECLINED unless $r->is_main; # don't handle sub-requests my $speed_limit = $r->dir_config('SpeedLimit') || 10; # Accesses +per minute my $samples = $r->dir_config('SpeedSamples') || 10; # Sampling +threshold (hits) my $forgive = $r->dir_config('SpeedForgive') || 20; # Forgive a +fter this period (minutes) my $expire = $r->dir_config('SpeedExpire') || 40; # Expire unus +ed # records from memory after this period (mi +nutes) my $content_type = $r->lookup_uri($r->uri)->content_type; return OK if $content_type =~ m:^image/:i; # ignore images tie %DB, 'IPC::Shareable', 'SPLM', {create => 1, mode => 0644} unless defined %DB; my($ip, $agent) = ($r->connection->remote_ip, $r->header_in('User +-Agent')); my $id = "$ip:$agent"; my $now = time()/60; # minutes since the epoch # lock the shared memory while we work with it tied(%DB)->shlock; my($first, $last, $hits, $locked) = split ' ', $DB{$id}; my $result = OK; my $l = $r->server->log; CASE: { unless ($first) { # we're seeing this client for the first tim +e $l->debug("First request from $ip. Initializing speed cou +nter."); $first = $last = $now; $hits = $locked = 0; last CASE; } if ($now - $last > $forgive) { # beyond the grace period. Tre +at like first $l->debug("$ip beyond grace period. Reinitializing speed +counter."); $last = $first = $now; $hits = $locked = 0; last CASE; } # update the values now $last = $now; $hits++; if ($hits < $samples) { $l->debug("$ip not enough samples to calculate speed."); last CASE; } if ($locked) { # already locked out, so forbid access $l->debug("$ip locked"); $result = FORBIDDEN; last CASE; } my $interval = $now - $first; $l->debug("$ip speed = ", $hits/$interval); if ($hits/$interval > $speed_limit) { $l->debug("$ip exceeded speed limit. Blocking."); $locked = 1; $result = FORBIDDEN; last CASE; } } $r->log_reason("Client exceeded speed limit.", $r->filename) if $result == FORBIDDEN; $DB{$id} = join " ", $first, $now, $hits, $locked; foreach my $key (keys %DB) { my ($first, $last, $hits, $locked) = split(' ', $DB{$key}); if ($now - $last > $expire) { delete $DB{$key}; } } tied(%DB)->shunlock; return $result; } 1; __END__


In reply to mod_perl blocking greedy clients by Anonymous Monk

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post; it's "PerlMonks-approved HTML":



  • Are you posting in the right place? Check out Where do I post X? to know for sure.
  • Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
    <code> <a> <b> <big> <blockquote> <br /> <dd> <dl> <dt> <em> <font> <h1> <h2> <h3> <h4> <h5> <h6> <hr /> <i> <li> <nbsp> <ol> <p> <small> <strike> <strong> <sub> <sup> <table> <td> <th> <tr> <tt> <u> <ul>
  • Snippets of code should be wrapped in <code> tags not <pre> tags. In fact, <pre> tags should generally be avoided. If they must be used, extreme care should be taken to ensure that their contents do not have long lines (<70 chars), in order to prevent horizontal scrolling (and possible janitor intervention).
  • Want more info? How to link or How to display code and escape characters are good places to start.
Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Chatterbox?
and the web crawler heard nothing...

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

    No recent polls found