Rev 4908: Minimal fix for 497274. in file:///home/vila/src/bzr/bugs/497274-http-405/

Vincent Ladeuil v.ladeuil+lp at free.fr
Fri Dec 18 14:26:12 GMT 2009


At file:///home/vila/src/bzr/bugs/497274-http-405/

------------------------------------------------------------
revno: 4908
revision-id: v.ladeuil+lp at free.fr-20091218142612-fe2ltuq0wu3o956e
parent: pqm at pqm.ubuntu.com-20091218090513-kzwkjw7rdf7bahqi
committer: Vincent Ladeuil <v.ladeuil+lp at free.fr>
branch nick: 497274-http-405
timestamp: Fri 2009-12-18 15:26:12 +0100
message:
  Minimal fix for 497274.
  
  * bzrlib/transport/http/response.py:
  (handle_response): Handle 405, may not be the cleanest solution
  but the tests pass.
  
  * bzrlib/transport/http/__init__.py:
  (SmartClientHTTPMedium.send_http_smart_request): EErk, untested
  code is broken code :-/
  
  * bzrlib/tests/test_http.py:
  (OnlyGETHEADRequestHandler.parse_request): A dedicated request
  handler emulating a restricted server.
  (TestGETHEADServer): Test the behaviour of the http clients
  against a server that can't reply to POST.
-------------- next part --------------
=== modified file 'bzrlib/tests/test_http.py'
--- a/bzrlib/tests/test_http.py	2009-12-04 15:22:23 +0000
+++ b/bzrlib/tests/test_http.py	2009-12-18 14:26:12 +0000
@@ -760,6 +760,47 @@
         self.assertRaises(errors.TransportError, t.get, 'foo/bar')
 
 
+class OnlyGETHEADRequestHandler(http_server.TestingHTTPRequestHandler):
+    """Only GET and HEAD requests are accepted."""
+
+    def parse_request(self):
+        """Handle a single HTTP request, by replying we cannot handle it"""
+        ok = http_server.TestingHTTPRequestHandler.parse_request(self)
+        if ok and self.command not in ('GET', 'HEAD'):
+            self.send_error(405)
+            ok = False
+        return ok
+
+
+class TestGETHEADServer(TestSpecificRequestHandler):
+    """Tests server aceepting only GET and HEAD requests"""
+
+    _req_handler_class = OnlyGETHEADRequestHandler
+
+    def test_http_has(self):
+        server = self.get_readonly_server()
+        t = self._transport(server.get_url())
+        self.assertEqual(False, t.has('foo/bar'))
+
+    def test_http_get(self):
+        server = self.get_readonly_server()
+        t = self._transport(server.get_url())
+        self.assertRaises(errors.NoSuchFile, t.get, 'foo/bar')
+
+    def test_http_post(self):
+        server = self.get_readonly_server()
+        t = self._transport(server.get_url())
+        code, file = t._post('')
+        self.assertEqual(405, code)
+
+    def test_http_smart_request(self):
+        server = self.get_readonly_server()
+        t = self._transport(server.get_url())
+        sm = http.SmartClientHTTPMedium(t)
+        self.assertRaises(errors.SmartProtocolError,
+                          sm.send_http_smart_request, '')
+
+
 class TestRecordingServer(tests.TestCase):
 
     def test_create(self):

=== modified file 'bzrlib/transport/http/__init__.py'
--- a/bzrlib/transport/http/__init__.py	2009-11-26 14:39:31 +0000
+++ b/bzrlib/transport/http/__init__.py	2009-12-18 14:26:12 +0000
@@ -614,7 +614,7 @@
             t = self._http_transport_ref()
             code, body_filelike = t._post(bytes)
             if code != 200:
-                raise InvalidHttpResponse(
+                raise errors.InvalidHttpResponse(
                     t._remote_path('.bzr/smart'),
                     'Expected 200 response code, got %r' % (code,))
         except (errors.InvalidHttpResponse, errors.ConnectionReset), e:

=== modified file 'bzrlib/transport/http/_urllib.py'
--- a/bzrlib/transport/http/_urllib.py	2009-12-03 17:11:57 +0000
+++ b/bzrlib/transport/http/_urllib.py	2009-12-18 14:26:12 +0000
@@ -133,8 +133,9 @@
         abspath = self._remote_path('.bzr/smart')
         # We include 403 in accepted_errors so that send_http_smart_request can
         # handle a 403.  Otherwise a 403 causes an unhandled TransportError.
+        # 405 is for servers that don't accept POST for the given url.
         response = self._perform(Request('POST', abspath, body_bytes,
-                                         accepted_errors=[200, 403]))
+                                         accepted_errors=[200, 403, 405]))
         code = response.code
         data = handle_response(abspath, code, response.info(), response)
         return code, data

=== modified file 'bzrlib/transport/http/response.py'
--- a/bzrlib/transport/http/response.py	2009-03-23 14:59:43 +0000
+++ b/bzrlib/transport/http/response.py	2009-12-18 14:26:12 +0000
@@ -323,6 +323,11 @@
                 raise errors.InvalidHttpResponse(url,
                     'Missing the Content-Range header in a 206 range response')
             rfile.set_range_from_header(content_range)
+    elif code == 405:
+        # The server refused to handle the request, the data presumably
+        # contains details about the error and not useful data, but we leave
+        # that to the higher levels.
+        return data
     else:
         raise errors.InvalidHttpResponse(url,
                                          'Unknown response code %s' % code)



More information about the bazaar-commits mailing list