Subject: Nice

From: Martin Thomson <[email-masked]>
Date: Fri, 16 Aug 2013 10:39:39 -0700

On a different end of the spectrum that we're used to operating in for
HTTP/2.0, this is a small proposal for a header that advises
intermediaries about the relative (un)priority of requests.

http://tools.ietf.org/html/draft-thomson-http-nice-00

This is probably most useful for constrained servers (I've put core on BCC).

--Martin

p.s., The title isn't a value judgement, it's a nod to the unix
utility (thanks to Richard Barnes for pointing this out).

---

From: William Chan (陈智昌) <[email-masked]>
Date: Fri, 16 Aug 2013 19:55:27 +0200

Quick thoughts/questions:
* Do you expect browsers to set this at all? It's not obvious to me how my
browser would use this, so I probably wouldn't bother with it in my browser.
* It seems like for your intended use, the priority level is not just an
opaque level but would carry semantic meaning. If that's the case, I
suggest renaming the header accordingly to indicate the appropriate
semantic axis.
* Can you give an example of where this would be used in an open,
interoperable manner? I'd like to understand the use cases that motivate
introducing prioritization semantics at a protocol level rather than an out
of band mechanism (e.g. intermediaries might be coded to understand that
different URL endpoints have certain priority levels).

---

From: James M Snell <[email-masked]>
Date: Fri, 16 Aug 2013 10:57:33 -0700

My immediate first response is: how does this overlap with Stream
priority.. I know this is a separate thing but it would be good to
make it clear how these intersect.

---

From: William Chan (陈智昌) <[email-masked]>
Date: Fri, 16 Aug 2013 20:04:49 +0200

Stream priority is only relative to other streams in a HTTP/2 connection.
The absolute values themselves carry no semantic meaning. They're purely
relative.

This Nice header proposal seems to ascribe semantic meaning to certain nice
values. In that sense, it's very distinct from stream priorities.

---

From: Martin Thomson <[email-masked]>
Date: Fri, 16 Aug 2013 11:12:41 -0700

> browser would use this, so I probably wouldn't bother with it in my browser.

I wouldn't expect you to set this in your browser.  These servers are
rarely serving web pages.  Though there are cases I have in mind where
JS applications might add the header to an XmlHTTPRequest.

> opaque level but would carry semantic meaning. If that's the case, I suggest
> renaming the header accordingly to indicate the appropriate semantic axis.

Renaming how so?  The only semantics this bears is that 0 > 1 > 2 > 3.

> different URL endpoints have certain priority levels).

I'm glad you asked.  We currently have a service deployed that
provides HTTP intermediation for devices, allowing those devices to
effectively act as HTTP servers.  Some of these devices are
battery-powered.  The interface between the intermediary and the
device is proprietary, which would allow the device to inform the
intermediary of it's current state.

If this header were present, the device - acting as a server - could
provide application-layer hints to its clients about what it might
mean to mark a request as "nice: 1" vs. "nice: 3".  Then, the
application could mark those requests that it didn't consider to be
important accordingly.

The key here is that while the intermediary to origin server
interactions are clearly proprietary, the client is just an HTTP
client in every regard.

---

From: Martin Thomson <[email-masked]>
Date: Fri, 16 Aug 2013 11:14:16 -0700

> make it clear how these intersect.

These are orthogonal.  Stream priority is a way of saying that a given
request has higher or lower relative latency requirements.  Whereas
this marks a request as being not important enough to get through.

I think that a little text on that subject makes sense.

---

From: Martin Thomson <[email-masked]>
Date: Fri, 16 Aug 2013 11:24:40 -0700

> values. In that sense, it's very distinct from stream priorities.

This semantic meaning is very loose.  Intentionally.  The first
writeup I put together had two values: 0 and 1.  Then I was convinced
that some applications might want a tiny bit more flexibility, which
would allow them to operate without having close coordination between
the origin server and client.  Learning what means what is still
something that requires some degree of coordination, but that can be a
little less than real-time.

The key here is that the client needs to know that there is some value
in dropping the reliability of the request it is making.  That's
unavoidable.  Going from that to more than one level isn't a huge
stretch, but drawing the line is the real challenge.

The number and nature of possible values and expressions of policy is
a massive rathole, as you might appreciate.  When discussing this with
colleagues here, we came up with a range of different ways to manage
this, including bit maps, multidimensional coordinate systems, special
labeling and a few other crazy schemes including a set of URI path
regular expressions (no kidding, that was the *first* proposal
floated).  The current proposal is as it is because when I'm building
the bike shed, I get to decide the colour.

---

From: James M Snell <[email-masked]>
Date: Fri, 16 Aug 2013 11:29:04 -0700

+1.. a bit of explanation in the text would be good... in particular,
an implementer using the Nice header in an HTTP/2 request will need to
understand how Stream Priority and Nice really have nothing to do with
each other... that distinction could get lost if it's not made
explicit. Otherwise, this looks fine.

That said, I'm thinking that this could easily be implemented as a
Prefer token per http://tools.ietf.org/html/draft-snell-http-prefer-18

The HTTP Prefer header has already been accepted for publication as an
RFC (it's just waiting on the httpbis work to be completed). The
semantics for handling this seem to be appropriate for use with
Prefer.

Example:

  GET /m HTTP/1.1
  Host: device9710.example.net:11453
  Prefer: nice=2

It would also be interesting to see how this plays alongside other
Prefer directives like "wait" and "respond-async" ... For instance,
the a client could tell the intermediary that a request is of low
importance and that the intermediary can provide an asynchronous
response when it gets around to processing the request...

  GET /m HTTP/1.1
  Host: device970.example.net:11453
  Prefer: nice=3, wait=60, respond-async

Semantically this says, "Please treat this request as unimportant, if
you can't respond within 60 seconds, respond asynchronously."

- James

---

From: Martin Thomson <[email-masked]>
Date: Fri, 16 Aug 2013 11:40:19 -0700

> Prefer token per http://tools.ietf.org/html/draft-snell-http-prefer-18

I did consider Prefer when putting this together, and I almost used it
(you'll notice that there is a nice+wait example in the doc already).

The reason I didn't use Prefer is that my understanding is that Prefer
is probably going to be ignored by intermediaries, since the
formulation of Prefer is such that an origin server is where it is
targeted.  I also saw "Preference-Applied" as being a little
disingenuous in this context, despite on first blush appearing to be
relevant, I just can't conceive of any value in anything other than
the negative (that is, this preference was NOT applied).

That said, it does fit from one perspective.  That is, this is an
eminently ignorable header, and designed as such.

---

From: James M Snell <[email-masked]>
Date: Fri, 16 Aug 2013 11:48:40 -0700

>From Section 2:

  In various situations, a proxy might
  determine that it is capable of honoring
  a preference independently of the server
  to which the request has been directed.

;-)

> the negative (that is, this preference was NOT applied).

The use of Preference-Applied is entirely optional and is only
required in certain specific situations (specifically, when the client
really needs to know whether the preference has been applied and is
unable to determine that in some other way. In the case of a "Prefer:
nice=3", I can't imagine that Preference-Applied would be necessary at
all... therefore, ignore it.

- James

---

From: Mark Nottingham <[email-masked]>
Date: Mon, 19 Aug 2013 10:36:31 +1000

FWIW, in your use case, Martin, the intermediary is acting as the origin server -- it's a gateway, not a proxy.

Cheers,

--
Mark Nottingham   http://www.mnot.net/

---

From: Martin Thomson <[email-masked]>
Date: Mon, 19 Aug 2013 11:33:05 -0700

> FWIW, in your use case, Martin, the intermediary is acting as the origin server -- it's a gateway, not a proxy.

Right you are.  I'm still struggling with the Prefer thing though.  It
makes sense in a way, but it triggers antibodies.

Maybe it's just Prefer isn't a real header in its own right.  It's a
header that contains other headers.  There's nothing special about
what Prefer carries that a regular header couldn't already carry.
There isn't a clear set of rules that help me decide when X belongs in
Prefer and when it doesn't.

---

From: James M Snell <[email-masked]>
Date: Mon, 19 Aug 2013 11:58:57 -0700

The main reason Prefer exists is to give a reliably ignorable
container for simple things that (a) can be safely ignored and (b)
deal with optional behaviors the server is being asked to do.
Truthfully, It's no really no different than the similar groups of
things we have in headers like Cache-Control... which is also made up
of a bunch of individual directives that could exist as independent
headers.

FWIW, I was just pointing out that you could have used Prefer and that
what you've described fits within Prefer's original purpose. If you'd
like using a separate header better, then by all means do so, but IMHO
it would be a purely stylistic choice as I see no technical advantages
to using a brand new dedicated header field (except perhaps saving a
handful of octets the first time you send it in an http/2 compressed
header block).

And yes, there are clear rules for when you would use Prefer vs. not
use it: Prefer is used by the client to ask the server to apply
optional behaviors when processing a request; Expressing those within
Prefer means that the server can safely ignore the client's request to
apply those behaviors if the server chooses. In my opinion, that makes
it fairly clear what kinds of things you'd put into it. Things like
"Link" and "HTTP2-Settings" obviously do not fit because those do not
deal with an "optional behavior that is safe to ignore". With "nice",
the client is asking the server to treat the request as unimportant..
that's clearly an "optional behavior that is safe to ignore". I'm
honestly not sure how much clearer it could be ;-)

- James