quicwg / base-drafts Public
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Can PUSH_PROMISE rules be relaxed to allow sending on a control stream? #947
Comments
|
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. |
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 request? (Edited: fixed typo where I used push instead of request). |
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. This avoids a race where clients issue requests prior to receiving any PUSH_PROMISE frames". 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. |
|
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. |
|
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 and header fields are preferred). Request/response is also great for implementations that like to minimise state. The great replies from @MikeBishop on other issues I've raised have also given me greater insight to this section. Where is says:
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? |
Reading the latest HTTP/QUIC editor's copy. Section 4.4 on server push states that:
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.
The text was updated successfully, but these errors were encountered: