Catch cyclic dependency graphs and give a nice error instead of running out of stack
[zeroinstall/zeroinstall-mseaborn.git] / tests / server.py
blob21f1883b719d31afe2347e44dceb520780d5fe6c
1 #!/usr/bin/env python
2 import os, sys
3 import BaseHTTPServer
4 import traceback
6 next_step = None
8 class Give404:
9 def __init__(self, path):
10 self.path = path
12 def __str__(self):
13 return self.path
15 def __repr__(self):
16 return "404 on " + self.path
18 class MyHandler(BaseHTTPServer.BaseHTTPRequestHandler):
19 def do_GET(self):
20 leaf = os.path.basename(self.path)
22 acceptable = dict([(str(x), x) for x in next_step])
24 resp = acceptable.get(self.path, None) or \
25 acceptable.get(leaf, None) or \
26 acceptable.get('*', None)
28 if not resp:
29 self.send_error(404, "Expected %s; got %s" % (next_step, self.path))
31 if os.path.exists(leaf) and not isinstance(resp, Give404):
32 self.send_response(200)
33 self.end_headers()
34 self.wfile.write(file(leaf).read())
35 self.wfile.close()
36 else:
37 self.send_error(404, "Missing: %s" % leaf)
39 def handle_requests(*script):
40 server_address = ('localhost', 8000)
41 httpd = BaseHTTPServer.HTTPServer(server_address, MyHandler)
42 child = os.fork()
43 if child:
44 return child
45 # We are the child
46 try:
47 sys.stderr = sys.stdout
48 print "Waiting for request"
49 global next_step
50 for next_step in script:
51 if type(next_step) != tuple: next_step = (next_step,)
52 for x in next_step:
53 httpd.handle_request()
54 print "Done"
55 os._exit(0)
56 except:
57 traceback.print_exc()
58 os._exit(1)