4 class protoerr(Exception):
8 def __init__(self, method, url, ver, rest, headers, fd):
13 self.headers = headers
14 self.sk = socket.fromfd(fd, socket.AF_UNIX, socket.SOCK_STREAM).makefile('r+')
20 def __getitem__(self, header):
21 header = header.lower()
22 for key, val in self.headers:
23 if key.lower() == header:
25 raise KeyError(header)
27 def __contains__(self, header):
28 header = header.lower()
29 for key, val in self.headers:
30 if key.lower() == header:
35 return req(self.method, self.url, self.ver, self.rest, self.headers, os.dup(self.sk.fileno()))
37 def match(self, match):
38 if self.rest[:len(match)] == match:
39 self.rest = self.rest[len(match):]
44 return "\"%s %s %s\"" % (self.method, self.url, self.ver)
49 def __exit__(self, *excinfo):
53 def recvreq(sock = 0):
54 data, fd = htlib.recvfd(sock)
58 parts = data.split('\0')[:-1]
60 raise protoerr("Truncated request")
61 method, url, ver, rest = parts[:4]
65 if parts[i] == "": break
66 if len(parts) - i < 3:
67 raise protoerr("Truncated request")
68 headers.append((parts[i], parts[i + 1]))
70 return req(method, url, ver, rest, headers, os.dup(fd))
74 def sendreq(sock, req):
76 data += req.method + '\0'
77 data += req.url + '\0'
78 data += req.ver + '\0'
79 data += req.rest + '\0'
80 for key, val in req.headers:
84 htlib.sendfd(sock, req.sk.fileno(), data)
86 def serveloop(handler, sock = 0):