RE: PATCH vs multipart/byteranges vs Content-Range

Julian Reschke wrote:
>
> So, to overwrite a single range of bytes, one would need a dummy
(empty) part, unless...
> ...it's ok to use Content-Range as a request header.

Content-Range is an entity header, not a request header. As such, it
describes the entity enclosed in the message, not anything at the
Request URI.

> <http://greenbytes.de/tech/webdav/rfc2616.html#rfc.section.14.16>:
> 
> "The Content-Range entity-header is sent with a partial 
> entity-body to specify where in the full entity-body the 
> partial body should be applied."

> So, to append a line of text to a representation with a 
> current Content-Length of 1234 bytes, would it be ok to use
> 
> ---
> PATCH /test.txt HTTP/1.1
> Host: example.com
> Content-Type: text/plain
> Content-Range: 1234-1245/1234
> Content-Length: 12
> 
> 0123456789
> ---
> 
> (where the line to be appended ends in CRLF, thus counting 12 bytes).

This means "I am sending 12 bytes of a 1234 byte patch, starting at the
end and ranging to an offset that is past the end." In PATCH, the
entity-body is the patch, so a "partial entity-body" means you are only
sending part of a patch. The server is likely to reject such a request
because (a) text/plain isn't a MIME type for a patch format, and (b) it
still needs the other 1234 bytes of the patch to know what to do.

If it was a PUT, it would mean "I am sending 12 bytes of the 1234 byte
entity, starting at the end and continuing 12 bytes past the end," which
seems to be what you are trying to do. However, even this has a
presumption that the first 1234 bytes would have been the same as what
the server already has, and that presumption is not really justified by
the definition of Content-Range. In other words, when you issue a range
request in a GET, you are saying "I only care about a specific part of
the response," which is different than "We agree on the content outside
the range; just send me the part we don't agree on yet." 

> 1) Would it be OK to use Content-Range on PATCH 
> (understanding people previously were reluctant to use it on 
> PUT because servers may ignore it, thus truncate a resource)?

RFC 2616 doesn't define semantics for Content-Range except when it is
used in a response. The specification says that the server must not
ignore Content-Range when it receives it in a request, but it doesn't
say what it should do with it. Effectively, a server should reject all
requests with a Content-Range header unless a protocol layered on top of
HTTP is being used, which defines semantics of such requests. Perhaps
HTTPbis can define semantics for Content-Range in requests but it would
have to be completely optional to be compatible with RFC 2616.

> 2) Should instance-length be the length *before* or *after* 
> applying the
>   request (I'd assume *before*). Or should it just use "*"? (*)

instance-length should be the total length of the complete patch, or
"*".

> 3) Should we mention this in the PATCH spec; minimally 
> requiring servers to either reject requests with 
> Content-Range headers

Servers are already required by RFC 2616 to reject any request with a
Content-Range header unless it knows what to do with it. 

> or to process the payload as a partial replace?

You would need a new header, that works like Content-Range, but applies
to the resource at the request URI instead of the entity body. But, even
if you had such a header, you have no way of choosing which
representation(s) of the resource it applies to. That is problematic
because byte-ranges are very representation-dependent; a byte-range for
a compressed variant is going to be quite different than the byte range
for the uncompressed variant.

By the way, I really like the idea of a patch format based on
multipart/byte-ranges; I even think that such a format should be a
SHOULD requirement for servers that implement PATCH.

- Brian

Received on Saturday, 16 February 2008 16:06:51 UTC