Subject: INVALID_STREAM and STREAM_ALREADY_CLOSED

From: Martin Thomson <[email-masked]>
Date: Tue, 26 Mar 2013 11:23:39 -0700

Another error code question.

INVALID_STREAM indicates that a frame arrived for an "inactive" stream.

STREAM_ALREADY_CLOSED indicates that a frame arrived for a (half-)closed stream.

Both are unexpected frames.  My first inclination was to suggest
(again) that a single error code was appropriate.

However, if I read between the lines, INVALID_STREAM is as a result of
getting a frame prior to the first 'official' frame in the stream
(i.e., SYN_STREAM).  But the general design doesn't require that a
stream starts with any particular frame.

So I conclude that it only makes sense to have STREAM_ALREADY_CLOSED.

---

From: Roberto Peon <[email-masked]>
Date: Tue, 26 Mar 2013 12:34:35 -0700

imho: Seems reasonable for now.
I expect that we'll expand the error codes as more implementors find error
conditions that they want to be able to debug from a client debug
information, at which point we can re-add any of this.

-=R

---

From: William Chan (陈智昌) <[email-masked]>
Date: Tue, 26 Mar 2013 12:58:05 -0700

We used INVALID_STREAM to indicate the client received a SYN_STREAM with an
associated stream id that does not exist. Maybe we should just terminate
the session.

STREAM_ALREADY_CLOSED can be confusing since peers don't necessarily know
that it's already closed unless we maintain the set of old closed stream
ids. And what if we receive DATA frames for non-existent streams? I guess
we shouldn't RST_STREAM a non-existent stream, since the stream id is
invalid.

On Tue, Mar 26, 2013 at 12:34 PM, Roberto Peon <[email-masked]> wrote:

> On Tue, Mar 26, 2013 at 11:23 AM, Martin Thomson <[email-masked]
> > wrote:
>

---

From: Martin Thomson <[email-masked]>
Date: Tue, 26 Mar 2013 13:34:00 -0700

On 26 March 2013 12:58, William Chan (陈智昌) <[email-masked]> wrote:
> associated stream id that does not exist. Maybe we should just terminate the
> session.

There are five potential scenarios, all based on the highest stream
identifier already seen:

1. Message with a stream ID that is higher than the last stream
identifier by more than 2.
Conclusion: No real problem here, just a few gaps in the chain that
mean less efficient use fo .

2. Message with a stream ID that is lower (or equal to) the highest
stream identifier.  That stream is still open.
Conclusion: No problem, that's normal operation.

3. Message with a stream ID that is lower (or equal to) the highest
stream identifier.  That stream is (half-)closed.
Conclusion: STREAM_ALREADY_CLOSED.

4. Client generates a frame with an even numbered stream ID/server
uses an odd stream ID. That stream hasn't been used by the peer yet.
Conclusion: The sender of this frame is supposed to wait for its peer
to send before using those streams.  This might warrant a separate
error code.  Is this what INVALID_STREAM is intended to cover?
Exception: RST_STREAM needs to be valid here to allow PUSH_PROMISE to
work properly.

5. Client generates a frame with an even numbered stream ID/server
uses an odd stream ID. That stream ID has already been used.
Conclusion: No problem, that's called a reply - normal operation.

> ids.

I never imagined that this would be the case:  If you track open
streams, as you must, all streams that you aren't tracking are closed
if they have an ID lower than the highest tracked stream ID.

> And what if we receive DATA frames for non-existent streams? I guess we
> shouldn't RST_STREAM a non-existent stream, since the stream id is invalid.

Be very clear here.  I like to think of streams as having three
states: unused, active, and closed.  (Note that you might consider
these states to apply separately in both directions.)  What states
correspond to 'non-existent'?  How does one convey an invalid stream
ID?

> information, at which point we can re-add any of this.

That is very much true..

---

From: William Chan (陈智昌) <[email-masked]>
Date: Tue, 26 Mar 2013 14:08:35 -0700

On Tue, Mar 26, 2013 at 1:34 PM, Martin Thomson <[email-masked]>wrote:

> the

No real problem, but unexpected and probably undesirable. Any reason to
allow this behavior? Should we make it a session error? Is that overly
strict?

> Conclusion: STREAM_ALREADY_CLOSED.

Does the receiver need to keep the stream in its data structures after it's
closed? It's kind of nice just to throw state away ASAP. But you need that
state around to identify it as already closed.

> Exception: RST_STREAM needs to be valid here to allow PUSH_PROMISE to

This is one reason for an invalid stream. What about the associated to
stream id in a PUSH_PROMISE?

> Conclusion: No problem, that's called a reply - normal operation.

Not normal if that stream has already been closed.

> if they have an ID lower than the highest tracked stream ID.

I thought we had a reason why this didn't work, but I do not recall it, so
I'm going to believe you are right here.

> correspond to 'non-existent'?  How does one convey an invalid stream

I was thinking unused.