Summary

  • The Byte Range PATCH draft, revision 05, says a server without partial-PUT support can ignore Content-Range and replace the entire resource with the submitted fragment.
  • Its message/byterange format makes a single contiguous write range part of a PATCH document. A server must reject a byte-range patch without a known range with HTTP 400 or 422.
  • A range write also needs bounds and length checks. The draft requires an exact match between a supplied part Content-Length and its range, and tells servers accepting sparse writes never to expose uninitialized data.

The draft's example is almost insulting in its simplicity. Start with the bytes 0123456789 followed by a line ending. Send wxyz for positions 2 through 5. The wanted result is 01wxyz6789 plus that line ending. The unwanted result is wxyz: eight original digits and the ending have disappeared. A four-byte change has become a four-byte replacement.

Section 2 identifies the trap. A Content-Range field on PUT requires explicit server support. Without it, the server may ignore the field and perform PUT's ordinary whole-resource replacement. The client may have faithfully declared the intended range while the server faithfully applies a different operation. The bytes on the wire are valid; the contract between the two parties is missing.

The draft proposes PATCH with a body format whose meaning is to write at a specified offset. message/byterange represents one range. multipart/byteranges can carry more than one region, and the proposed application/byteranges provides a binary form. The single-part example puts Content-Range: bytes 2-5/12 inside the patch document, followed by wxyz. A receiver that understands the media type has an explicit partial-write instruction to execute. An unknown patch format should meet a refusal at the method or media-type boundary, before any file is altered.

A range is a contract, not decoration

Each patch part must identify one contiguous range. If the position is unknown, the server must return 400 or 422. If a part includes Content-Length, the number must equal the length specified by its range; a mismatch is an error. These checks sound clerical until a file is being modified in place. They force the server to account for how much data it received and exactly where it intends to put it.

The draft also handles cases where the final size is not yet known. A complete length can accompany a range, or * can stand in for it. Content-Offset describes where to write when the ending position is unknown, such as an indeterminate stream. The form of the instruction changes; the need for a known start position does not. A client that cannot name the destination cannot demand that the server guess.

One byte past the end is another boundary. The draft says servers should reject writes that leap beyond, rather than land adjacent to, the current resource. A gap creates a sparse file with undefined bytes. A server that permits that layout must keep uninitialized content from leaking, and should fill undefined regions with zeros. The visual difference between appending at the edge and leaving a hole in the middle is small. The storage and disclosure consequences are not.

Interruption remains a separate choice. Section 4 offers Prefer: transaction=atomic or transaction=persist: an atomic preference asks the server to commit on success; a persist preference asks it to keep received data during an interrupted upload. The server should report an honored preference with Preference-Applied. Neither option excuses the receiver from interpreting the range correctly in the first place. The earlier question is whether the four bytes belong inside the file or are the new file.

The PATCH RFC provides Accept-Patch as a way to advertise supported patch document types. An operator can therefore ask what the endpoint claims to understand, then test the exact byte outcome. The missing evidence is a controlled mixed-server trace of the same ranged PUT and message/byterange PATCH, including initial and final bytes, status and ETag. That trace would show how real endpoints handle the boundary.

Byte Range PATCH draft and status · RFC 5789 PATCH · RFC 9110 HTTP semantics