Rev 4514: lifeless said: try harder :) in file:///home/vila/src/bzr/bugs/383920-pycurl-hangs/
Vincent Ladeuil
v.ladeuil+lp at free.fr
Wed Jul 8 09:51:19 BST 2009
At file:///home/vila/src/bzr/bugs/383920-pycurl-hangs/
------------------------------------------------------------
revno: 4514
revision-id: v.ladeuil+lp at free.fr-20090708085119-rmfk350eoiwxtpqh
parent: v.ladeuil+lp at free.fr-20090707082457-otq7zht7lgkpnpbr
committer: Vincent Ladeuil <v.ladeuil+lp at free.fr>
branch nick: 383920-pycurl-hangs
timestamp: Wed 2009-07-08 10:51:19 +0200
message:
lifeless said: try harder :)
* bzrlib/tests/http_server.py:
(TestingHTTPRequestHandler.send_error): Deleted, not needed
anymre.
(TestingThreadingHTTPServer.process_request_thread): shutdown()
the socket explicitely.
* NEWS:
Describe the new fix.
-------------- next part --------------
=== modified file 'NEWS'
--- a/NEWS 2009-07-07 08:24:57 +0000
+++ b/NEWS 2009-07-08 08:51:19 +0000
@@ -75,14 +75,13 @@
of a remote repository.
(Jelmer Vernooij, #332194)
-* Fix bogus ``send_error`` in python's BaseHTTPServer by inserting the missing
- 'Content-Length header. https pycurl clients can hang otherwise.
- (Vincent Ladeuil, #383920).
-
* Force deletion of readonly files during merge, update and other tree
transforms.
(Craig Hewetson, Martin Pool, #218206)
+* Force socket shutdown in threaded http test servers to avoid client hangs
+ (pycurl). (Vincent Ladeuil, #383920).
+
* The ``log+`` decorator, useful in debugging or profiling, could cause
"AttributeError: 'list' object has no attribute 'next'". This is now
fixed. The log decorator no longer shows the elapsed time or transfer
=== modified file 'bzrlib/tests/http_server.py'
--- a/bzrlib/tests/http_server.py 2009-07-07 08:24:57 +0000
+++ b/bzrlib/tests/http_server.py 2009-07-08 08:51:19 +0000
@@ -145,35 +145,6 @@
return SimpleHTTPServer.SimpleHTTPRequestHandler.send_head(self)
- def send_error(self, code, message=None):
- """Send and log an error reply.
-
- Replace the bogus BaseHTTPServer.py with one that add the
- Content-Length header to address strict http clients.
- """
-
- try:
- short, long = self.responses[code]
- except KeyError:
- short, long = '???', '???'
- if message is None:
- message = short
- explain = long
- self.log_error("code %d, message %s", code, message)
- # using _quote_html to prevent Cross Site Scripting attacks (see bug
- # #1100201)
- content = (self.error_message_format %
- {'code': code,
- 'message': BaseHTTPServer._quote_html(message),
- 'explain': explain})
- self.send_response(code, message)
- self.send_header("Content-Length", "%d" % len(content))
- self.send_header("Content-Type", self.error_content_type)
- self.send_header('Connection', 'close')
- self.end_headers()
- if self.command != 'HEAD' and code >= 200 and code not in (204, 304):
- self.wfile.write(content)
-
def send_range_content(self, file, start, length):
file.seek(start)
self.wfile.write(file.read(length))
@@ -412,6 +383,23 @@
# lying around.
self.daemon_threads = True
+ def process_request_thread(self, request, client_address):
+ SocketServer.ThreadingTCPServer.process_request_thread(
+ self, request, client_address)
+ # Under some circumstances (as in bug #383920), we need to force the
+ # shutdown as python delays it until gc occur otherwise and the client
+ # may hang.
+ try:
+ # The request process has been completed, the thread is about to
+ # die, let's shutdown the socket if we can.
+ request.shutdown(socket.SHUT_RDWR)
+ except (socket.error, select.error), e:
+ if e[0] in (errno.EBADF, errno.ENOTCONN):
+ # Right, the socket is already down
+ pass
+ else:
+ raise
+
class HttpServer(transport.Server):
"""A test server for http transports.
=== modified file 'bzrlib/tests/test_read_bundle.py'
--- a/bzrlib/tests/test_read_bundle.py 2009-07-07 08:24:57 +0000
+++ b/bzrlib/tests/test_read_bundle.py 2009-07-08 08:51:19 +0000
@@ -90,7 +90,7 @@
# read_mergeable_from_url will invoke get_transport which may *not*
# respect self._transport (i.e. returns a transport that is different
# from the one we want to test, so we must inject a correct transport
- # into possible_transports first.
+ # into possible_transports first).
self.possible_transports = [self.get_transport(self.bundle_name)]
self._captureVar('BZR_NO_SMART_VFS', None)
wt = self.create_test_bundle()
More information about the bazaar-commits
mailing list