Subject: Re: Questions on Server Push

From: Martin Thomson <[email-masked]>
Date: Mon, 3 Jun 2013 09:05:45 -0700

On 31 May 2013 02:59, Shigeki Ohtsu <[email-masked]> wrote:
> In the above B case, FINAL flag cannot be set in HEADERS+PRIORITY so
>  we need to know it at first to distinguish the case A.

This isn't quite right.  Only the stream from the server to the client
(the response stream) needs to be open in order to send PUSH_PROMISE.

Note also that your example doesn't show that the pushed resource is
on a different stream to original request.  e.g.:

1. Client -> HEADERS+PRIORITY(Get Request)  -> Server (stream 1)
2. Client <- PUSH_PROMISE <- Server (stream 1)
3. Client <- HEADER(Promised Response) <- Server (stream 2)
4. Client <- DATA(Promised Response) with FINAL <- Server (stream 2)
5. Client <- HEADER(Response) <- Server (stream 1)
6. Client <- DATA with FINAL(Response) <-Server (stream 1)

Also, the ordering isn't strictly this way.  Steps 3,4 and 5,6 can be
interleaved in any order.  The only constraint is that step 6 (the one
containing the FINAL for stream 1) comes after step 2.

> Q3: In above case, no stream was created before step 5 so that
> PUSH_PROMISE was sent on a new stream. This is forbidden in the spec.

This is a case that we haven't completely resolved yet.  My
expectation is that we will define something like: the pre-Upgrade
request implicitly opens stream 1.   See
https://github.com/http2/http2-spec/issues/52

---

From: Martin Thomson <[email-masked]>
Date: Mon, 3 Jun 2013 17:07:58 -0700

On 3 June 2013 17:02, Shigeki Ohtsu <[email-masked]> wrote:
> then  PUSH_PROMISE on step2 seemed to be sent from server on the
> half-closed stream 1. Do we need to change the spec so as to permit
> to send PUSH_PROMISE on a half-closed stream?

Half-closed is directional.  You can't send on a stream that is
half-closed in the direction you are sending, but you can send on the
open half.  If it weren't directional, the server couldn't send a
response.

> We would be glad if you add some notes about this after
> "After sending a PUSH_PROMISE, the server commences transmission of a pushed
> resource."
> in 4.3.1.

Yes, this text isn't completely correct.  It may commence
transmission, but it can wait before starting.

> It might be also related to the description to be written about the stream
> lifecycles
> as noted on http://http2.github.io/http2-spec/#rfc.comment.5

Stream lifecycles are still a work in progress.  If you have any
specific suggestions, that would be helpful, but at this stage, I'm
not sure that we have a good agreement on what the basics are.
Anything that we "fix" now will probably change later.

--Martin

---

From: Mike Bishop <[email-masked]>
Date: Tue, 4 Jun 2013 00:09:18 +0000

Streams get half-closed from each side.  Stream 1 is half-closed by the client, not half-closed by the server.  A stream is closed when each side has half-closed.

Is there a wording clarification that would help make this plainer?

-----Original Message-----
From: Shigeki Ohtsu [mailto:[email-masked]] 
Sent: Monday, June 3, 2013 5:02 PM
To: Martin Thomson
Cc: HTTP Working Group
Subject: Re: Questions on Server Push

Thanks for your answer. Please let me clarify it.

> (the response stream) needs to be open in order to send PUSH_PROMISE.

In 4.3.1 Server implementation, it says that "A server cannot send a PUSH_PROMISE on a new stream or a half-closed stream."

If the following is permitted

  1. Client -> HEADERS+PRIORITY with FINAL (Get Request) -> Server (stream 1)
(stream1 is half-closed)
(stream1 is full-closed)

then  PUSH_PROMISE on step2 seemed to be sent from server on the half-closed stream 1. Do we need to change the spec so as to permit to send PUSH_PROMISE on a half-closed stream?

> containing the FINAL for stream 1) comes after step 2.

This was the another question that came into my mind, but I wrote the example
  to follow the current SPDY case. It was solved, thanks.

We would be glad if you add some notes about this after "After sending a PUSH_PROMISE, the server commences transmission of a pushed resource."
in 4.3.1.

It might be also related to the description to be written about the stream lifecycles as noted on http://http2.github.io/http2-spec/#rfc.comment.5

> https://github.com/http2/http2-spec/issues/52

Thanks, I missed to find the issue.
It would be nice to have the first implicit client-initiated stream
  which has a default priority. The sequence would be

1. Client -> Get Request(HTTP/1.1) with Upgrade -> Server (open implicit stream 1 with a default priority) 2. Client <- 101 Switch Protocol Response <- Server 3. Client <- Connection Header + SETTINGS <- Server 4. Client -> Connection Header + SETTINGS -> Server 5. Client <- PUSH_PROMISE <- Server (implicit stream 1) 6. Client <- HEADER(Promised Response) <- Server (stream 2) 7. Client <- DATA(Promised Response) with FINAL <- Server (stream 2) 8. Client <- HEADER(Response) <- Server (implicit stream 1) 9. Client <- DATA with FINAL(Response) <-Server (implicit stream 1)

Regards,

---

From: Shigeki Ohtsu <[email-masked]>
Date: Tue, 04 Jun 2013 09:35:45 +0900

> Is there a wording clarification that would help make this plainer?

I think that "A server cannot send a PUSH_PROMISE on a half-closed stream"
seems to be rather a superfluous description because in  3.4.3 "Subsequent frames
MUST NOT be sent by that endpoint for the half closed stream for the remaining
duration of the HTTP/2.0 connection." so that not only PUSH_PROMISE but also
any other frames cannot be sent on a half-closed stream in that case.

---

From: Shigeki Ohtsu <[email-masked]>
Date: Tue, 04 Jun 2013 09:02:19 +0900

> (the response stream) needs to be open in order to send PUSH_PROMISE.

In 4.3.1 Server implementation, it says that
"A server cannot send a PUSH_PROMISE on a new stream or a half-closed stream."

We would be glad if you add some notes about this after
"After sending a PUSH_PROMISE, the server commences transmission of a pushed resource."
in 4.3.1.

It might be also related to the description to be written about the stream lifecycles
as noted on http://http2.github.io/http2-spec/#rfc.comment.5

1. Client -> Get Request(HTTP/1.1) with Upgrade -> Server
(open implicit stream 1 with a default priority)
2. Client <- 101 Switch Protocol Response <- Server
3. Client <- Connection Header + SETTINGS <- Server
4. Client -> Connection Header + SETTINGS -> Server
5. Client <- PUSH_PROMISE <- Server (implicit stream 1)
6. Client <- HEADER(Promised Response) <- Server (stream 2)
7. Client <- DATA(Promised Response) with FINAL <- Server (stream 2)
8. Client <- HEADER(Response) <- Server (implicit stream 1)
9. Client <- DATA with FINAL(Response) <-Server (implicit stream 1)

Regards,

---

From: Shigeki Ohtsu <[email-masked]>
Date: Tue, 04 Jun 2013 09:23:52 +0900

> open half.  If it weren't directional, the server couldn't send a

Oh, I understood. I thought "a half-closed stream" means the state of stream
where either endpoint has already sent the FINAL.

The spec means that "A server cannot send a PUSH_PROMISE on a new stream or a half-closed
stream (on which FINAL has already sent from the server)."

Thanks.