Subject: PUSH_PROMISE at invalid times

From: Tatsuhiro Tsujikawa <[email-masked]>
Date: Sat, 17 Aug 2013 22:06:50 +0900

In draft-05, new restriction was introduced for
PUSH_PROMISE.

'''

Since PUSH_PROMISE reserves a stream, ignoring a PUSH_PROMISE frame
   causes the stream state to become indeterminate.  A receiver MUST
   treat the receipt of a PUSH_PROMISE on a stream that is neither
   "open" nor "half-closed (local)" as a connection error
   (Section 5.4.1
<http://tools.ietf.org/html/draft-ietf-httpbis-http2-05#section-5.4.1>)
of type PROTOCOL_ERROR.  Similarly, a receiver MUST
   treat the receipt of a PUSH_PROMISE that promises an illegal stream
   identifier (Section 5.1.1
<http://tools.ietf.org/html/draft-ietf-httpbis-http2-05#section-5.1.1>)
(that is, an identifier for a stream that
   is not currently in the "idle" state) as a connection error
   (Section 5.4.1
<http://tools.ietf.org/html/draft-ietf-httpbis-http2-05#section-5.4.1>)
of type PROTOCOL_ERROR.

"""

I agree that PUSH_PROMISE with illegal stream identifier or PUSH_PROMISE

after the remote endpoint sent a frame with END_STREAM are

treated as connection error of type PROTOCOL_ERROR.

But treating the other cases as connection error is problematic.
This is because the local endpoint think that stream was closed
(e.g., by sending RST_STREAM), but the remote endpoint may
not know that closure of the stream when it sent PUSH_PROMISE.
And according to the spec, the local endpoint must treat
this incoming PUSH_PROMISE as connection error, which is a
bit hard for me. This makes PUSH_PROMISE unreliable.
The alternative approach is always process PUSH_PROMISE
and its header block, thus changes stream state and compression
state. After that if the receiver thinks that it should be rejected,
then issue RST_STREAM to the promised stream ID.

Best regards,

Tatsuhiro Tsujikawa

---

From: Martin Thomson <[email-masked]>
Date: Mon, 19 Aug 2013 09:47:46 -0700

> then issue RST_STREAM to the promised stream ID.

We've made it a general policy that we'll be really harsh on badly
behaving implementations.  Being tolerant of rubbish just hides
implementation issues.  We've all seen how much damage has done to
HTTP/1.1.

In this case, the only thing that is missing - at least in the cited
text - is another mention that it is possible that you can receive a
PUSH_PROMISE after sending RST_STREAM.  That's already in the stream
states section, but there's no mention in the PUSH_PROMISE section
that was added.

---

From: Tatsuhiro Tsujikawa <[email-masked]>
Date: Wed, 21 Aug 2013 00:24:52 +0900

> states section, but there's no mention in the PUSH_PROMISE section

I totally agree to punish broken implementations. I've written many network
applications and those broken ones always bother me a lot.
My point is the interactions between fully compliant implementations which
is PUSH_PROMISE after sending RST_STREAM. Sorry if my original post is not
clear about it.
I saw a commit to address this issue, so my concern is completely cleared.
Thank you very much!

Best regards,

Tatsuhiro Tsujikawa