wip
[hippotat] / server
1 #!/usr/bin/python2
2
3 from twisted.web.server import Site
4 from twisted.web.resource import Resource
5 from twisted.web.server import NOT_DONE_YET
6 from twisted.internet import reactor
7
8 import ConfigParser
9 import ipaddress
10
11 clients = { }
12
13 def ipaddress(input):
14 try:
15 r = ipaddress.IPv4Address(input)
16 except AddressValueError:
17 r = ipaddress.IPv6Address(input)
18 return r
19
20 def ipnetwork(input):
21 try:
22 r = ipaddress.IPv4Network(input)
23 except NetworkValueError:
24 r = ipaddress.IPv6Network(input)
25 return r
26
27 defcfg = u'''
28 [default]
29 max_batch_down: 65536
30 max_queue_time: 10
31 max_request_time: 54
32
33 [global]
34 max_batch_down: 262144
35 max_queue_time: 121
36 max_request_time: 121
37 '''
38
39 class Client():
40 def __init__(ip, cs):
41 # instance data members
42 self._ip = ip
43 self._cs = cs
44 self.pw = cfg.get(cs, 'password')
45 # plus:
46 # .cfg[<config-key>]
47 self.cfg = { }
48 for k in ('max_batch_down','max_queue_time','max_request_time'):
49 req = cfg.getint(cs, k)
50 limit = cfg.getint('global',k)
51 self.cfg[k] = min(req, limit)
52
53 def process_arriving_data(d):
54
55
56 def process_cfg():
57 global network
58 global ourself
59
60 network = ipnetwork(cfg.get('virtual','network'))
61 try:
62 ourself = cfg.get('virtual','server')
63 except ConfigParser.NoOptionError:
64 ourself = network.hosts().next()
65
66 for cs in cfg.sections():
67 if not (':' in cs or '.' in cs): continue
68 ci = ipaddress(cs)
69 if ci not in network:
70 raise ValueError('client %s not in network' % ci)
71 if ci in clients:
72 raise ValueError('multiple client cfg sections for %s' % ci)
73 clients[ci] = Client(ci, cs)
74
75 class FormPage(Resource):
76 def render_POST(self, request):
77 # find client, update config, etc.
78 ci = ipaddress(request.args['i'])
79 c = clients[ci]
80 pw = request.args['pw']
81 if pw != c.pw: raise ValueError('bad password')
82
83 # update config
84 for r, w in (('mbd', 'max_batch_down'),
85 ('mqt', 'max_queue_time'),
86 ('mrt', 'max_request_time')):
87 try: v = request.args[r]
88 except KeyError: continue
89 v = int(v)
90 c.cfg[w] = v
91
92 try: d = request.args['d']
93 except KeyError: d = ''
94
95 c.process_arriving_data(d)
96
97 reactor.