84
84
"Conventional" is used in the sense described in
85
85
doc/developers/network-protocol.txt: a simple message with arguments and an
89
* args: expecting args
90
* body: expecting body (terminated by receiving a post-body status)
91
* error: expecting post-body error
92
* end: expecting end of message
96
89
def __init__(self, request_handler, responder):
97
90
MessageHandler.__init__(self)
98
91
self.request_handler = request_handler
99
92
self.responder = responder
100
self.expecting = 'args'
101
self._should_finish_body = False
102
self._response_sent = False
93
self.args_received = False
104
95
def protocol_error(self, exception):
105
if self.responder.response_sent:
106
# We can only send one response to a request, no matter how many
107
# errors happen while processing it.
109
96
self.responder.send_error(exception)
111
98
def byte_part_received(self, byte):
112
if self.expecting == 'body':
114
# Success. Nothing more to come except the end of message.
115
self.expecting = 'end'
117
# Error. Expect an error structure.
118
self.expecting = 'error'
120
raise errors.SmartProtocolError(
121
'Non-success status byte in request body: %r' % (byte,))
123
raise errors.SmartProtocolError(
124
'Unexpected message part: byte(%r)' % (byte,))
99
raise errors.SmartProtocolError(
100
'Unexpected message part: byte(%r)' % (byte,))
126
102
def structure_part_received(self, structure):
127
if self.expecting == 'args':
128
self._args_received(structure)
129
elif self.expecting == 'error':
130
self._error_received(structure)
103
if self.args_received:
132
104
raise errors.SmartProtocolError(
133
105
'Unexpected message part: structure(%r)' % (structure,))
135
def _args_received(self, args):
136
self.expecting = 'body'
137
self.request_handler.args_received(args)
106
self.args_received = True
107
self.request_handler.dispatch_command(structure[0], structure[1:])
138
108
if self.request_handler.finished_reading:
139
self._response_sent = True
140
109
self.responder.send_response(self.request_handler.response)
141
self.expecting = 'end'
143
def _error_received(self, error_args):
144
self.expecting = 'end'
145
self.request_handler.post_body_error_received(error_args)
147
111
def bytes_part_received(self, bytes):
148
if self.expecting == 'body':
149
self._should_finish_body = True
150
self.request_handler.accept_body(bytes)
152
raise errors.SmartProtocolError(
153
'Unexpected message part: bytes(%r)' % (bytes,))
155
def end_received(self):
156
if self.expecting not in ['body', 'end']:
157
raise errors.SmartProtocolError(
158
'End of message received prematurely (while expecting %s)'
160
self.expecting = 'nothing'
161
self.request_handler.end_received()
112
# Note that there's no intrinsic way to distinguish a monolithic body
113
# from a chunk stream. A request handler knows which it is expecting
114
# (once the args have been received), so it should be able to do the
116
self.request_handler.accept_body(bytes)
117
self.request_handler.end_of_body()
162
118
if not self.request_handler.finished_reading:
163
raise errors.SmartProtocolError(
164
"Complete conventional request was received, but request "
165
"handler has not finished reading.")
166
if not self._response_sent:
167
self.responder.send_response(self.request_handler.response)
119
raise SmartProtocolError(
120
"Conventional request body was received, but request handler "
121
"has not finished reading.")
122
self.responder.send_response(self.request_handler.response)
170
125
class ResponseHandler(object):
277
233
bytes = self._medium_request.read_bytes(next_read_size)
279
235
# end of file encountered reading from server
280
if 'hpss' in debug.debug_flags:
282
'decoder state: buf[:10]=%r, state_accept=%s',
283
self._protocol_decoder._get_in_buffer()[:10],
284
self._protocol_decoder.state_accept.__name__)
285
236
raise errors.ConnectionReset(
286
"Unexpected end of message. "
287
"Please check connectivity and permissions, and report a bug "
288
"if problems persist.")
237
"please check connectivity and permissions",
238
"(and try -Dhpss if further diagnosis is required)")
289
239
self._protocol_decoder.accept_bytes(bytes)
291
def protocol_error(self, exception):
292
# Whatever the error is, we're done with this request.
293
self.finished_reading = True
294
self._medium_request.finished_reading()
297
241
def read_response_tuple(self, expect_body=False):
298
242
"""Read a response tuple from the wire."""
299
243
self._wait_for_response_args()