X-Git-Url: http://dolda2000.com/gitweb/?p=wrw.git;a=blobdiff_plain;f=wrw%2Fproto.py;h=80e24197843c4b71f2ea04c7de826998a169eab2;hp=3dcf0d7a31d4c4ae8ab26c90a4db68c4df193427;hb=51a13716668cc48bf87e0d0296f8b9900fafe83b;hpb=87f2697cdea2cca6eb6cae7f1ff5e46a5d8133a3 diff --git a/wrw/proto.py b/wrw/proto.py index 3dcf0d7..80e2419 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."), @@ -98,19 +98,20 @@ def simpleerror(env, startreq, code, title, msg): """ % (title, title, htmlq(msg)) + buf = buf.encode("us-ascii") startreq("%i %s" % (code, title), [("Content-Type", "text/html"), ("Content-Length", str(len(buf)))]) return [buf] def urlq(url): - if isinstance(url, unicode): + if isinstance(url, str): url = url.encode("utf-8") ret = "" - invalid = "&=#?/\"'" + invalid = b"%;&=#?/\"'" for c in url: - if c in invalid or (ord(c) <= 32) or (ord(c) >= 128): - ret += "%%%02X" % ord(c) + if c in invalid or (c <= 32) or (c >= 128): + ret += "%%%02X" % c else: - ret += c + ret += chr(c) return ret class urlerror(ValueError): @@ -167,11 +168,16 @@ def scripturl(req): raise Exception("Malformed local part when reconstructing URL") return siteurl(req) + req.uriname[1:] -def requrl(req): +def requrl(req, qs=True): s = siteurl(req) if req.uri[0] != '/': raise Exception("Malformed local part when reconstructing URL") - return siteurl(req) + req.uri[1:] + pf = req.uri[1:] + if not qs: + p = pf.find('?') + if not p < 0: + pf = pf[:p] + return siteurl(req) + pf def parstring(pars={}, **augment): buf = "" @@ -191,6 +197,40 @@ def parstring(pars={}, **augment): def parurl(url, pars={}, **augment): qs = parstring(pars, **augment) if qs != "": - return url + "?" + qs + return url + ("&" if "?" in url else "?") + qs else: return url + +# Wrap these, since binascii is a bit funky. :P +def enhex(bs): + return base64.b16encode(bs).decode("us-ascii") +def unhex(es): + if not isinstance(es, collections.ByteString): + try: + es = es.encode("us-ascii") + except UnicodeError: + raise binascii.Error("non-ascii character in hex-string") + return base64.b16decode(es) +def enb32(bs): + return base64.b32encode(bs).decode("us-ascii") +def unb32(es): + if not isinstance(es, collections.ByteString): + try: + es = es.encode("us-ascii") + except UnicodeError: + raise binascii.Error("non-ascii character in base32-string") + 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).decode("us-ascii") +def unb64(es): + if not isinstance(es, collections.ByteString): + try: + es = es.encode("us-ascii") + except UnicodeError: + raise binascii.Error("non-ascii character in base64-string") + if (len(es) % 4) != 0: + es += b"=" * (4 - (len(es) % 4)) + return base64.b64decode(es)