Subject: HTTP/3 DATA_WITH_OFFSET frame

From: Samuel Hurst <[email-masked]>
Date: Thu, 18 Feb 2021 15:09:54 +0000

Hello to both the QUIC and HTTP working groups,

******
TL;DR: I've made a new extension frame (with I-D [1]) to support binary
framing of multipart range requests in HTTP/3.
******

A long time ago we started an effort to adapt the QUIC wire protocol to
be able to efficiently deliver HTTP resources to many receivers using
multicast [2]. We have been using this in our experiments with delivery
of segmented live media for some time now [3], using multipart range
requests to fill gaps from packet loss.

As part of these experiments, we discovered issues with maintaining
synchronisation between senders and receivers using HTTP/3 DATA frames
carried on an unreliable transport. In order to help mitigate this
issue, I have come up with a new DATA_WITH_OFFSET extension frame [1]
which is based on the H3 DATA frame but carries a HTTP representation
offset in the header.

Outside of the multicast work, I discovered that such a frame could be
more generally useful in terms of supporting multipart range requests in
HTTP/3. My current understanding is that a HTTP/3 endpoint that supports
range requests will perform single range requests fine, but I would
imagine that performing a multipart range request with HTTP/3 would
require both endpoints to use the existing multipart/byteranges media
type in the body response. This means that endpoints aren't able to take
advantage of features such as binary framing and header compression that
HTTP/3 and QPACK give.

I've put together a short internet draft as a starting point. Section 3
describes the extension frame itself, and section 4 describes how it is
used with multipart range responses. As part of this, I've modified the
syntax of the Content-Range response header to make it an explicit
list-based field as the current HTTP/3 spec doesn't allow you to use
more HEADERS frames between DATA frames. This extra functionality is
dependent on endpoints negotiating support with a HTTP/3 settings parameter.

Any comments or feedback are welcomed.

Best Regards,
Sam

[1]:
https://datatracker.ietf.org/doc/draft-hurst-quic-http-data-offset-frame/
[2]: https://datatracker.ietf.org/doc/draft-pardue-quic-http-mcast/
[3]:
https://www.bbc.co.uk/rd/projects/dynamic-adaptive-streaming-ip-multicast-dasm

---

From: Dmitri Tikhonov <[email-masked]>
Date: Thu, 18 Feb 2021 10:48:57 -0500

Hello Sam,

An interesting draft!

> advantage of features such as binary framing and header compression that

These are two different use cases: multicast over unreliable transport
and multipart range requests.  Have you implemented the latter?  As an
implementer, I would be curious to see how a receiver can take advantage
of such framing.  I imagine that several read cursors would have to be
maintained in case of missing STREAM frames and adjusted as more data
comes in.  Then there is the matter of potentially overlapping STREAM
frames due to retransmit.  Not that any of that can't be done, of
course, but it would be an undertaking...

> used with multipart range responses.

>From Section 3:

 " The purpose of the "DATA_WITH_OFFSET" frame is only to assist in
 " locating a particular slice of data carried as part of an HTTP
 " message payload, and not as a means to send data out of order.
 " Senders MUST send data in order, i.e. with increasing values in the
 " Offset field.

Why proscribe such use?  This may be an avenue for innovation or
optimization.

  - Dmitri.

---

From: Samuel Hurst <[email-masked]>
Date: Thu, 18 Feb 2021 16:15:27 +0000

> An interesting draft!

Thank you!

> course, but it would be an undertaking...

I have not implemented the latter yet, mostly because of a lack of time.
This has primarily come out of our unreliable transport work around
multicast, but it just so happens that with my familiarity with using
multipart range request I figured that it could benefit there too.

In terms of actually implementing the multirange support, my personal
approach would be to have the stream manage the retransmission and then
pass this to a HTTP layer within whatever library I'm using (as that was
my previous experience of playing with libraries like ngtcp2/nghttp3).
The DATA_WITH_OFFSET offset header would then just replace whatever
internal data counter I would have been using to synchronise the
position in the HTTP representation with the position in the stream.
This would then naturally skip ahead between ranges.

With the inclusion of the offset field, a potential optimisation could
be to not block the delivery of subsequent ranges while waiting for a
retransmission on a previous range? Which I think might tie into your
next point...

> Why proscribe such use?  This may be an avenue for innovation or

I couldn't immediately think of any particular reason why an
implementation would want to send data out-of-order, and the existing H3
DATA frame must send in-order as it is tied to the stream frame to
derive the offset within the given HTTP representation being
transferred. However, if there are realistic use cases in this regard
then I'm more than happy to remove this proscription in a future version
of the draft.

-Sam

---

From: Dmitri Tikhonov <[email-masked]>
Date: Thu, 18 Feb 2021 11:46:53 -0500

> approach would be to have the stream manage the retransmission and then

By retransmission, do you mean dropping overlaps that were already passed
up to the HTTP layer?

> This would then naturally skip ahead between ranges.

OK, so the HTTP layer would then have to figure out where HTTP/3 frame
headers are.  To do so, it still needs to find the frames in order based
on stream offsets and HTTP/3 frame lengths.

> retransmission on a previous range?

Yes, I get it.

> Which I think might tie into your next point...
> 
> > From Section 3:
> > 
> transferred.

I don't know of a reason, either, but to me that does not mean that
this use must be forbidden.

> However, if there are realistic use cases in this regard

One theoretical use-case that comes to mind is that of a log file that
is being appended to.  The receiver wants to display the latest data
while downloading the whole file.  A new write to the growing file is
sent with higher priority.

  - Dmitri.