From 3cb623e7c2658909802d2b8cccf333275f3ccd90 Mon Sep 17 00:00:00 2001 From: posativ Date: Thu, 18 Oct 2012 16:16:36 +0200 Subject: [PATCH] check if url exists before creating a comment --- isso/__init__.py | 3 +++ isso/comment.py | 9 ++++++--- isso/utils.py | 23 +++++++++++++++++++++++ specs/test_comment.py | 2 +- 4 files changed, 33 insertions(+), 4 deletions(-) diff --git a/isso/__init__.py b/isso/__init__.py index b610817..4fe1faa 100644 --- a/isso/__init__.py +++ b/isso/__init__.py @@ -53,16 +53,19 @@ url_map = Map([ class Isso: + PRODUCTION = True SECRET_KEY = ',\x1e\xbaY\xbb\xdf\xe7@\x85\xe3\xd9\xb4A9\xe4G\xa6O' MODERATION = False SQLITE = None + HOST = 'http://localhost:8000/' MAX_AGE = 15*60 def __init__(self, conf): self.__dict__.update(dict((k, v) for k, v in conf.iteritems() if k.isupper())) self.signer = URLSafeTimedSerializer(self.SECRET_KEY) + self.HOST = utils.determine(self.HOST) if self.SQLITE: self.db = db.SQLite(self) diff --git a/isso/comment.py b/isso/comment.py index 2bd0f50..b4ec839 100644 --- a/isso/comment.py +++ b/isso/comment.py @@ -8,15 +8,18 @@ from werkzeug.exceptions import abort from itsdangerous import SignatureExpired, BadSignature -from isso import json, models +from isso import json, models, utils def create(app, environ, request, path): + if app.PRODUCTION and not utils.urlexists(app.HOST, path): + return abort(404) + try: rv = app.db.add(path, models.Comment.fromjson(request.data)) - except ValueError as e: - return Response(unicode(e), 400) + except ValueError: + return abort(400) response = Response(json.dumps(rv), 201, content_type='application/json') response.set_cookie('session', app.signer.dumps([path, rv.id]), max_age=app.MAX_AGE) diff --git a/isso/utils.py b/isso/utils.py index 4b59761..726d087 100644 --- a/isso/utils.py +++ b/isso/utils.py @@ -4,6 +4,11 @@ # License: BSD Style, 2 clauses. see isso/__init__.py import json +import socket +import httplib +import urlparse +import contextlib + from isso.models import Comment @@ -14,3 +19,21 @@ class IssoEncoder(json.JSONEncoder): return dict((field, value) for field, value in obj.iteritems()) return json.JSONEncoder.default(self, obj) + + +def urlexists(host, path): + with contextlib.closing(httplib.HTTPConnection(host)) as con: + try: + con.request('HEAD', path) + except socket.error: + return False + return con.getresponse().status == 200 + + +def determine(host): + """Make `host` compatible with :py:mod:`httplib`.""" + + if not host.startswith(('http://', 'https://')): + host = 'http://' + host + rv = urlparse.urlparse(host) + return (rv.netloc + ':443') if rv.scheme == 'https' else rv.netloc diff --git a/specs/test_comment.py b/specs/test_comment.py index 91068d4..ef04e96 100644 --- a/specs/test_comment.py +++ b/specs/test_comment.py @@ -17,7 +17,7 @@ class TestComments(unittest.TestCase): def setUp(self): fd, self.path = tempfile.mkstemp() - self.app = Isso({'SQLITE': self.path}) + self.app = Isso({'SQLITE': self.path, 'PRODUCTION': False}) self.client = Client(self.app, Response) self.get = lambda *x, **z: self.client.get(*x, **z)