~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/smart/message.py

NEWS section template into a separate file

Show diffs side-by-side

added added

removed removed

Lines of Context:
12
12
#
13
13
# You should have received a copy of the GNU General Public License
14
14
# along with this program; if not, write to the Free Software
15
 
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16
16
 
17
17
import collections
18
18
from cStringIO import StringIO
36
36
 
37
37
    def headers_received(self, headers):
38
38
        """Called when message headers are received.
39
 
        
 
39
 
40
40
        This default implementation just stores them in self.headers.
41
41
        """
42
42
        self.headers = headers
67
67
 
68
68
    def protocol_error(self, exception):
69
69
        """Called when there is a protocol decoding error.
70
 
        
 
70
 
71
71
        The default implementation just re-raises the exception.
72
72
        """
73
73
        raise
74
 
    
 
74
 
75
75
    def end_received(self):
76
76
        """Called when the end of the message is received."""
77
77
        # No-op by default.
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
 
            raise SmartProtocolError(
124
 
                "Conventional request body was received, but request handler "
125
 
                "has not finished reading.")
126
 
        self.responder.send_response(self.request_handler.response)
 
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)
127
168
 
128
169
 
129
170
class ResponseHandler(object):
131
172
 
132
173
    def read_response_tuple(self, expect_body=False):
133
174
        """Reads and returns the response tuple for the current request.
134
 
        
 
175
 
135
176
        :keyword expect_body: a boolean indicating if a body is expected in the
136
177
            response.  Some protocol versions needs this information to know
137
178
            when a response is finished.  If False, read_body_bytes should
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(
240
280
            if 'hpss' in debug.debug_flags:
241
281
                mutter(
242
282
                    'decoder state: buf[:10]=%r, state_accept=%s',
243
 
                    self._protocol_decoder._in_buffer[:10],
 
283
                    self._protocol_decoder._get_in_buffer()[:10],
244
284
                    self._protocol_decoder.state_accept.__name__)
245
285
            raise errors.ConnectionReset(
246
 
                "please check connectivity and permissions",
247
 
                "(and try -Dhpss if further diagnosis is required)")
 
286
                "Unexpected end of message. "
 
287
                "Please check connectivity and permissions, and report a bug "
 
288
                "if problems persist.")
248
289
        self._protocol_decoder.accept_bytes(bytes)
249
290
 
250
291
    def protocol_error(self, exception):
252
293
        self.finished_reading = True
253
294
        self._medium_request.finished_reading()
254
295
        raise
255
 
        
 
296
 
256
297
    def read_response_tuple(self, expect_body=False):
257
298
        """Read a response tuple from the wire."""
258
299
        self._wait_for_response_args()
267
308
 
268
309
    def read_body_bytes(self, count=-1):
269
310
        """Read bytes from the body, decoding into a byte stream.
270
 
        
271
 
        We read all bytes at once to ensure we've checked the trailer for 
 
311
 
 
312
        We read all bytes at once to ensure we've checked the trailer for
272
313
        errors, and then feed the buffer back as read_body_bytes is called.
273
314
 
274
315
        Like the builtin file.read in Python, a count of -1 (the default) means
289
330
        while not self.finished_reading:
290
331
            while self._bytes_parts:
291
332
                bytes_part = self._bytes_parts.popleft()
292
 
                if 'hpss' in debug.debug_flags:
 
333
                if 'hpssdetail' in debug.debug_flags:
293
334
                    mutter('              %d byte part read', len(bytes_part))
294
335
                yield bytes_part
295
336
            self._read_more()
312
353
        raise errors.LockContention('(remote lock)')
313
354
    elif error_name == 'LockFailed':
314
355
        raise errors.LockFailed(*error_args[:2])
 
356
    elif error_name == 'FileExists':
 
357
        raise errors.FileExists(error_args[0])
 
358
    elif error_name == 'NoSuchFile':
 
359
        raise errors.NoSuchFile(error_args[0])
315
360
    else:
316
361
        raise errors.ErrorFromSmartServer(error_tuple)