57
57
expect_body=expect_response_body),
60
for protocol_version in [3, 2, 1]:
60
for protocol_version in [3, 2]:
61
61
encoder, response_handler = self._construct_protocol(
63
63
self._call(encoder, method, args, body=body,
66
66
response_tuple = response_handler.read_response_tuple(
67
67
expect_body=expect_response_body)
68
except errors.UnexpectedProtocolVersionMarker, e:
68
except errors.UnexpectedProtocolVersionMarker, err:
69
69
# TODO: We could recover from this without disconnecting if
70
70
# we recognise the protocol version.
71
71
self._medium.disconnect()
74
74
self._protocol_version = protocol_version
75
75
return response_tuple, response_handler
76
raise errors.SmartProtocolError(
77
'Unknown server protocol version: %r' % (e.marker,))
77
# As a last resort, try protocol version 1. Because version 1
78
# responses don't have a protocol version marker it is hard to
79
# distinguish valid v1 error response from random garbage, so we
80
# send a 'hello' request, which does have a predictable response.
81
# Eventually, we should just drop compatibility with servers that
82
# only support version 1.
83
encoder, response_handler = self._construct_protocol(1)
84
self._call(encoder, 'hello', ())
86
response_tuple = response_handler.read_response_tuple(
88
except errors.ConnectionReset, err:
89
# Either an interrupted connection, or the server doesn't even
90
# speak version 1. At this point we've already tried a couple
91
# of requests in other protocol versions without seeing this
92
# error, so most likely it is just that the server is not a
94
raise errors.SmartProtocolError(
95
'Server is not a bzr server, or connection interrupted.')
96
# The result must be '1'. (v2 servers can return '2' for hello
97
# requests, but we've already established that the server doesn't
98
# accept v2 requests.)
99
if response_tuple != ('1',):
100
raise errors.SmartProtocolError(
101
'Server is not a bzr server: unexpected response %r'
103
# Ok, apparently this is a version one server. Issue the original
105
encoder, response_handler = self._construct_protocol(1)
106
self._call(encoder, method, args, body=body,
107
readv_body=readv_body)
108
response_tuple = response_handler.read_response_tuple(
109
expect_body=expect_response_body)
110
self._protocol_version = 1
111
return response_tuple, response_handler
79
113
def _construct_protocol(self, version):
80
114
request = self._medium.get_request()