Fixed HTTP redirect tests on Python 3
[zeroinstall/solver.git] / tests / server.py
blob4af55c753c977bc4e373a1230c01eb8182a520e0
1 #!/usr/bin/env python
3 from __future__ import print_function
5 import os, sys
6 import traceback
8 if sys.version_info[0] > 2:
9 from urllib import parse as urlparse # Python 3
10 from http import server
11 import pickle
12 else:
13 import urlparse
14 import BaseHTTPServer as server
15 import cPickle as pickle
17 next_step = None
19 class Give404:
20 def __init__(self, path):
21 self.path = path
23 def __str__(self):
24 return self.path
26 def __repr__(self):
27 return "404 on " + self.path
29 class MyHandler(server.BaseHTTPRequestHandler):
30 def do_GET(self):
31 parsed = urlparse.urlparse(self.path)
33 print(parsed)
34 if parsed.path.startswith('/redirect/'):
35 self.send_response(302)
36 self.wfile.write(('Location: /' + parsed.path[1:].split('/', 1)[1]).encode('utf-8'))
37 return
39 leaf = os.path.basename(parsed.path)
41 acceptable = dict([(str(x), x) for x in next_step])
43 resp = acceptable.get(parsed.path, None) or \
44 acceptable.get(leaf, None) or \
45 acceptable.get('*', None)
47 # (don't use a symlink as they don't work on Windows)
48 if leaf == 'latest.xml':
49 leaf = 'Hello.xml'
51 if not resp:
52 self.send_error(404, "Expected %s; got %s" % (next_step, parsed.path))
53 elif parsed.path.startswith('/key-info/'):
54 self.send_response(200)
55 self.end_headers()
56 self.wfile.write(b'<key-lookup><item vote="good">Approved for testing</item></key-lookup>')
57 self.wfile.close()
58 elif os.path.exists(leaf) and not isinstance(resp, Give404):
59 self.send_response(200)
60 self.end_headers()
61 with open(leaf, 'rb') as stream:
62 self.wfile.write(stream.read())
63 self.wfile.close()
64 else:
65 self.send_error(404, "Missing: %s" % leaf)
67 def handle_requests(*script):
68 from subprocess import Popen, PIPE
70 # Pass the script on the command line as a pickle.
71 child = Popen(
72 [sys.executable, __file__, repr(pickle.dumps(script)) ],
73 stdout=PIPE, universal_newlines=True)
75 # Make sure the server is actually running before we try to
76 # interact with it.
77 l = child.stdout.readline()
78 assert l == 'Waiting for request\n', l
79 return child
81 def main():
82 # Grab the script that was passed on the command line from the parent
83 script = pickle.loads(eval(sys.argv[1]))
84 server_address = ('localhost', 8000)
85 httpd = server.HTTPServer(server_address, MyHandler)
86 try:
87 sys.stderr = sys.stdout
88 #sys.stdout = sys.stderr
89 print("Waiting for request")
90 sys.stdout.flush() # Make sure the "Waiting..." message is seen by the parent
91 global next_step
92 for next_step in script:
93 if type(next_step) != tuple: next_step = (next_step,)
94 for x in next_step:
95 httpd.handle_request()
96 print("Done")
97 os._exit(0)
98 except:
99 traceback.print_exc()
100 os._exit(1)
102 if __name__ == '__main__':
103 # This is the child process. We have to import ourself and
104 # run the main routine there, or the pickled Give404 instances
105 # passed from the parent won't be recognized as having the
106 # same class (server.Give404).
107 import server
108 server.main()