Make distinct error pages for throttled IPs and ratelimited UAs.

Also check for throttling before checking UAs so that
throttled IPs get a consistent message.
This commit is contained in:
Neil Williams
2012-02-01 14:50:04 -08:00
parent 19dd459e94
commit 4ef748d0f5
5 changed files with 59 additions and 41 deletions

View File

@@ -22,6 +22,7 @@
import os.path
from mako.filters import url_escape
import pylons
import paste.fileapp
from paste.httpexceptions import HTTPFound
from pylons.middleware import error_document_template, media_path
@@ -71,44 +72,6 @@ redditbroke = \
</html>
'''
toofast = \
'''<!doctype html>
<html>
<head>
<title>Too Many Requests</title>
<style>
body {
font: small verdana, arial, helvetica, sans-serif;
width: 600px;
margin: 0 auto;
}
h1 {
height: 40px;
background: transparent url(%(logo_url)s) no-repeat scroll top right;
}
</style>
</head>
<body>
<h1>whoa there, pardner!</h1>
<p>reddit's awesome and all, but you may have a bit of a
problem. we've seen far too many requests come from your ip address
recently.</p>
<p>if you think that we've incorrectly blocked you or you would like
to discuss easier ways to get the data you want, please contact us
any of the following ways.</p>
<ul>
<li><a href="http://webchat.freenode.net/?channels=reddit-ratelimit">#reddit-ratelimit on freenode</a></li>
<li><a href="http://groups.google.com/group/reddit-dev">the reddit-dev google group</a></li>
<li><a href="mailto:ratelimit@reddit.com">ratelimit@reddit.com</a></li>
</ul>
<p>when contacting us, please include your ip address which is: <strong>%(ip)s</strong></p>
<p>as a reminder, we recommend that clients make no more than one
request every two seconds to avoid being blocked like this.</p>
</body>
</html>
'''
class ErrorController(RedditController):
"""Generates error documents as and when they are required.
@@ -177,8 +140,16 @@ class ErrorController(RedditController):
def send429(self):
c.response.status_code = 429
return toofast % dict(ip=request.ip,
logo_url=static(g.default_header_url))
if 'retry_after' in request.environ:
c.response.headers['Retry-After'] = str(request.environ['retry_after'])
template_name = '/ratelimit_toofast.html'
else:
template_name = '/ratelimit_throttled.html'
loader = pylons.buffet.engines['mako']['engine']
template = loader.load_template(template_name)
return template.render(logo_url=static(g.default_header_url))
def send503(self):
c.response.status_code = 503

View File

@@ -416,6 +416,7 @@ def set_colors():
def ratelimit_agent(agent):
key = 'rate_agent_' + agent
if g.cache.get(key):
request.environ['retry_after'] = 1
abort(429)
else:
g.cache.set(key, 't', time = 1)
@@ -564,8 +565,8 @@ class MinimalController(BaseController):
#check if user-agent needs a dose of rate-limiting
if not c.error_page:
ratelimit_agents()
ratelimit_throttled()
ratelimit_agents()
c.allow_loggedin_cache = False

View File

@@ -0,0 +1,22 @@
<!doctype html>
<html>
<head>
<title>Too Many Requests</title>
<style>
body {
font: small verdana, arial, helvetica, sans-serif;
width: 600px;
margin: 0 auto;
}
h1 {
height: 40px;
background: transparent url(${logo_url}) no-repeat scroll top right;
}
</style>
</head>
<body>
<h1>whoa there, pardner!</h1>
${self.body()}
</body>
</html>

View File

@@ -0,0 +1,16 @@
<%inherit file="ratelimit_base.html"/>
<p>reddit's awesome and all, but you may have a bit of a
problem. we've seen far too many requests come from your ip address
recently.</p>
<p>if you think that we've incorrectly blocked you or you would like
to discuss easier ways to get the data you want, please contact us
any of the following ways.</p>
<ul>
<li><a href="http://webchat.freenode.net/?channels=reddit-ratelimit">#reddit-ratelimit on freenode</a></li>
<li><a href="http://groups.google.com/group/reddit-dev">the reddit-dev google group</a></li>
<li><a href="mailto:ratelimit@reddit.com">ratelimit@reddit.com</a></li>
</ul>
<p>when contacting us, please include your ip address which is: <strong>${request.ip}</strong></p>
<p>as a reminder, we recommend that clients make no more than one
request every two seconds to avoid being blocked like this.</p>

View File

@@ -0,0 +1,8 @@
<%inherit file="ratelimit_base.html"/>
<p>you appear to be a search engine spider or are coming to us via
AppEngine. to prevent abuse, we maintain a one request per second speed
limit from these sources. please wait a moment and try again.</p>
<p>if you are not a search engine spider, but are spoofing one via your
browser's user agent string, please change your user agent string to
avoid seeing this message again.</p>