173
173
An extension to version two allows streamed bodies. A streamed body looks
174
174
a lot like HTTP's chunked encoding::
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
182
182
TERMINATOR := SUCCESS_TERMINATOR | ERROR_TERMINATOR
183
183
SUCCESS_TERMINATOR := 'END' NEWLINE
184
184
ERROR_TERMINATOR := 'ERR' NEWLINE CHUNKS SUCCESS_TERMINATOR
262
262
Conventional requests will send a CONTENTS of ::
264
264
CONV_REQ := ARGS SINGLE_OR_STREAMED_BODY?
265
SINGLE_OR_STREAMED_BODY := BYTES
265
SINGLE_OR_STREAMED_BODY := BYTES
268
ARGS := STRUCTURE(argument_tuple)
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")
278
278
If the RESP_STATUS is success ("S"), the arguments are the
279
method-dependent result.
279
method-dependent result.
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
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.
310
310
For new methods, these sequences are just a convention and may be varied
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.
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
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
372
it's writing. This is technically difficult for http but feasible over
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.
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.
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.
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.
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`_.
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