circumvent CGI 1.1 specs (PATH_INFO is quoted)

pull/16/head
posativ 12 years ago
parent 3cb623e7c2
commit f2eff22ff7

@ -20,7 +20,7 @@
#
# Isso a lightweight Disqus alternative
__version__ = '0.1'
__version__ = '0.2'
import json
@ -33,22 +33,24 @@ from werkzeug.exceptions import HTTPException, NotFound, InternalServerError
from isso import admin, comment, db, utils
# override default json :func:`dumps`.
_dumps = json.dumps
setattr(json, 'dumps', lambda obj, **kw: _dumps(obj, cls=utils.IssoEncoder, **kw))
# yep. lazy.
url = lambda path, endpoint, methods: Rule(path, endpoint=endpoint, methods=methods)
url_map = Map([
# moderation panel
url('/', 'admin.index', ['GET', 'POST']),
# comments API
url('/comment/<string:path>/', 'comment.get', ['GET']),
url('/comment/<string:path>/new', 'comment.create', ['POST']),
url('/comment/<string:path>/<int:id>', 'comment.get', ['GET']),
url('/comment/<string:path>/<int:id>', 'comment.modify', ['PUT', 'DELETE']),
])
# comment API, note that the client side quotes the URL, but this is
# actually unnecessary. PEP 333 aka WSGI always unquotes PATH_INFO.
url('/comment/<re(".+"):path>/', 'comment.get', ['GET']),
url('/comment/<re(".+"):path>/new', 'comment.create', ['POST']),
url('/comment/<re(".+"):path>/<int:id>', 'comment.get', ['GET']),
url('/comment/<re(".+"):path>/<int:id>', 'comment.modify', ['PUT', 'DELETE']),
], converters={'re': utils.RegexConverter})
class Isso:
@ -59,7 +61,7 @@ class Isso:
SQLITE = None
HOST = 'http://localhost:8000/'
MAX_AGE = 15*60
MAX_AGE = 15 * 60
def __init__(self, conf):
@ -101,5 +103,10 @@ class Isso:
def main():
app = Isso({'SQLITE': '/tmp/sqlite.db'})
run_simple('127.0.0.1', 8080, app)
from os.path import join, dirname
from werkzeug.wsgi import SharedDataMiddleware
app = Isso({'SQLITE': '/tmp/sqlite.db', 'PRODUCTION': False})
app = SharedDataMiddleware(app,{
'/static': join(dirname(__file__), 'static')})
run_simple('127.0.0.1', 8000, app, use_reloader=True)

@ -13,7 +13,7 @@ from isso import json, models, utils
def create(app, environ, request, path):
if app.PRODUCTION and not utils.urlexists(app.HOST, path):
if app.PRODUCTION and not utils.urlexists(app.HOST, '/' + path):
return abort(404)
try:

@ -99,7 +99,7 @@ class SQLite(Abstract):
def add(self, path, c):
with sqlite3.connect(self.dbpath) as con:
keys = ','.join(self.fields)
values = ','.join('?'*len(self.fields))
values = ','.join('?' * len(self.fields))
con.execute('INSERT INTO comments (%s) VALUES (%s);' % (keys, values), (
0, path, c.created, c.modified, c.text, c.author, c.email, c.website,
c.parent, self.mode)

@ -8,6 +8,7 @@ import socket
import httplib
import urlparse
import contextlib
import werkzeug.routing
from isso.models import Comment
@ -21,6 +22,12 @@ class IssoEncoder(json.JSONEncoder):
return json.JSONEncoder.default(self, obj)
class RegexConverter(werkzeug.routing.BaseConverter):
def __init__(self, url_map, *items):
super(RegexConverter, self).__init__(url_map)
self.regex = items[0]
def urlexists(host, path):
with contextlib.closing(httplib.HTTPConnection(host)) as con:
try:

@ -1,4 +1,5 @@
import urllib
import tempfile
import unittest
@ -64,7 +65,7 @@ class TestComments(unittest.TestCase):
def testGetInvalid(self):
assert self.get('/comment/path/123').status_code == 404
assert self.get('/comment/path/spam').status_code == 404
assert self.get('/comment/path/spam/123').status_code == 404
assert self.get('/comment/foo/').status_code == 404
def testUpdate(self):
@ -102,3 +103,15 @@ class TestComments(unittest.TestCase):
assert self.get('/comment/path/1').status_code == 200
assert self.get('/comment/path/2').status_code == 200
def testPathVariations(self):
paths = ['/sub/path/', '/path.html', '/sub/path.html', '%2Fpath/%2F']
for path in paths:
assert self.post('/comment/' + path + '/new',
data=json.dumps(comment(text='...'))).status_code == 201
for path in paths:
assert self.get('/comment/' + path)
assert self.get('/comment/' + path + '/1')

Loading…
Cancel
Save