206
208
"""Append a '-proxied' suffix to file served"""
208
210
def translate_path(self, path):
209
return TestingHTTPRequestHandler.translate_path(self,
211
# We need to act as a proxy and accept absolute urls,
212
# which SimpleHTTPRequestHandler (grand parent) is not
213
# ready for. So we just drop the protocol://host:port
214
# part in front of the request-url (because we know we
215
# would not forward the request to *another* proxy).
217
# So we do what SimpleHTTPRequestHandler.translate_path
218
# do beginning with python 2.4.3: abandon query
219
# parameters, scheme, host port, etc (which ensure we
220
# provide the right behaviour on all python versions).
221
path = urlparse.urlparse(path)[2]
222
# And now, we can apply *our* trick to proxy files
223
self.path += '-proxied'
224
# An finally we leave our mother class do whatever it
225
# wants with the path
226
return TestingHTTPRequestHandler.translate_path(self, path)
229
class RedirectRequestHandler(TestingHTTPRequestHandler):
230
"""Redirect all request to the specified server"""
232
def parse_request(self):
233
"""Redirect a single HTTP request to another host"""
234
valid = TestingHTTPRequestHandler.parse_request(self)
236
tcs = self.server.test_case_server
237
code, target = tcs.is_redirected(self.path)
238
if code is not None and target is not None:
239
# Redirect as instructed
240
self.send_response(code)
241
self.send_header('Location', target)
243
return False # The job is done
245
# We leave the parent class serve the request
250
class HTTPServerRedirecting(HttpServer):
251
"""An HttpServer redirecting to another server """
253
def __init__(self, request_handler=RedirectRequestHandler):
254
HttpServer.__init__(self, request_handler)
255
# redirections is a list of tuples (source, target, code)
256
# - source is a regexp for the paths requested
257
# - target is a replacement for re.sub describing where
258
# the request will be redirected
259
# - code is the http error code associated to the
260
# redirection (301 permanent, 302 temporarry, etc
261
self.redirections = []
263
def redirect_to(self, host, port):
264
"""Redirect all requests to a specific host:port"""
265
self.redirections = [('(.*)',
266
r'http://%s:%s\1' % (host, port) ,
269
def is_redirected(self, path):
270
"""Is the path redirected by this server.
272
:param path: the requested relative path
274
:returns: a tuple (code, target) if a matching
275
redirection is found, (None, None) otherwise.
279
for (rsource, rtarget, rcode) in self.redirections:
280
target, match = re.subn(rsource, rtarget, path)
283
break # The first match wins
289
class TestCaseWithRedirectedWebserver(TestCaseWithTwoWebservers):
290
"""A support class providing redirections from one server to another.
292
We set up two webservers to allows various tests involving
294
The 'old' server is redirected to the 'new' server.
297
def create_transport_secondary_server(self):
298
"""Create the secondary server redirecting to the primary server"""
299
new = self.get_readonly_server()
300
redirecting = HTTPServerRedirecting()
301
redirecting.redirect_to(new.host, new.port)
305
super(TestCaseWithRedirectedWebserver, self).setUp()
306
# The redirections will point to the new server
307
self.new_server = self.get_readonly_server()
308
# The requests to the old server will be redirected
309
self.old_server = self.get_secondary_server()