chiark / gitweb /
1a9049b845131db9c6148373e6f121853fd60e9a
[hippotat.git] / 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.