Subject: Comments on Extensible Prioritization Scheme for HTTP

From: Glenn Strauss <[email-masked]>
Date: Thu, 31 Mar 2022 01:21:42 -0400

Comments on Extensible Prioritization Scheme for HTTP
https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-priority-12

HTTP/2 SETTINGS frame in the original RFC7540 spec contains
  SETTINGS_ENABLE_PUSH
This is a logical, boolean flag to enable an optional-use feature.

draft-ietf-httpbis-priority-12 has had multiple revisions with name
changes for a new setting, and the current proposed name is
  SETTINGS_NO_RFC7540_PRIORITIES
with an *inverted boolean value*, which if set to *true* results in
indicating a desire to *disable* use of RFC7540 HTTP/2 PRIORITY frame.

I am a developer mocking up draft-ietf-httpbis-priority.
>From my perspective, in order to follow a logical opt-in to enable use
of optional features, I prefer the following proposal: new SETTINGS
  SETTINGS_ENABLE_PRIORITY
  SETTINGS_ENABLE_PRIORITY_UPDATE
each named after the respective HTTP/2 frame type PRIORITY
and (proposed) PRIORITY_UPDATE.  These are named in similar pattern to
SETTINGS_ENABLE_PUSH feature, associated with HTTP/2 frame PUSH_PROMISE.

Similar to when a TLS client might send TLS early data, an HTTP/2 client
might optimistically send any of the above frames prior to receiving the
HTTP/2 server connection preface.  An HTTP/2 server may ignore unknown
frame types, so a client could determine that a server ignored those
early frames if the HTTP/2 server connection preface does not enable the
SETTINGS feature for supporting the (optional) frame type.  I think that
this is a good convention for optional features:
  SETTINGS_ENABLE_<feature>
and optional features using new frame types tend to have the new frame
type named after the feature the new frame type supports.

For the existing HTTP/2 PRIORITY frame, a client would not definitively
know if PRIORITY is supported unless the server were to send
SETTINGS_ENABLE_PRIORITY, but existing support for HTTP/2 frame type
PRIORITY is not widespread, and use of the HTTP/2 PRIORITY frame is
deprecated in the draft being discussed: draft-ietf-httpbis-priority.

Cheers, Glenn

---

From: Willy Tarreau <[email-masked]>
Date: Thu, 31 Mar 2022 09:07:09 +0200

Hello Glenn,

> indicating a desire to *disable* use of RFC7540 HTTP/2 PRIORITY frame.

It's not as much a desire to "disable" as it is an indication that
it will neither emit nor process them.

> SETTINGS_ENABLE_PUSH feature, associated with HTTP/2 frame PUSH_PROMISE.

But that wouldn't work with existing deployments! Right now support for
priorities is implied by H2. Both a client and a server willing to use
them have nothing to say, and any RFC7540-compliant implementation will
see it like this. Thus a client may expect that the server will deliver
important objects first and may possibly announce certain priorities
based on what it thinks it needs. In fact both sides may act in a way
that is supposed to help the other one based on the assumption that it
will use it and benefit from this.

Explicitly saying "no need to make efforts for me" and "I will not
bother you with this" can be a useful indication to the partner that
it ought to fall back to alternate mechanisms instead.

Hoping this helps,
Willy

---

From: Glenn Strauss <[email-masked]>
Date: Thu, 31 Mar 2022 07:33:14 -0400

> it will neither emit nor process them.

I have proposed SETTINGS_ENABLE_PRIORITY w/ boolean to enable instead of
SETTINGS_NO_RFC7540_PRIORITIES w/ inverted boolean to enable.

> will use it and benefit from this.

Since the PRIORITY frame type already exists, perhaps the default for
SETTINGS_ENABLE_PRIORITY should be 1 and a server can send
SETTINGS_ENABLE_PRIORITY 0 to mean the same thing as
SETTINGS_NO_RFC7540_PRIORITIES 1.  If not sent in the HTTP/2 server
connection preface, then the default remains.  I believe that this is
fully compatible with existing deployments.

However, given that the draft spec deprecates PRIORITY frames, I would
prefer that the default be SETTINGS_ENABLE_PRIORITY 0, and become an
opt-in.  For advanced systems attempting to leverage PRIORITY, I would
expect those systems to be better maintained and able to upgrade in a
reasonable timeframe, as compared to more typical, often non-existent
maintenance cycles.

Please understand that my primary reason for posting is to suggest a
pattern to follow for this and for future opt-in extensions.  The draft
for the proposed PRIORITY_UPDATE might result in unnecessary chatter by
new implementations assuming support for PRIORITY *and* PRIORITY_UPDATE,
whereas my proposed adjustments suggests a more determistic template for
opt-in extensions.

Cheers, Glenn

---

From: Lucas Pardue <[email-masked]>
Date: Thu, 31 Mar 2022 13:06:45 +0100

Hi Glenn,

Thanks for reaching out.

I agree with Willy's words. I'll add that document is in AUTH48 now, and
technical changes so far in the process are best avoided unless there is
overwhelming evidence. Personally I'm not seeing that.

Your proposal focuses on frames but there's more to it than that when it
comes to priorities. It's complicated. HTTP/2 stream priorities are part of
HTTP/2, if you'd like that default off, it would have to happen there, and
that's asking everyone to change. It's too late for that now.

Furthermore, extensible priorities can work if the client uses headers and
no frames. HTTP doesn't require, or provide the means, for servers to
generically advertise the request headers they support. Additionally,
servers can ignore unknown frames, or parse the known PRIORITY_UPDATE frame
and ignore it's contents, per the spec.

It's noble to want a pattern but I don't think we have enough examples of
HTTP/2 extensions at the IETF to form consensus on one. So I think it's
more optimal to consider each extension on a case by case basis and apply
the judgements of the community.

Cheers
Lucas

---

From: Glenn Strauss <[email-masked]>
Date: Thu, 31 Mar 2022 09:46:19 -0400

On Thu, Mar 31, 2022 at 01:06:45PM +0100, Lucas Pardue wrote:
> HTTP/2 extensions at the IETF to form consensus on one.

My understanding is that communicating/negotiating feature support
is among the raison d'être of HTTP/2 SETTINGS.

Communicating and negotiating features is not new.  For example, the
*1977* RFC 731 for telnet has IAC WILL/IAC WONT and IAC DO/IAC DONT.

I believe that draft-ietf-httpbis-priority for PRIORITY_UPDATE has
serious omissions in this regard -- communicating and negotiating
use of the optional feature -- especially since the draft recognizes
limitations of PRIORITY and proposes an alternative to provide
substantially overlapping functionality.  For example:

https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-priority-12#section-2.1.1
makes an assumption which I find incorrect.

   Similarly, if the client receives SETTINGS_NO_RFC7540_PRIORITIES with
   value of 0 or if the settings parameter was absent, it SHOULD stop
   sending PRIORITY_UPDATE frames (Section 7.1), since those frames are
   likely to be ignored.

My server (lighttpd) parses and discards PRIORITY frames, but I am
planning on implementing the coarser, but simpler, PRIORITY_UPDATE,
as well as supporting the proposed HTTP request header Priority.
draft-ietf-httpbis-priority does not currently provide a clean way
to communicate server HTTP/2 support preference for PRIORITY_UPDATE, 
but not PRIORITY, to the client.  Using HTTP/2 SETTINGS appears to
me to be a simple and an appropriate place to communicate this.

Cheers, Glenn

---

From: Willy Tarreau <[email-masked]>
Date: Thu, 31 Mar 2022 16:04:15 +0200

On Thu, Mar 31, 2022 at 09:46:19AM -0400, Glenn Strauss wrote:
> substantially overlapping functionality.

But why do you see it different here ? The optional feature here is
to give up on a previously implied one. As such there's a setting
which says exactly this, "let's enable this optional feature that
allows us to agree on giving up the default implied behaviour".

>  For example:

I'm personally not seeing a problem here. What it says is that if the
peer announces that it doesn't want to abandon the default behavior,
the one seeing this must respect this and not switch to the alternate
one.

> me to be a simple and an appropriate place to communicate this.

Not very sure what you mean here. As a server, you'll likely adapt to
what the client presents, so if you see SETTINGS_NO_RFC7540_PRIORITIES
advertised by the client, you'll likely advertise it as well to indicate
your willingness to switch to PRIORITY_UPDATE, or am I missing something ?

Willy

---

From: Lucas Pardue <[email-masked]>
Date: Thu, 31 Mar 2022 15:20:50 +0100

Hi Glenn,

Response inline

> is among the raison d'être of HTTP/2 SETTINGS.

That depends on the case. For instance, extension frames can be sent
without any need of negotiation and we formally have ALTSVC (RFC 7838) and
ORIGIN (RFC 8336) that do it that way. Examples where settings have been
used are strictly where the HTTP/2 or HTTP/3 semantics have been changed,
such as extended CONNECT (RFC 8441), or the pending HTTP/3 DATAGRAM
setting, or WebTransport extensions to HTTP/2 and HTTP/3. All of these are
quite different in their needs, the advice in
https://httpwg.org/http2-spec/draft-ietf-httpbis-http2bis.html#section-5.5
holds but there are no clear patterns in my opinion.

> *1977* RFC 731 for telnet has IAC WILL/IAC WONT and IAC DO/IAC DONT.

I don't see the relevance between telnet and HTTP/2 or HTTP/3.

> me to be a simple and an appropriate place to communicate this.

We've been over this through the standardization process. There wasn't an
appetite to attempt to define a rich negotiation process for a
prioritization scheme. Instead, an HTTP/2 server that send
SETTINGS_NO_RFC7540_PRIORITIES=1 is most likely going to support Extensible
Priorities because there is nothing else. If at some future point somebody
decides they need a different priority scheme, they will probably have to
do work to figure out how it gets used. We don't need to spend effort today
trying to solve a problem that might never exist.

Cheers,
Lucas

---

From: Glenn Strauss <[email-masked]>
Date: Thu, 31 Mar 2022 11:15:29 -0400

On Thu, Mar 31, 2022 at 03:20:50PM +0100, Lucas Pardue wrote:
> Instead, an HTTP/2 server that send SETTINGS_NO_RFC7540_PRIORITIES=1
> is most likely going to support Extensible Priorities because there
> is nothing else.

I think the logic of that statement is the strongest argument that
the setting name is indirect and suboptimal.

My server could send SETTINGS_NO_RFC7540_PRIORITIES to simply mean
"I ignore PRIORITY frames, so don't bother sending them".  Why should
that imply support for PRIORITY_UPDATE?

In that light, I interpret my proposed
  SETTINGS_ENABLE_PRIORITY_UPDATE
as a clearer, and possible equivalent to Lucas, to the *inversion* of
  SETTINGS_NO_RFC7540_PRIORITIES

If SETTINGS_NO_RFC7540_PRIORITIES 0 implies to Lucas to "use the only
other current alternative which is PRIORITY_UPDATE", then why not have
the setting be to communicate directly that the server supports
PRIORITY_UPDATE?

Why is the indirect SETTINGS_NO_RFC7540_PRIORITIES better?
The reason for creating PRIORITY_UPDATE is due to limitations in
practical use (and implementations).  How can we be so sure that
PRIORITY_UPDATE will be a "perfect" replacement?

> I don't see the relevance between telnet and HTTP/2 or HTTP/3.

Expressing "I do (do not) support"  (IAC DO/IAC DONT)
Expressing "I will (will not) use"  (IAC WILL/IAC WONT)

A server may wish to say one or more of
  I can use PRIORITY frames (or I ignore PRIORITY frames)
  I can use PRIORITY_UPDATE frames (or I ignore PRIORITY_UPDATE frames)
This directly communicates available features (e.g. IAC DO)

I think the proposed overloading of SETTINGS_NO_RFC7540_PRIORITIES is
indirect and unnecessarily confusing.

>the one seeing this must respect this and not switch to the alternate

I got confused with the indirect logic.

As above, because of the overloading and inverted logic, there is no way
for the server to communicate exactly what it supports if the server
supports both.  A client might or might not send
SETTINGS_NO_RFC7540_PRIORITIES.

On the other hand, I think it much more direct if a client or server
sends SETTINGS_ENABLE_PRIORITY or SETTINGS_ENABLE_PRIORITY_UPDATE,
and sending one does not imply anything about the other.
End-to-end?  Hop-by-hop?  PRIORITY is independent from PRIORITY_UPDATE.

If a separate SETTINGS_ENABLE_PRIORITY is not desirable, then
SETTINGS_ENABLE_PRIORITY_UPDATE could imply that PRIORITY_UPDATE
should be used instead of PRIORITY.

Cheers, Glenn

---

From: Willy Tarreau <[email-masked]>
Date: Thu, 31 Mar 2022 17:41:09 +0200

> that imply support for PRIORITY_UPDATE?

See it differently. PRIORITY_UPDATE is more flexible (contains text)
and the server is free to ignore them. So you could see this as a way
to say "I will not read your PRIORITY frames, but I may possibly read
your PRIORITY_UPDATE frames". I seem to remember that it was considered
that explicitly disengaging from both had little benefit considering
that as soon as the client was aware that it doesn't have to maintain
its priority tree, most of the effort is done.

>   SETTINGS_NO_RFC7540_PRIORITIES

No an inversion, you mean equivalent instead ?

> other current alternative which is PRIORITY_UPDATE",

No, that's value 1.

> then why not have

Probably because it was considered that the vast majority of
implementations would advertise the two at once anyway, and that the
extra cost for those willing to implement nothing is close to zero.

> PRIORITY_UPDATE will be a "perfect" replacement?

Noone claims that, however using the same settings mechanism, a future
option could easily ask to replace this choice.

> supports both.

Maybe the essential point you forgot is that once the server sends its
settings, it's too late for the client to make a different choice because
usually the client will send preface + settings + one or a few requests,
then all the server can do is confirm the client's choices. As such the
client will not wait for the server's response before starting to send.
I guess that if the client sends the setting to 1 and the server doesn't
send anything or sends it to zero, most likely the client will just
refrain from sending PRIORITY frames (since it promised not to via the
initial setting) and it will not send PRIORITY_UPDATE frames either since
the server didn't mention accepting them.

> A client might or might not send SETTINGS_NO_RFC7540_PRIORITIES.

Then in this case the client wants to stay on the RFC7540 behavior.

> End-to-end?  Hop-by-hop?  PRIORITY is independent from PRIORITY_UPDATE.

Not completely, you don't want to have both at once. It's not just the
way to convey the message that changes but also the way to calculate
priorities.

Willy

---

From: Lucas Pardue <[email-masked]>
Date: Thu, 31 Mar 2022 19:02:35 +0100

There's lots of things that could theoretically be done. They all add
complexity. Any form of feature advertisement or negotiation would also
need to extend to HTTP/3 for parity. Few clients are going to wait to see
what the server claims to support (and support is a very weird definition
here, because servers can just ignore all client signals even if they are
understood). What we have in the document now has gained IETF consensus and
is due to be imminently published by the RFC Editor. It does not exclude
new additional work being done as a follow up activity, if we discover some
new information and agree to spend effort to solve a problem.

Cheers,
Lucas