From: Fredrik Tolf Date: Sun, 8 Nov 2015 03:01:08 +0000 (+0100) Subject: Merge branch 'master' into python2 X-Git-Url: http://dolda2000.com/gitweb/?p=wrw.git;a=commitdiff_plain;h=b6f62b898efdc272130d3dbdd6742c5b785e7c7d;hp=2b4cce75e1eb09715b27fa94b63484c0a6f5a032 Merge branch 'master' into python2 Conflicts: wrw/auth.py wrw/form.py wrw/proto.py wrw/session.py --- diff --git a/wrw/auth.py b/wrw/auth.py index 4ae292d..bb0e0cd 100644 --- a/wrw/auth.py +++ b/wrw/auth.py @@ -1,5 +1,5 @@ import binascii, hashlib, threading, time -import resp +import resp, proto class unauthorized(resp.httperror): def __init__(self, challenge, message=None, detail=None): @@ -31,7 +31,7 @@ def parsebasic(req): if mech != "basic": return None, None try: - raw = binascii.a2b_base64(data) + raw = proto.unb64(data) except binascii.Error: return None, None p = raw.find(":") diff --git a/wrw/form.py b/wrw/form.py index da13a4a..76abab6 100644 --- a/wrw/form.py +++ b/wrw/form.py @@ -7,9 +7,12 @@ def formparse(req): buf = {} buf.update(urlparse.parse_qsl(req.query)) if req.ihead.get("Content-Type") == "application/x-www-form-urlencoded": - rbody = req.input.read(2 ** 20) + try: + rbody = req.input.read(2 ** 20) + except IOError as exc: + return exc if len(rbody) >= 2 ** 20: - raise ValueError("x-www-form-urlencoded data is absurdly long") + return ValueError("x-www-form-urlencoded data is absurdly long") buf.update(urlparse.parse_qsl(rbody)) return buf @@ -81,7 +84,9 @@ class formpart(object): return ret def close(self): - self.fillbuf(-1) + while True: + if self.read(8192) == "": + break def __enter__(self): return self @@ -152,5 +157,10 @@ class multipart(object): self.lastpart.parsehead() return self.lastpart -def formdata(req): - return req.item(formparse) +def formdata(req, onerror=Exception): + data = req.item(formparse) + if isinstance(data, Exception): + if onerror is Exception: + raise data + return onerror + return data diff --git a/wrw/proto.py b/wrw/proto.py index 3dcf0d7..a67fa19 100644 --- a/wrw/proto.py +++ b/wrw/proto.py @@ -1,4 +1,4 @@ -import time, calendar +import time, calendar, collections, binascii, base64 statusinfo = { 400: ("Bad Request", "Invalid HTTP request."), @@ -105,7 +105,7 @@ def urlq(url): if isinstance(url, unicode): url = url.encode("utf-8") ret = "" - invalid = "&=#?/\"'" + invalid = ";&=#?/\"'" for c in url: if c in invalid or (ord(c) <= 32) or (ord(c) >= 128): ret += "%%%02X" % ord(c) @@ -194,3 +194,22 @@ def parurl(url, pars={}, **augment): return url + "?" + qs else: return url + +# Wrap these, since binascii is a bit funky. :P +def enhex(bs): + return base64.b16encode(bs) +def unhex(es): + return base64.b16decode(es) +def enb32(bs): + return base64.b32encode(bs) +def unb32(es): + if (len(es) % 8) != 0: + es += b"=" * (8 - (len(es) % 8)) + es = es.upper() # The whole point of Base32 is that it's case-insensitive :P + return base64.b32decode(es) +def enb64(bs): + return base64.b64encode(bs) +def unb64(es): + if (len(es) % 4) != 0: + es += b"=" * (4 - (len(es) % 4)) + return base64.b64decode(es) diff --git a/wrw/session.py b/wrw/session.py index 0c585a3..476113a 100644 --- a/wrw/session.py +++ b/wrw/session.py @@ -1,5 +1,9 @@ import threading, time, pickle, random, os +<<<<<<< HEAD import cookie, env +======= +from . import cookie, env, proto +>>>>>>> master __all__ = ["db", "get"] @@ -8,7 +12,7 @@ def gennonce(length): class session(object): def __init__(self, lock, expire=86400 * 7): - self.id = gennonce(16).encode("hex") + self.id = proto.enhex(gennonce(16)) self.dict = {} self.lock = lock self.ctime = self.atime = self.mtime = int(time.time()) diff --git a/wrw/util.py b/wrw/util.py index 92b441c..22bce9d 100644 --- a/wrw/util.py +++ b/wrw/util.py @@ -10,7 +10,10 @@ def wsgiwrap(callable): def formparams(callable): spec = inspect.getargspec(callable) def wrapper(req): - data = form.formdata(req) + try: + data = form.formdata(req) + except IOError: + raise resp.httperror(400, "Invalid request", "Form data was incomplete") args = dict(data.items()) args["req"] = req if not spec.keywords: