Re: Push Promise Issues

I didn't comment on any editorial stuff because I suck at it, but fwiw I
agree with your points on all the areas that can/should be clarified.

On Wed, Apr 24, 2013 at 9:35 AM, James M Snell <jasnell@gmail.com> wrote:

> 1. The process for rejecting a promised stream needs to be clarified.
> Right now, section 3.7.5 says, "The PUSH_PROMISE allows the client an
> opportunity to reject pushed resources." but does not say any thing
> about how such rejection occurs, etc. It's not until section 4.3.2
> that the CANCEL mechanism is briefly described. As an editorial
> suggestion, including a forward reference to section 4.3.2. in section
> 3.7.5 would be helpful.
>
> The rejection process described in section 4.3.2 is not very clear and
> has a number of issues. The current spec language says:
>
>   To cancel individual server push streams, the
>   client can issue a stream error (Section 3.5.2)
>   of type CANCEL.  Upon receipt, the server
>   ceases transmission of the pushed data...


>   To cancel all server push streams related to a
>   request, the client may issue a stream error
>   (Section 3.5.2) of type CANCEL on the
>   associated-stream-id.  By cancelling that stream,
>   the server MUST immediately stop sending frames
>   for any streams with in-association-to for the original
>   stream.
>
> The way this is worded, the implication is that the client is
> cancelling a promised stream that is already in the process of being
> transmitted. It's not clear that this is also how a client is to
> reject a promised stream *before* transmission begins. Also, it needs
> to be made clear that the stream error needs to specify the identifier
> of the promised stream and not the associated promising stream.


> That is, for example, if stream 1 includes push_promises for streams 3
> and 5, and the client wishes to reject only stream 3, it sends an
> RST_STREAM for stream 3.
>
> 2. If the client is rejecting the promised stream, the error code used
> in the RST_STREAM ought to be REFUSED_STREAM and not CANCEL.
>

Can you explain why? It's not clear to me how a server would handle them
differently. I do see that the client may be able to indicate that it has
not processed the stream at all, but I'm not sure that matters. On the
other hand, I think it's useful in the opposite direction to use
REFUSED_STREAM to indicate that it's safe for the client to retry the
request. I think there's an editorial issue to clarify that in the spec (
https://github.com/http2/http2-spec/issues/57).


>
> 3. How long should a client wait for the transmission of a promised
> stream? Is there some reasonable timeout? Should the client simply
> issue a CANCEL if it feels the stream hasn't been received in a
> reasonable period of time? If so, that needs to be described.
>

I'm not sure this is any different from how long a client would wait for a
SYN_REPLY (oops, I mean the HEADERS frame). My client (Chromium) will not
time out, but that's up to the client. Typically users will reload the page
which will trigger cancellations and resending of a HEADERS+PRIORITY frame.
We may also use PING frames for liveness detection, but that would lead us
to terminate the entire session.


>
> 4. In 4.3.1 it is mentioned that the PUSH_PROMISE must include the
> :scheme, :host and :port headers. In section 4.3.2, it says :scheme,
> :host and :path. I assume that's just a typo in section 4.3.1.
>
> 5. Section 4.3.1 says that the PUSH_PROMISE SHOULD include header
> fields that allow a cache to determine if the resource is already
> cached... It should specifically call out a number of headers such as
> content-type, etag and last-modified.
>
> 6. The last paragraph in section 4.3.2 dealing with the mixing of
> headers frames and data frames ought to be removed. This really has
> nothing to do with Server push and the question of whether we should
> allow intermingling of those frame types is still an open question.
>
> 7. Whether or not a client can send a PUSH_PROMISE to the server needs
> to be determined. One can easily envision a use case where a client
> wishes to send multiple simultaneous streams to a server. For
> instance, sending a PUT or POST to a server that has multiple payloads
> (uploading more than one picture or video at a time, for instance).
> While such a use case is not currently covered by HTTP/1 semantics,
> the new framing layer makes such cases possible and we need to decide
> now whether or not we are going to allow it.
>

> For example,
>
> A. Client creates a stream to the server with :method=POST, includes
> two PUSH_PROMISE frames for two images it wishes to upload...
> B. Client sends each image in separate streams with their own HEADERS
> frame.
>

I'm sleep deprived and still confused this morning, but I don't grok this
one. Can you explain why a client would send a PUSH_PROMISE rather than a
SYN_STREAM (er, a HEADERS+PRIORITY, god my brain still needs to wrap around
these new names) frame? PUSH_PROMISE exists to prevent races (having the
peer request the resource at the same time that the sender is trying to
push it). I don't see how the race exists in the client=>server direction
with HTTP semantics, although I can imagine a non-HTTP semantic layering
atop the framing layer that might have this race.


>
> Another case, dealing with the age-old problem of uploading a media
> resource and it's associated metadata in a single operation (currently
> implemented in many apis as a clumsy MIME package):
>
> A. Client creates a stream to the server with :method=PUT, includes
> two PUSH_PROMISE frames, one for the image, the other for metadata
> about the image.
> B. Client sends each part in separate streams with their own HEADERS frame.
>
> In my opinion, these are very compelling use cases that need to be
> carefully considered. If clients are allowed to send PUSH_PROMISE
> frames, we need to mention it.
>
> Possibly more later...
>
> - James
>
>

Received on Wednesday, 24 April 2013 17:26:22 UTC