872
860
return 1 # XXX !!!
875
class SmartClientRequestProtocolThree(ProtocolThreeDecoder, SmartClientRequestProtocolTwo):
877
response_marker = RESPONSE_VERSION_THREE
878
request_marker = REQUEST_VERSION_THREE
880
def __init__(self, client_medium_request):
881
ProtocolThreeDecoder.__init__(self, message.MessageHandler())
882
SmartClientRequestProtocolTwo.__init__(self, client_medium_request)
884
# XXX: the encoding of requests and decoding responses are somewhat
885
# conflated into one class here. The protocol is half-duplex, so combining
886
# them just makes the code needlessly ugly.
888
def _write_prefixed_bencode(self, structure):
889
bytes = bencode(structure)
890
self._request.accept_bytes(struct.pack('!L', len(bytes)))
891
self._request.accept_bytes(bytes)
893
def _write_headers(self, headers=None):
895
headers = {'Software version': bzrlib.__version__}
896
self._write_prefixed_bencode(headers)
898
def _write_args(self, args):
899
self._request.accept_bytes('s')
900
self._write_prefixed_bencode(args)
902
def _write_end(self):
903
self._request.accept_bytes('e')
905
def _write_prefixed_body(self, bytes):
906
self._request.accept_bytes('b')
907
self._request.accept_bytes(struct.pack('!L', len(bytes)))
908
self._request.accept_bytes(bytes)
910
def _wait_for_request_end(self):
912
next_read_size = self.next_read_size()
913
if next_read_size == 0:
914
# a complete request has been read.
916
bytes = self._request.read_bytes(next_read_size)
918
# end of file encountered reading from server
919
raise errors.ConnectionReset(
920
"please check connectivity and permissions",
921
"(and try -Dhpss if further diagnosis is required)")
922
self.accept_bytes(bytes)
924
# these methods from SmartClientRequestProtocolOne/Two
925
def call(self, *args, **kw):
926
# XXX: ideally, signature would be call(self, *args, headers=None), but
927
# python doesn't allow that. So, we fake it.
930
headers = kw.pop('headers')
932
raise TypeError('Unexpected keyword arguments: %r' % (kw,))
933
if 'hpss' in debug.debug_flags:
934
mutter('hpss call: %s', repr(args)[1:-1])
935
if getattr(self._request._medium, 'base', None) is not None:
936
mutter(' (to %s)', self._request._medium.base)
937
self._request_start_time = time.time()
938
self._write_protocol_version()
939
self._write_headers(headers)
940
self._write_args(args)
942
self._request.finished_writing()
944
def call_with_body_bytes(self, args, body, headers=None):
945
"""Make a remote call of args with body bytes 'body'.
947
After calling this, call read_response_tuple to find the result out.
949
if 'hpss' in debug.debug_flags:
950
mutter('hpss call w/body: %s (%r...)', repr(args)[1:-1], body[:20])
951
if getattr(self._request._medium, '_path', None) is not None:
952
mutter(' (to %s)', self._request._medium._path)
953
mutter(' %d bytes', len(body))
954
self._request_start_time = time.time()
955
self._write_protocol_version()
956
self._write_headers(headers)
957
self._write_args(args)
958
self._write_prefixed_body(body)
960
self._request.finished_writing()
962
def call_with_body_readv_array(self, args, body, headers=None):
963
"""Make a remote call with a readv array.
965
The body is encoded with one line per readv offset pair. The numbers in
966
each pair are separated by a comma, and no trailing \n is emitted.
968
if 'hpss' in debug.debug_flags:
969
mutter('hpss call w/readv: %s', repr(args)[1:-1])
970
if getattr(self._request._medium, '_path', None) is not None:
971
mutter(' (to %s)', self._request._medium._path)
972
self._request_start_time = time.time()
973
self._write_protocol_version()
974
self._write_headers(headers)
975
self._write_args(args)
976
readv_bytes = self._serialise_offsets(body)
977
self._write_prefixed_body(readv_bytes)
978
self._request.finished_writing()
979
if 'hpss' in debug.debug_flags:
980
mutter(' %d bytes in readv request', len(readv_bytes))
982
def cancel_read_body(self):
983
"""Ignored. Not relevant to version 3 of the protocol."""
985
def read_response_tuple(self, expect_body=False):
986
"""Read a response tuple from the wire.
988
The expect_body flag is ignored.
990
# XXX: warn if expect_body doesn't match the response?
991
self._wait_for_request_end()
992
if self.response_handler.error_args is not None:
993
_translate_error(self.response_handler.error_args)
994
return self.response_handler.error_args
995
return self.response_handler.args
997
def read_body_bytes(self, count=-1):
998
"""Read bytes from the body, decoding into a byte stream.
1000
We read all bytes at once to ensure we've checked the trailer for
1001
errors, and then feed the buffer back as read_body_bytes is called.
1003
# XXX: don't buffer the full request
1004
self._wait_for_request_end()
1005
return self.response_handler.prefixed_body.read(count)
1008
def _translate_error(error_tuple):
1009
# XXX: Hmm! Need state from the request. Hmm.
1010
error_name = error_tuple[0]
1011
error_args = error_tuple[1:]
1012
if error_name == 'LockContention':
1013
raise errors.LockContention('(remote lock)')
1014
elif error_name == 'LockFailed':
1015
raise errors.LockContention(*error_args[:2])
1018
raise errors.UnexpectedSmartServerResponse('Sucktitude: %r' %
1022
863
class _ProtocolThreeEncoder(object):
865
response_marker = request_marker = MESSAGE_VERSION_THREE
1024
867
def __init__(self, write_func):
1027
pr('writing:', repr(bytes))
1028
return write_func(bytes)
1029
self._write_func = wf
868
self._write_func = write_func
870
def _serialise_offsets(self, offsets):
871
"""Serialise a readv offset list."""
873
for start, length in offsets:
874
txt.append('%d,%d' % (start, length))
875
return '\n'.join(txt)
1031
877
def _write_protocol_version(self):
1032
878
self._write_func(MESSAGE_VERSION_THREE)