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
89
96
def __init__(self, request_handler, responder):
90
97
MessageHandler.__init__(self)
91
98
self.request_handler = request_handler
92
99
self.responder = responder
93
self.args_received = False
100
self.expecting = 'args'
101
self._should_finish_body = False
102
self._response_sent = False
95
104
def protocol_error(self, exception):
96
105
if self.responder.response_sent:
100
109
self.responder.send_error(exception)
102
111
def byte_part_received(self, byte):
103
raise errors.SmartProtocolError(
104
'Unexpected message part: byte(%r)' % (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,))
106
126
def structure_part_received(self, structure):
107
if self.args_received:
127
if self.expecting == 'args':
128
self._args_received(structure)
129
elif self.expecting == 'error':
130
self._error_received(structure)
108
132
raise errors.SmartProtocolError(
109
133
'Unexpected message part: structure(%r)' % (structure,))
110
self.args_received = True
111
self.request_handler.dispatch_command(structure[0], structure[1:])
135
def _args_received(self, args):
136
self.expecting = 'body'
137
self.request_handler.dispatch_command(args[0], args[1:])
112
138
if self.request_handler.finished_reading:
139
self._response_sent = True
113
140
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)
115
147
def bytes_part_received(self, bytes):
116
# Note that there's no intrinsic way to distinguish a monolithic body
117
# from a chunk stream. A request handler knows which it is expecting
118
# (once the args have been received), so it should be able to do the
120
self.request_handler.accept_body(bytes)
121
self.request_handler.end_of_body()
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()
122
162
if not self.request_handler.finished_reading:
123
163
raise errors.SmartProtocolError(
124
"Conventional request body was received, but request handler "
125
"has not finished reading.")
126
self.responder.send_response(self.request_handler.response)
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)
129
170
class ResponseHandler(object):
202
243
self._bytes_parts.append(bytes)
204
245
def structure_part_received(self, structure):
205
if type(structure) is not list:
246
if type(structure) is not tuple:
206
247
raise errors.SmartProtocolError(
207
248
'Args structure is not a sequence: %r' % (structure,))
208
structure = tuple(structure)
209
249
if not self._body_started:
210
250
if self.args is not None:
211
251
raise errors.SmartProtocolError(