From: Fredrik Tolf Date: Sun, 6 Nov 2011 19:56:52 +0000 (+0100) Subject: Merge branch 'master' of git.dolda2000.com:/srv/git/r/wrw X-Git-Url: http://dolda2000.com/gitweb/?a=commitdiff_plain;h=a4811d704ac8b4d97ae9af3841823ad2b56c4380;hp=397fd288ed6d5b8f96c414778df96acb35514f4d;p=wrw.git Merge branch 'master' of git.dolda2000.com:/srv/git/r/wrw --- diff --git a/wrw/proto.py b/wrw/proto.py index 62d1769..6b43396 100644 --- a/wrw/proto.py +++ b/wrw/proto.py @@ -39,6 +39,56 @@ def urlq(url): ret += c return ret +class urlerror(ValueError): + pass + +def parseurl(url): + p = url.find("://") + if p < 0: + raise urlerror("Protocol not found in absolute URL `%s'" % url) + proto = url[:p] + l = url.find("/", p + 3) + if l < 0: + raise urlerror("Local part not found in absolute URL `%s'" % url) + host = url[p + 3:l] + local = url[l:] + q = local.find("?") + if q < 0: + query = "" + else: + query = local[q + 1:] + local = local[:q] + return proto, host, local, query + +def consurl(proto, host, local, query = ""): + if len(local) < 1 and local[0] != '/': + raise urlerror("Local part of URL must begin with a slash") + ret = "%s://%s%s" % (proto, host, local) + if len(query) > 0: + ret += "?" + query + return ret + +def appendurl(url, other): + if "://" in other: + return other + proto, host, local, query = parseurl(url) + if len(other) > 0 and other[0] == '/': + return consurl(proto, host, other) + else: + p = local.rfind('/') + return consurl(proto, host, local[:p + 1] + other) + +def requrl(req): + host = req.ihead.get("Host", None) + if host is None: + raise Exception("Could not reconstruct URL because no Host header was sent") + proto = "http" + if req.https: + proto = "https" + if req.uri[0] != '/': + raise Exception("Malformed local part when reconstructing URL") + return "%s://%s%s" % (proto, host, req.uri) + def parstring(pars = {}, **augment): buf = "" for key in pars: diff --git a/wrw/resp.py b/wrw/resp.py index 2e26ccf..8216d23 100644 --- a/wrw/resp.py +++ b/wrw/resp.py @@ -70,3 +70,14 @@ class httperror(usererror): class notfound(httperror): def __init__(self): return super(notfound, self).__init__(404) + +class redirect(dispatch.restart): + def __init__(self, url, status = 303): + super(redirect, self).__init__() + self.url = url + self.status = status + + def handle(self, req): + req.status(self.status, "Redirect") + req.ohead["Location"] = proto.appendurl(proto.requrl(req), self.url) + return []