X-Git-Url: http://dolda2000.com/gitweb/?a=blobdiff_plain;f=wrw%2Fproto.py;h=881f4e477a84152257e7eb037b6571545c53208a;hb=001ec99e577b56479149fbe39de1d9291a134527;hp=62d1769fbc93d2b9d5ff65a1a2905e8cd17e0d63;hpb=5ef9e48843faf4a84af0ee8912ef72adb520efca;p=wrw.git diff --git a/wrw/proto.py b/wrw/proto.py index 62d1769..881f4e4 100644 --- a/wrw/proto.py +++ b/wrw/proto.py @@ -1,8 +1,12 @@ statusinfo = { - 400: ("Bad Request", "Your issued HTTP request is invalid."), - 403: ("Forbidden", "You are not authorized to view the requested resource."), + 400: ("Bad Request", "Invalid HTTP request."), + 401: ("Unauthorized", "Authentication must be provided for the requested resource."), + 403: ("Forbidden", "You are not authorized to request the requested resource."), 404: ("Not Found", "The requested resource was not found."), - 500: ("Server Error", "An internal error occurred.") + 405: ("Method Not Allowed", "The request method is not recognized or permitted by the requested resource."), + 500: ("Server Error", "An internal error occurred."), + 501: ("Not Implemented", "The requested functionality has not been implemented."), + 503: ("Service Unavailable", "Service is being denied at this time."), } def httpdate(ts): @@ -17,6 +21,55 @@ def phttpdate(dstr): tz = (((tz / 100) * 60) + (tz % 100)) * 60 return time.mktime(time.strptime(dstr, "%a, %d %b %Y %H:%M:%S")) - tz - time.altzone +def pmimehead(hstr): + def pws(p): + while p < len(hstr) and hstr[p].isspace(): + p += 1 + return p + def token(p, sep): + buf = "" + p = pws(p) + if p >= len(hstr): + return "", p + if hstr[p] == '"': + p += 1 + while p < len(hstr): + if hstr[p] == '\\': + p += 1 + if p < len(hstr): + buf += hstr[p] + p += 1 + else: + break + elif hstr[p] == '"': + p += 1 + break + else: + buf += hstr[p] + p += 1 + return buf, pws(p) + else: + while p < len(hstr): + if hstr[p] in sep: + break + buf += hstr[p] + p += 1 + return buf.strip(), pws(p) + p = 0 + val, p = token(p, ";") + pars = {} + while p < len(hstr): + if hstr[p] != ';': + break + p += 1 + k, p = token(p, "=") + if k == "" or hstr[p:p + 1] != '=': + break + p += 1 + v, p = token(p, ';') + pars[k.lower()] = v + return val, pars + def htmlq(html): ret = "" for c in html: @@ -39,6 +92,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: