~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to doc/developers/network-protocol.txt

  • Committer: Andrew Bennetts
  • Date: 2009-07-27 08:02:52 UTC
  • mto: This revision was merged to the branch mainline in revision 4573.
  • Revision ID: andrew.bennetts@canonical.com-20090727080252-1r4s9oqwlkzgywx7
Fix trivial bug in _vfs_set_tags_bytes.

Show diffs side-by-side

added added

removed removed

Lines of Context:
172
172
 
173
173
An extension to version two allows streamed bodies.  A streamed body looks
174
174
a lot like HTTP's chunked encoding::
175
 
 
 
175
 
176
176
  STREAMED_BODY := "chunked" NEWLINE CHUNKS TERMINATOR
177
177
  CHUNKS := CHUNK [CHUNKS]
178
178
  CHUNK := HEX_LENGTH CHUNK_CONTENT
179
179
  HEX_LENGTH := HEX_DIGITS NEWLINE
180
180
  CHUNK_CONTENT := bytes
181
 
 
 
181
  
182
182
  TERMINATOR := SUCCESS_TERMINATOR | ERROR_TERMINATOR
183
183
  SUCCESS_TERMINATOR := 'END' NEWLINE
184
184
  ERROR_TERMINATOR := 'ERR' NEWLINE CHUNKS SUCCESS_TERMINATOR
201
201
-------------
202
202
 
203
203
.. note::
204
 
 
 
204
  
205
205
  For some discussion of the requirements that led to this new protocol
206
206
  version, see `bug #83935`_.
207
207
 
226
226
  HEADERS := LENGTH_PREFIX bencoded_dict
227
227
  END_MESSAGE := "e"
228
228
 
229
 
  BODY := MESSAGE_PART+
 
229
  BODY := MESSAGE_PART+ 
230
230
  MESSAGE_PART := ONE_BYTE | STRUCTURE | BYTES
231
231
  ONE_BYTE := "o" byte
232
232
  STRUCTURE := "s" LENGTH_PREFIX bencoded_structure
262
262
Conventional requests will send a CONTENTS of ::
263
263
 
264
264
  CONV_REQ := ARGS SINGLE_OR_STREAMED_BODY?
265
 
  SINGLE_OR_STREAMED_BODY := BYTES
 
265
  SINGLE_OR_STREAMED_BODY := BYTES 
266
266
        | BYTES+ TRAILER
267
 
 
268
 
  ARGS := STRUCTURE(argument_tuple)
 
267
         
 
268
  ARGS := STRUCTURE(argument_tuple) 
269
269
  TRAILER := SUCCESS_STATUS | ERROR
270
270
  SUCCESS_STATUS := ONE_BYTE("S")
271
271
  ERROR := ONE_BYTE("E") STRUCTURE(argument_tuple)
276
276
  RESP_STATUS := ONE_BYTE("S") | ONE_BYTE("E")
277
277
 
278
278
If the RESP_STATUS is success ("S"), the arguments are the
279
 
method-dependent result.
 
279
method-dependent result.  
280
280
 
281
281
For errors (where the Status byte of a response or a streamed body is
282
282
"E"), the situation is analagous to requests.  The first item in the
287
287
Note that the streamed body from version two is now just multiple
288
288
BYTES parts.
289
289
 
290
 
The end of the request or response is indicated by the lower-level
 
290
The end of the request or response is indicated by the lower-level 
291
291
END_MESSAGE.  If there's only one BYTES element in the body, the TRAILER
292
292
may or may not be present, depending on whether it was sent as a single
293
293
chunk or as a stream that happens to have one element.
304
304
  initial success and then another byte part with no intervening bytes.
305
305
  If we stop sending the final success message and only flag errors
306
306
  they'll only get one if the error is detected after streaming starts but
307
 
  before any bytes are actually sent.  Possibly we should wait until at
 
307
  before any bytes are actually sent.  Possibly we should wait until at 
308
308
  least the first chunk is ready before declaring success.
309
309
 
310
310
For new methods, these sequences are just a convention and may be varied
317
317
 
318
318
  (Discussion) We're discussing having the byte segments be not just a
319
319
  method for sending a stream across the network, but actually having them
320
 
  be preserved in the RPC from end to end.  This may be useful when
 
320
  be preserved in the rpc from end to end.  This may be useful when
321
321
  there's an iterator on one side feeding in to an iterator on the other,
322
322
  if it avoids doing chunking and byte-counting at two levels, and if
323
 
  those iterators are a natural place to get good granularity.  Also, for
 
323
  those iterators are a natural place to get good granularity.  Also, for 
324
324
  cases like ``insert_record_stream`` the server can't do much with the
325
325
  data until it gets a whole chunk, and so it'll be natural and efficient
326
326
  for it to be called with one chunk at a time.
327
327
 
328
 
  On the other hand, there may be times when we've got some bytes from the
 
328
  On the other hand, there may be times when we've got some bytes from the 
329
329
  network but not a full chunk, and it might be worthwhile to pass it up.
330
330
  If we promise to preserve chunks, then to do this we'd need two separate
331
331
  streaming interfaces: "we got a chunk" and "we got some bytes but not
369
369
  sent.
370
370
 
371
371
  This relies on the client being able to read back from the server while
372
 
  it's writing.  This is technically difficult for HTTP but feasible over
373
 
  a socket or SSH.
 
372
  it's writing.  This is technically difficult for http but feasible over
 
373
  a socket or ssh.
374
374
 
375
375
  We'd need a clean way to pass this back to the request method, even
376
376
  though it's presumably in the middle of doing its body iterator.
400
400
  happening out of order, or mixed requests happening at the same time.
401
401
 
402
402
  Wonder how our network performance would have turned out now if we'd
403
 
  done full-duplex from the start, and ignored hpss over HTTP.  We have
404
 
  pretty good (read-only) HTTP support just over dumb HTTP, and that may be
 
403
  done full-duplex from the start, and ignored hpss over http.  We have
 
404
  pretty good (readonly) http support just over dumb http, and that may be
405
405
  better for many users.
406
406
 
407
407
 
422
422
that includes any repository that might need to be referenced, and the
423
423
client needs to know about a root directory beyond which it cannot ascend.
424
424
 
425
 
Servers run over SSH will typically want to be able to access any path the
 
425
Servers run over ssh will typically want to be able to access any path the
426
426
user can access.  Public servers on the other hand (which might be over
427
 
HTTP, SSH or TCP) will typically want to restrict access to only a
 
427
http, ssh or tcp) will typically want to restrict access to only a
428
428
particular directory and its children, so will want to do a software
429
429
virtual root at that level.  In other words they'll want to rewrite
430
430
incoming paths to be under that level (and prevent escaping using ../
431
431
tricks).  The default implementation in bzrlib does this using the
432
432
`bzrlib.transport.chroot` module.
433
433
 
434
 
URLs that include ~ are passed across to the server verbatim and the
435
 
server can expand them.  The default implementation in bzrlib does this
436
 
using `bzrlib.transport.pathfilter` and `os.path.expanduser`, taking care
437
 
to respect the virtual root.
 
434
URLs that include ~ should probably be passed across to the server
 
435
verbatim and the server can expand them.  This will proably not be
 
436
meaningful when limited to a directory?  See `bug 109143`_.
438
437
 
439
 
Paths in request arguments are UTF-8 encoded, except for the legacy VFS
440
 
requests which expect escaped (`bzrlib.urlutils.escape`) paths.
 
438
.. _bug 109143: https://bugs.launchpad.net/bzr/+bug/109143
441
439
 
442
440
 
443
441
Requests