import binascii, hashlib, threading, time
- import resp
-from . import resp, proto
++import resp, proto
class unauthorized(resp.httperror):
def __init__(self, challenge, message=None, detail=None):
- super().__init__(401, message, detail)
+ super(unauthorized, self).__init__(401, message, detail)
if isinstance(challenge, str):
challenge = [challenge]
self.challenge = challenge
def handle(self, req):
for challenge in self.challenge:
req.ohead.add("WWW-Authenticate", challenge)
- return super().handle(req)
+ return super(unauthorized, self).handle(req)
class forbidden(resp.httperror):
def __init__(self, message=None, detail=None):
- super().__init__(403, message, detail)
+ super(forbidden, self).__init__(403, message, detail)
def parsemech(req):
h = req.ihead.get("Authorization", None)
if mech != "basic":
return None, None
try:
- raw = binascii.a2b_base64(data)
+ raw = proto.unb64(data)
except binascii.Error:
return None, None
- try:
- raw = raw.decode("utf-8")
- except UnicodeError:
- raw = raw.decode("latin1")
p = raw.find(":")
if p < 0:
return None, None
def _obscure(self, nm, pw):
dig = hashlib.sha256()
- dig.update(self.realm.encode("utf-8"))
- dig.update(nm.encode("utf-8"))
- dig.update(pw.encode("utf-8"))
+ dig.update(self.realm)
+ dig.update(nm)
+ dig.update(pw)
return dig.digest()
def check(self, req):
with lock:
try:
ret = self.auth(req, nm, pw)
- except forbidden as exc:
+ except forbidden, exc:
with self._lock:
self._cache[nm, pwh] = (lock, now, "f", exc)
raise
-import urllib.parse
-from . import proto
+import urlparse
+import proto
__all__ = ["formdata"]
def formparse(req):
buf = {}
- buf.update(urllib.parse.parse_qsl(req.query))
+ 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(urllib.parse.parse_qsl(rbody.decode("latin1")))
+ buf.update(urlparse.parse_qsl(rbody))
return buf
class badmultipart(Exception):
class formpart(object):
def __init__(self, form):
self.form = form
- self.buf = b""
+ self.buf = ""
self.eof = False
self.head = {}
def fillbuf(self, sz):
req = self.form.req
- mboundary = b"\r\n--" + self.form.boundary + b"\r\n"
- lboundary = b"\r\n--" + self.form.boundary + b"--\r\n"
+ mboundary = "\r\n--" + self.form.boundary + "\r\n"
+ lboundary = "\r\n--" + self.form.boundary + "--\r\n"
while not self.eof:
p = self.form.buf.find(mboundary)
if p >= 0:
break
while len(self.form.buf) <= len(lboundary):
ret = req.input.read(8192)
- if ret == b"":
+ if ret == "":
raise badmultipart("Missing last multipart boundary")
self.form.buf += ret
self.buf = self.buf[limit:]
else:
ret = self.buf
- self.buf = b""
+ self.buf = ""
return ret
def readline(self, limit=-1):
last = 0
while True:
- p = self.buf.find(b'\n', last)
+ p = self.buf.find('\n', last)
if p < 0:
if self.eof:
ret = self.buf
- self.buf = b""
+ self.buf = ""
return ret
last = len(self.buf)
self.fillbuf(last + 128)
return ret
def close(self):
- self.fillbuf(-1)
+ while True:
- if self.read(8192) == b"":
++ if self.read(8192) == "":
+ break
def __enter__(self):
return self
self.close()
return False
- def parsehead(self, charset):
+ def parsehead(self):
def headline():
ln = self.readline(256)
- if ln[-1] != ord(b'\n'):
+ if ln[-1] != '\n':
raise badmultipart("Too long header line in part")
- try:
- return ln.decode(charset).rstrip()
- except UnicodeError:
- raise badmultipart("Form part header is not in assumed charset")
+ return ln.rstrip()
ln = headline()
while True:
raise badmultipart("Form part uses unexpected transfer encoding: %r" % encoding)
class multipart(object):
- def __init__(self, req, charset):
+ def __init__(self, req):
val, par = proto.pmimehead(req.ihead.get("Content-Type", ""))
if req.method != "POST" or val != "multipart/form-data":
raise badmultipart("Request is not a multipart form")
if "boundary" not in par:
raise badmultipart("Multipart form lacks boundary")
- try:
- self.boundary = par["boundary"].encode("us-ascii")
- except UnicodeError:
- raise badmultipart("Multipart boundary must be ASCII string")
+ self.boundary = par["boundary"]
self.req = req
- self.buf = b"\r\n"
+ self.buf = "\r\n"
self.eof = False
- self.headcs = charset
self.lastpart = formpart(self)
self.lastpart.close()
def __iter__(self):
return self
- def __next__(self):
+ def next(self):
if not self.lastpart.eof:
raise RuntimeError("All form parts must be read entirely")
if self.eof:
raise StopIteration()
self.lastpart = formpart(self)
- self.lastpart.parsehead(self.headcs)
+ 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
- import time, calendar
+ import time, calendar, collections, binascii, base64
statusinfo = {
400: ("Bad Request", "Invalid HTTP request."),
</body>
</html>
""" % (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, str):
+ if isinstance(url, unicode):
url = url.encode("utf-8")
ret = ""
- invalid = "&=#?/\"'"
- invalid = b";&=#?/\"'"
++ invalid = ";&=#?/\"'"
for c in url:
- if c in invalid or (c <= 32) or (c >= 128):
- ret += "%%%02X" % c
+ if c in invalid or (ord(c) <= 32) or (ord(c) >= 128):
+ ret += "%%%02X" % ord(c)
else:
- ret += chr(c)
+ ret += c
return ret
class urlerror(ValueError):
return url + "?" + qs
else:
return url
- return base64.b16encode(bs).decode("us-ascii")
+
+ # Wrap these, since binascii is a bit funky. :P
+ def enhex(bs):
- 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.b16encode(bs)
+ def unhex(es):
- return base64.b32encode(bs).decode("us-ascii")
+ return base64.b16decode(es)
+ def enb32(bs):
- if not isinstance(es, collections.ByteString):
- try:
- es = es.encode("us-ascii")
- except UnicodeError:
- raise binascii.Error("non-ascii character in base32-string")
++ return base64.b32encode(bs)
+ def unb32(es):
- return base64.b64encode(bs).decode("us-ascii")
+ 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):
- if not isinstance(es, collections.ByteString):
- try:
- es = es.encode("us-ascii")
- except UnicodeError:
- raise binascii.Error("non-ascii character in base64-string")
++ return base64.b64encode(bs)
+ def unb64(es):
+ if (len(es) % 4) != 0:
+ es += b"=" * (4 - (len(es) % 4))
+ return base64.b64decode(es)
import threading, time, pickle, random, os
++<<<<<<< HEAD
+import cookie, env
++=======
+ from . import cookie, env, proto
++>>>>>>> master
__all__ = ["db", "get"]
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())
def clean(self):
now = int(time.time())
with self.lock:
- clist = list(self.live.keys())
+ clist = self.live.keys()
for sessid in clist:
with self.lock:
try:
data = self.backdb[sessid]
try:
return pickle.loads(data)
- except:
+ except Exception, e:
raise KeyError()
def freeze(self, sess):
import inspect, math
-from . import req, dispatch, session, form, resp, proto
+import req, dispatch, session, form, resp, proto
def wsgiwrap(callable):
def wrapper(env, startreq):
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:
for arg in list(args):
if arg not in spec.args:
del args[arg]
- for i in range(len(spec.args) - (len(spec.defaults) if spec.defaults else 0)):
+ for i in xrange(len(spec.args) - (len(spec.defaults) if spec.defaults else 0)):
if spec.args[i] not in args:
raise resp.httperror(400, "Missing parameter", ("The query parameter `", resp.h.code(spec.args[i]), "' is required but not supplied."))
return callable(**args)
self.bk = real
self.bki = iter(real)
self._next = None
- self.__next__()
+ self.next()
def __iter__(self):
return self
- def __next__(self):
+ def next(self):
if self._next is self.end:
raise StopIteration()
ret = self._next
wrapper.__wrapped__ = callable
return wrapper
-def stringwrap(charset):
- def dec(callable):
- @pregen
- def wrapper(*args, **kwargs):
- for string in callable(*args, **kwargs):
- yield string.encode(charset)
- wrapper.__wrapped__ = callable
- return wrapper
- return dec
-
class sessiondata(object):
@classmethod
def get(cls, req, create=True):
class autodirty(sessiondata):
@classmethod
def get(cls, req):
- ret = super().get(req)
+ ret = super(autodirty, cls).get(req)
if "_is_dirty" not in ret.__dict__:
ret.__dict__["_is_dirty"] = False
return ret
return self._is_dirty
def __setattr__(self, name, value):
- super().__setattr__(name, value)
+ super(autodirty, self).__setattr__(name, value)
if "_is_dirty" in self.__dict__:
self.__dict__["_is_dirty"] = True
def __delattr__(self, name):
- super().__delattr__(name, value)
+ super(autodirty, self).__delattr__(name, value)
if "_is_dirty" in self.__dict__:
self.__dict__["_is_dirty"] = True
class manudirty(object):
def __init__(self, *args, **kwargs):
- super().__init__(*args, **kwargs)
+ super(manudirty, self).__init__(*args, **kwargs)
self.__dirty = False
def sessfrozen(self):
class specclass(type):
def __init__(self, name, bases, tdict):
- super().__init__(name, bases, tdict)
+ super(specclass, self).__init__(name, bases, tdict)
sslots = set()
dslots = set()
for cls in self.__mro__:
for i, slot in enumerate(self.__sslots_a__):
setattr(self, slot, specslot(slot, i, slot in dslots))
-class specdirty(sessiondata, metaclass=specclass):
+class specdirty(sessiondata):
+ __metaclass__ = specclass
__slots__ = ["session", "__sslots__", "_is_dirty"]
def __specinit__(self):
@staticmethod
def __new__(cls, req, sess):
- self = super().__new__(cls)
+ self = super(specdirty, cls).__new__(cls)
self.session = sess
self.__sslots__ = [specslot.unbound] * len(cls.__sslots_a__)
self.__specinit__()