RSS Hammering Protection

I have some RSS feeds that I want to stop people hammering more than x times per x mins

I have been playing with a SESSION script that does what I need, however I dont know if its possible to modify it. As the feed uses SUB sections like

rss.php?section=news
rss.php?section=reviews
rss.php?section=comments

Currently it blocks access to all the sections, what I would like is it on a per query basis. so the news, reviews and comments can be hit once per IP per x mins

I dont want to use MySQL as thats extra overhead, I was thinking about using a .txt but unsure how to do that


<?php
#config
$minutes = "15";
$time_window_seconds=$minutes*60;
$max_hits_per_ip_per_window=1;

function minutes( $seconds ){
	return sprintf( "%02.2d:%02.2d", floor( $seconds / 60 ), $seconds % 60 );
}


session_id( "sputnik" );
session_start();

#retrieve the global counter
$global_counter = 0;
if( isset($_SESSION['count']) ) {
    $global_counter = $_SESSION['count'];
}

#delete the session history if the time window is up
if (!isset($_SESSION['time'])) {
    $_SESSION['time'] = time();
} elseif( time() - $_SESSION['time'] > $time_window_seconds ) {
    session_unset();
    $_SESSION['time'] = time();
}

#now you can count hits from all users
#  until the global session expires of course 
#  you could use cron to persist from time to time
$_SESSION['count'] = ++$global_counter;

#count hits from each unique ip for rate limiting
#  don't persist this data
$ip=$_SERVER['REMOTE_ADDR'];
if (!isset($_SESSION["$ip"])) {
    $_SESSION["$ip"] = 1;
} else {
    $_SESSION["$ip"]++;
}

#show the user it's working
if( $_SESSION["$ip"] > $max_hits_per_ip_per_window ) {

	$waited = time() - $_SESSION['time'];
	$left = $time_window_seconds - $waited;

	//echo "<BR>You have waited  ".minutes($waited)." seconds, - ".minutes($left)." seconds left.<BR>";
	echo "<BR>Please wait ".minutes($left)." Min<BR>";
	die();
}
?>

Why not setup caching at a sensible interval based on the average time each section is updated?

This way all your clients are served, and your database is only queried at controlled levels.

KISS. :slight_smile:

You should also bear in mind that (most) RSS readers won’t utilise cookies, therefore your session mechanism would be moot.

ive gone the cache route before, I have just updated the rss to support search queries etc, and its not suitable to cache those.

I see the point with cookies, ill scrap that.

Logging via mysql would only generate 1 query to lookup, 1 to insert so wouldnt be as bad as someone hitting the rss lots.

Why not?

ill look at optimizing my cache routine a little more I guess then