~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/smart/message.py

  • Committer: Canonical.com Patch Queue Manager
  • Date: 2009-02-04 12:56:11 UTC
  • mfrom: (3842.3.22 call_with_body_stream)
  • Revision ID: pqm@pqm.ubuntu.com-20090204125611-m7kqmwruvndk7yrv
Add client and server APIs for streamed request bodies.

Show diffs side-by-side

added added

removed removed

Lines of Context:
84
84
    "Conventional" is used in the sense described in
85
85
    doc/developers/network-protocol.txt: a simple message with arguments and an
86
86
    optional body.
 
87
 
 
88
    Possible states:
 
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
 
93
     * nothing: finished
87
94
    """
88
95
 
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
94
103
 
95
104
    def protocol_error(self, exception):
96
105
        if self.responder.response_sent:
100
109
        self.responder.send_error(exception)
101
110
 
102
111
    def byte_part_received(self, byte):
103
 
        raise errors.SmartProtocolError(
104
 
            'Unexpected message part: byte(%r)' % (byte,))
 
112
        if self.expecting == 'body':
 
113
            if byte == 'S':
 
114
                # Success.  Nothing more to come except the end of message.
 
115
                self.expecting = 'end'
 
116
            elif byte == 'E':
 
117
                # Error.  Expect an error structure.
 
118
                self.expecting = 'error'
 
119
            else:
 
120
                raise errors.SmartProtocolError(
 
121
                    'Non-success status byte in request body: %r' % (byte,))
 
122
        else:
 
123
            raise errors.SmartProtocolError(
 
124
                'Unexpected message part: byte(%r)' % (byte,))
105
125
 
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)
 
131
        else:
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:])
 
134
 
 
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'
 
142
 
 
143
    def _error_received(self, error_args):
 
144
        self.expecting = 'end'
 
145
        self.request_handler.post_body_error_received(error_args)
114
146
 
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
119
 
        # right thing.
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)
 
151
        else:
 
152
            raise errors.SmartProtocolError(
 
153
                'Unexpected message part: bytes(%r)' % (bytes,))
 
154
 
 
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)'
 
159
                % (self.expecting,))
 
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)
127
168
 
128
169
 
129
170
class ResponseHandler(object):
202
243
        self._bytes_parts.append(bytes)
203
244
 
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(