- From: Austin Wright <aaa@bzfx.net>
- Date: Wed, 29 Oct 2025 12:51:18 -0700
- To: Richard Bradbury <richard.bradbury@rd.bbc.co.uk>
- Cc: HTTP Working Group <ietf-http-wg@w3.org>
- Message-Id: <5743648D-D924-4600-8B47-00234CA36595@bzfx.net>
Hi Richard, > On Oct 29, 2025, at 05:51, Richard Bradbury <richard.bradbury@rd.bbc.co.uk> wrote: > > Thanks for the suggestion to use a multipart partial content response instead of chunked transfer. > > Reading section 15.3.7.2 of RFC 9110 <https://www.rfc-editor.org/rfc/rfc9110.html#section-15.3.7.2>, the requirement for the HTTP client to request at least two byte ranges to elicit a multipart/byterange response is certainly satisfied by requesting Range: bytes=0-,0-. Requesting the whole representation twice doesn't seem too much of a hack. Likewise, I don't have any problem with a multipart/byterange response. Overall, it seems quite a neat solution. > Good catch with “bytes=“, I promise I had this in an initial draft of my email! > One wrinkle is working out how the responding HTTP server (the gateway in this Use Case) populates Content-Length at the start of its response. It's hard for it to predict how many "parts" the received object will need to be split into. One implementation strategy would be to decide up front on a fixed set of blocks and to stick with that target block pattern regardless of how/when multicast packets arrive at the gateway. I'm not sure if that lack of flexibility would be a problem in practice or not. > You can use chunked encoding and multi-part responses at the same time. (In HTTP 2 and 3, sending multiple data frames are the equivalent to chunked encoding, they just don’t have extension points.) I wouldn’t be surprised if all HTTP servers do it this way. While this means you can’t use Content-Length, for purposes of understanding how much data remains to be transferred, the first “Content-Range” header will inform the client of the total length of the resource. Would that be sufficient for your use? Regards, Austin. > Thanks also for pointing me at your Internet Draft covering push-based Use Cases. > > > On 27/10/2025 02:52, Austin Wright wrote: >> Since the chunked encoding extension points have no equivalent in other HTTP versions, they are going to be highly disfavored. Even if they were, you would also need a way for clients to signal that they would read the extension, instead of ignoring it. However, I think there’s a better mechanism that’s well supported and will get you most of the way there. >> >> Did you consider partial content responses <https://www.rfc-editor.org/rfc/rfc9110.html#name-206-partial-content> for your needs? While parts are typically provided in order, they can be delivered out-of-order, and you can deliver the entire resource this way. >> >> To upload documents, requests could use the PATCH method. Since “multipart/byteranges” is often disfavored, I have an Internet-Draft over in the HTTP APIs working group called “Byte Range PATCH” that defines alternative formats; I would appreciate your review: https://datatracker.ietf.org/doc/draft-ietf-httpapi-patch-byterange/ >> >> Responses are be carried in a 206 (Partial Content) response, to a client that indicates it supports these responses. To indicate support for multipart responses (where each part lists its own Content-Range field, instead of in the response headers), you must make a Range request with multiple ranges; this suggests you can make a Range request listing the whole resource twice, and the server should interpret this as support for multipart partial content responses for the whole document: >> >> > Range 0-, 0- >> >> If this sounds like too much of a hack, the alternative would be to introduce a new field that indicates which multipart response formats are permissible: >> >> > Accept-Multipart: message/byterange, multipart/byteranges, application/byteranges >> >> In particular, application/byteranges is a proposed binary format that would be defined by Byte Range PATCH. If you would find this useful, please let us know over there. >> >> >>> On Oct 20, 2025, at 08:40, Richard Bradbury wrote: >>> >>> I am seeking expert opinion on a candidate solution to a Real World Use Case with which I was recently presented. >>> >>> TL;DR: >>> >>> Would it be legitimate to extend HTTP/1.1 chunked transfer coding to support delivery of chunks out of order? >>> Is such an extension a useful thing to standardise? >>> Use Case description >>> >>> The Use Case involves transmitting Binary Large Objects (BLOBs) in a multicast FLUTE v1 <https://www.rfc-editor.org/rfc/rfc3926.html> session operating in carousel mode (i.e., FLUTE transmission objects in the session are sent repeatedly, possibly interleaved). The receiver is a gateway device offering an HTTP endpoint to downstream clients that want to acquire one or more transmission objects of interest to them. >>> >>> Steps: >>> >>> A client requests an HTTP resource from the gateway, citing it's URL. >>> The gateway joins the appropriate multicast group (based on some look-up mechanism not of concern here) and starts receiving FLUTE transmission objects, including the File Delivery Table <https://www.rfc-editor.org/rfc/rfc3926.html#section-3.2> transmission object. >>> The gateway looks up the URL requested by the client in the File Delivery Table of the FLUTE session and this yields the Transmission Object Identifier that it needs to acquire. >>> The gateway starts receiving FLUTE packets (well, actually ALC/LCT packets) for the identified transmission object and sends their payloads to the requesting client in the HTTP response body. >>> So far, so vanilla. >>> The twist is that the gateway has a low memory footprint, much smaller than the size of the BLOBs being transmitted in the FLUTE session. Hence, it cannot operate in a store-and-forward mode, and needs instead to deliver incoming data from the FLUTE session to its client in an efficient, pipelined fashion, minimising the need for buffering and anything beyond simple reassembly of received data blocks. Moreover, the client request to the gateway (step 1 above) arrives at a random time during the FLUTE session, in the worst case towards the end of a rotation of the carousel. In addition, the gateway may occasionally drop received FLUTE packets. >>> >>> Candidate solutions >>> >>> My first instinct is always to try and reuse existing building blocks wherever possible, rather than inventing something new. >>> >>> HTTP/1.1 >>> >>> The chunked transfer coding feature that all HTTP/1.1 clients and servers are required to implement seems a good fit, except for one small detail: it assumes in-order delivery of chunks. Each chunk follows on from the last and is appended by the HTTP recipient to the previously received chunk (if any). >>> >>> My idea is to include with every chunk a name–value pair (e.g. "offset=...") that additionally signals the byte position of this chunk in the overall resource representation. I reckon this could be achieved in the chunk delimiter using the chunk-ext production specified in section 7.1 of RFC 9112 <https://www.rfc-editor.org/rfc/rfc9112#name-chunked-transfer-coding>. For example: >>> >>> 1fb;offset="40d4" >>> >>> With this additional signalling, the chunks could be sent on by the gateway to the client in whichever order they are received from the multicast FLUTE session, even if the gateway joins the multicast group partway through a carousel rotation. And the client could, for example, write received chunks to a sparse file using lseek() as they arrive in the HTTP response body. Happy days. >>> >>> Once the entire transmission object has been received by the gateway and forwarded to the requesting client, the HTTP response body is terminated with the standard zero-length chunk. (More than one full rotation of the FLUTE carousel may be required to satisfy this termination condition in the presence of packet loss.) >>> >>> In the absence of the proposed "offset=..." extension, a received chunk is assumed to belong immediately after the one previously received, as now, so the signalling is backwards-compatible with RFC 9112. >>> >>> HTTP/2 >>> >>> (Not an immediate requirement, but I include an analysis for completeness.) >>> >>> This protocol version effectively uses chunked transfer for all message bodies, thanks to its binary framing. The HTTP/2 DATA frame includes length but not position. Being based on TCP, HTTP/2 client implementations are likely not expecting to receive DATA frames out of order. Since chunked transfer coding is explicitly prohibited by section 8.1 of RFC 9113 <https://www.rfc-editor.org/rfc/rfc9113.html#name-http-message-framing> it seems very difficult to achieve our of order delivery with this version of HTTP. >>> HTTP/3 >>> >>> (Not an immediate requirement, but I include an analysis for completeness.) >>> >>> Again, this protocol version natively uses chunked transfers. Similar to HTTP/2, the HTTP/3 DATA frame header signals the frame length. The position of this in the underlying QUIC stream is explicitly encoded in the Offset field of the QUIC STREAM frame header, so there is potential to get cute with HTTP/3 DATA frame delivery order, provided the size of the HTTP/3 DATA frame headers (which can contain variable-length integers) is properly accounted for and no other frames are sent on that QUIC stream. I can't decide if that's elegant or evil. Maybe both at the same time. >>> >>> Although QUIC streams are intended to offer an in-order bytestream abstraction to applications, being a UDP-based protocol, QUIC endpoints need to be robust to receiving datagrams out of order, to some extent. I note in particular the following in section 2.2 of RFC 9000 <https://www.rfc-editor.org/rfc/rfc9000.html#name-sending-and-receiving-data>: >>> "Endpoints MUST be able to deliver stream data to an application as an ordered byte stream. Delivering an ordered byte stream requires that an endpoint buffer any data that is received out of order, up to the advertised flow control limit. >>> >>> QUIC makes no specific allowances for delivery of stream data out of order. However, implementations MAY choose to offer the ability to deliver data out of order to a receiving application." >>> >>> Hence, sending QUIC STREAM frames with unordered Offset values seems to be a potentially viable solution to satisfy the Use Case that is sort of in keeping with the spirit of RFC 9000. >>> >>> Whether HTTP/3 client implementations are robust to receiving DATA frames out of order is another matter, of course, but that would be a requirement for supporting this Use Case. (Unlike the resource-constrained gateway, the end client in this Use Case is less constrained.) >>>
Received on Wednesday, 29 October 2025 19:51:36 UTC