271
278
:return: A lock object, which should be passed to Transport.unlock()
273
280
raise TransportNotPossible('http does not support lock_write()')
283
#---------------- test server facilities ----------------
284
import BaseHTTPServer, SimpleHTTPServer, socket, time
288
class WebserverNotAvailable(Exception):
292
class BadWebserverPath(ValueError):
294
return 'path %s is not in %s' % self.args
297
class TestingHTTPRequestHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):
299
def log_message(self, format, *args):
300
self.server.test_case.log("webserver - %s - - [%s] %s",
301
self.address_string(),
302
self.log_date_time_string(),
305
def handle_one_request(self):
306
"""Handle a single HTTP request.
308
You normally don't need to override this method; see the class
309
__doc__ string for information on how to handle specific HTTP
310
commands such as GET and POST.
313
for i in xrange(1,11): # Don't try more than 10 times
315
self.raw_requestline = self.rfile.readline()
316
except socket.error, e:
317
if e.args[0] in (errno.EAGAIN, errno.EWOULDBLOCK):
318
# omitted for now because some tests look at the log of
319
# the server and expect to see no errors. see recent
320
# email thread. -- mbp 20051021.
321
## self.log_message('EAGAIN (%d) while reading from raw_requestline' % i)
327
if not self.raw_requestline:
328
self.close_connection = 1
330
if not self.parse_request(): # An error code has been sent, just exit
332
mname = 'do_' + self.command
333
if not hasattr(self, mname):
334
self.send_error(501, "Unsupported method (%r)" % self.command)
336
method = getattr(self, mname)
339
class TestingHTTPServer(BaseHTTPServer.HTTPServer):
340
def __init__(self, server_address, RequestHandlerClass, test_case):
341
BaseHTTPServer.HTTPServer.__init__(self, server_address,
343
self.test_case = test_case
346
class HttpServer(Server):
347
"""A test server for http transports."""
349
_HTTP_PORTS = range(13000, 0x8000)
351
def _http_start(self):
353
for port in self._HTTP_PORTS:
355
httpd = TestingHTTPServer(('localhost', port),
356
TestingHTTPRequestHandler,
358
except socket.error, e:
359
if e.args[0] == errno.EADDRINUSE:
361
print >>sys.stderr, "Cannot run webserver :-("
367
raise WebserverNotAvailable("Cannot run webserver :-( "
368
"no free ports in range %s..%s" %
369
(_HTTP_PORTS[0], _HTTP_PORTS[-1]))
371
self._http_base_url = 'http://localhost:%s/' % port
372
self._http_starting.release()
373
httpd.socket.settimeout(0.1)
375
while self._http_running:
377
httpd.handle_request()
378
except socket.timeout:
381
def _get_remote_url(self, path):
382
path_parts = path.split(os.path.sep)
383
if os.path.isabs(path):
384
if path_parts[:len(self._local_path_parts)] != \
385
self._local_path_parts:
386
raise BadWebserverPath(path, self.test_dir)
387
remote_path = '/'.join(path_parts[len(self._local_path_parts):])
389
remote_path = '/'.join(path_parts)
391
self._http_starting.acquire()
392
self._http_starting.release()
393
return self._http_base_url + remote_path
395
def log(self, *args, **kwargs):
396
"""Capture Server log output."""
397
self.logs.append(args[3])
400
"""See bzrlib.transport.Server.setUp."""
401
self._home_dir = os.getcwdu()
402
self._local_path_parts = self._home_dir.split(os.path.sep)
403
self._http_starting = threading.Lock()
404
self._http_starting.acquire()
405
self._http_running = True
406
self._http_base_url = None
407
self._http_thread = threading.Thread(target=self._http_start)
408
self._http_thread.setDaemon(True)
409
self._http_thread.start()
410
self._http_proxy = os.environ.get("http_proxy")
411
if self._http_proxy is not None:
412
del os.environ["http_proxy"]
416
"""See bzrlib.transport.Server.tearDown."""
417
self._http_running = False
418
self._http_thread.join()
419
if self._http_proxy is not None:
421
os.environ["http_proxy"] = self._http_proxy
424
"""See bzrlib.transport.Server.get_url."""
425
return self._get_remote_url(self._home_dir)
427
def get_bogus_url(self):
428
"""See bzrlib.transport.Server.get_bogus_url."""
429
return 'http://jasldkjsalkdjalksjdkljasd'
432
def get_test_permutations():
433
"""Return the permutations to be used in testing."""
434
warn("There are no HTTPS transport provider tests yet.")
435
return [(HttpTransport, HttpServer),