python: Added a util module and moved serveloop thence.
[ashd.git] / python / ashd / proto.py
CommitLineData
c270f222
FT
1import os, socket
2import htlib
3
4class protoerr(Exception):
5 pass
6
7class req(object):
8 def __init__(self, method, url, ver, rest, headers, fd):
9 self.method = method
10 self.url = url
11 self.ver = ver
12 self.rest = rest
13 self.headers = headers
14 self.sk = socket.fromfd(fd, socket.AF_UNIX, socket.SOCK_STREAM).makefile('r+')
15 os.close(fd)
16
17 def close(self):
18 self.sk.close()
19
20 def __getitem__(self, header):
21 header = header.lower()
22 for key, val in self.headers:
23 if key.lower() == header:
24 return val
25 raise KeyError(header)
26
27 def __contains__(self, header):
28 header = header.lower()
29 for key, val in self.headers:
30 if key.lower() == header:
31 return True
32 return False
33
34 def dup(self):
35 return req(self.method, self.url, self.ver, self.rest, self.headers, os.dup(self.sk.fileno()))
36
37 def match(self, match):
38 if self.rest[:len(match)] == match:
39 self.rest = self.rest[len(match):]
40 return True
41 return False
42
43 def __str__(self):
44 return "\"%s %s %s\"" % (self.method, self.url, self.ver)
45
46 def __enter__(self):
47 return self
48
49 def __exit__(self, *excinfo):
50 self.sk.close()
51 return False
52
53def recvreq(sock = 0):
54 data, fd = htlib.recvfd(sock)
55 if fd is None:
56 return None
57 try:
c270f222
FT
58 parts = data.split('\0')[:-1]
59 if len(parts) < 5:
60 raise protoerr("Truncated request")
61 method, url, ver, rest = parts[:4]
62 headers = []
63 i = 4
64 while True:
65 if parts[i] == "": break
66 if len(parts) - i < 3:
67 raise protoerr("Truncated request")
68 headers.append((parts[i], parts[i + 1]))
69 i += 2
70 return req(method, url, ver, rest, headers, os.dup(fd))
71 finally:
72 os.close(fd)
73
74def sendreq(sock, req):
75 data = ""
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:
81 data += key + '\0'
82 data += val + '\0'
83 data += '\0'
84 htlib.sendfd(sock, req.sk.fileno(), data)