Subject: [quicwg/base-drafts] Can PUSH_PROMISE rules be relaxed to allow sending on a control stream? (#947)

From: Lucas Pardue <[email-masked]>
Date: Mon, 20 Nov 2017 18:45:51 +0000 (UTC)

Reading the latest HTTP/QUIC editor's copy. Section 4.4 on server push states that:

> The PUSH_PROMISE frame is sent on a response stream.

The recent changes in this area have moved away from Stream ID, PUSH_PROMISE frames now reference a Push ID. Push cancellation is achieved by the HTTP/QUIC CANCEL_PUSH frame, which is restricted to the control stream. 

So I got to wondering if there may be benefits allowing/restricting HTTP/QUIC PUSH_PROMISE frames on the control stream. It seems to me that CANCEL_PUSH forces implementations to be geared up for managing server push on the control stream anyway.

Maybe I'm missing the benefit of tying pushes to requests, RFC 7540 talks about the requirements but I can't infer the benefits. Relaxing the rule and incorporating something like cache digests might give an appropriately-configured server enough information to push just the correct things with a bit more performance (it is described as unsolicited right?). Another use case is to allow server push without having to hold streams open.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/issues/947

---

From: Martin Thomson <[email-masked]>
Date: Tue, 21 Nov 2017 04:28:45 +0000 (UTC)

Ordering of PUSH_PROMISE relative to other activity in a response is critical.  Ideally, a URL arrives after a PUSH_PROMISE, or the client might make another request that duplicates the push.  It's very hard for a server to decide to cancel a request on the basis that a push is outgoing, because it can't know whether the client really wanted a second request, so we rely on ordering.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/issues/947#issuecomment-345913522

---

From: Lucas Pardue <[email-masked]>
Date: Tue, 21 Nov 2017 09:23:28 +0000 (UTC)

>  It's very hard for a server to decide to *cancel a request* on the basis that a push is outgoing, because it can't know whether the client really wanted a second request, so we rely on ordering.

For clarification, are you saying it's hard for a server to cancel a second request, because the server can't know if the client really wanted the second push?

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/issues/947#issuecomment-345965817

---

From: Lucas Pardue <[email-masked]>
Date: Tue, 21 Nov 2017 14:08:19 +0000 (UTC)

> Ordering of PUSH_PROMISE relative to other activity in a response is critical. Ideally, a URL arrives after a PUSH_PROMISE, or the client might make another request that duplicates the push.

Hmm, now I think about it, RFC 7540 Section 8.2.1 does say that "The server SHOULD send PUSH_PROMISE frames prior to sending any frames that reference the promised responses". HTTP/2 relied on TCP to provide send-order reception guarantees. Since QUIC cannot guarantee ordering across streams but does provide in-order delivery within a stream, sending PUSH_PROMISE on the response stream can help towards this requirement. So a simple way to address my initial comment would be to directly qualify the sentence with text, a reference to Section 8.2.1 or both.

However, I could also argue that the race condition issues could be less pronounced for HTTP/QUIC due to the CANCEL_PUSH semantic that didn't previously exist. A sensible SHOULD would place PUSH_PROMISE on the request stream but there be cases where a request-less push on the control stream could be of benefit.

I'd also like to say that I think the current design is clever. The spec already goes to some lengths to help accommodate request concurrency and out-of-order delivery. I really like the approach for allowing multiple PUSH_PROMISE frames to use the same PUSH ID.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/issues/947#issuecomment-346036886

---

From: Martin Thomson <[email-masked]>
Date: Wed, 22 Nov 2017 04:09:21 +0000 (UTC)

An important property of pushes is their association with other requests.  We discussed uncoupled pushes during the development of HTTP/2 and it made it very difficult for a stack that has multiple clients to decide which of those clients will receive the push.  Though there might be cases where ordering is less critical, but I don't know how to justify adding extra complexity.

Happy to add clarification about the ordering rationale.  

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/issues/947#issuecomment-346237869

---

From: Lucas Pardue <[email-masked]>
Date: Wed, 22 Nov 2017 17:55:38 +0000 (UTC)

Intermediaries perhaps feel particular pain. Some might say that Service Worker shines a new light on old problems.

So I think you've convinced me in the general case. In practical terms, a request object primitive is a pretty useful thing, especially for implementations that already use such a paradigm (perhaps also why H2 or HQ frames that operate at application-level have some difficulty gaining traction). Request/response is also great for implementations that like to minimise state. 

> The PUSH_PROMISE frame is sent on a response stream.

I think the term "response stream" is left over from the old @martinthomson unidirectional PR. This is the only occurrence of the term and in the current context of HTTP/QUIC doesn't make much sense.

In actuality, the PUSH_PROMISE frame is sent on the client-initiated, bidirectional stream that carried the request that generated the push. I think thats the only form allowed (i.e. you can't send PUSH_PROMISE on a server-initiated unidirectional or bidirectional stream. I might be arguing now that the current definition is **not strict enough** in mandating on what streams PUSH_PROMISE can be sent on.

Once that gets clarified, I think the idea of sending PUSH_PROMISE on server-initiated unidirectional streams (the control stream to name one) falls outside the general case but may help special use cases. Would there be aversion to a HTTP/QUIC extension that modifies semantics to allow such use cases?

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/issues/947#issuecomment-346427757

---

From: Mike Bishop <[email-masked]>
Date: Thu, 23 Nov 2017 11:48:32 +0000 (UTC)

Closed #947 via #957.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/issues/947#event-1355651230