Design Issue: Life-cycle of a Stream

James M Snell <> Wed, 01 May 2013 17:06 UTC

Return-Path: <>
Received: from localhost (localhost []) by (Postfix) with ESMTP id 28D2121F9A7C for <>; Wed, 1 May 2013 10:06:18 -0700 (PDT)
X-Virus-Scanned: amavisd-new at
X-Spam-Flag: NO
X-Spam-Score: -10.558
X-Spam-Status: No, score=-10.558 tagged_above=-999 required=5 tests=[AWL=0.041, BAYES_00=-2.599, RCVD_IN_DNSWL_HI=-8]
Received: from ([]) by localhost ( []) (amavisd-new, port 10024) with ESMTP id ngtVRlOVz9Zc for <>; Wed, 1 May 2013 10:06:03 -0700 (PDT)
Received: from ( []) by (Postfix) with ESMTP id 344EC21F99BA for <>; Wed, 1 May 2013 10:06:03 -0700 (PDT)
Received: from lists by with local (Exim 4.72) (envelope-from <>) id 1UXaST-0001Q4-Bf for; Wed, 01 May 2013 17:04:45 +0000
Resent-Date: Wed, 01 May 2013 17:04:45 +0000
Resent-Message-Id: <>
Received: from ([]) by with esmtp (Exim 4.72) (envelope-from <>) id 1UXaSH-0001NM-Cm for; Wed, 01 May 2013 17:04:33 +0000
Received: from ([]) by with esmtps (TLS1.0:RSA_ARCFOUR_SHA1:16) (Exim 4.72) (envelope-from <>) id 1UXaSG-0005Hl-Ea for; Wed, 01 May 2013 17:04:33 +0000
Received: by with SMTP id v19so1456192obq.3 for <>; Wed, 01 May 2013 10:04:06 -0700 (PDT)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;; s=20120113; h=x-received:mime-version:from:date:message-id:subject:to :content-type; bh=g1rYrfStEFXigEvyvND8mIPpIJHK+d2zKipTkqVXniQ=; b=xFQKBbGO+SwK2ZhiLn+3hhIMcJ7I15Wc6wSqfwK1Nrb/wqUqsGstzoacY1RBOddX74 nogQCwJk5nTIhhLLtdd7pkgnwGF3gURXKEJ6DPQEv/c6/Zu++3TbspIr8ZESRYU0U4Pk 5TFYjIADE3RnD+rvgDrOdvmImkSU+lQKFraOyWISDyLdPvzAprNPJlT53q7Cpb6SI6Pd 5v0DM61njt4yVxx3Dq9OXSls4trluhJekgqibdMZzyOidWHbK+Ersn5PUpEFEBRMXQn9 j6WMj+v0RtlQPiP7O6gn9uO6qVdkvKZMsIdxtcastNSbEOWvQhxKSKZc2s5FZT5hcXfk g26Q==
X-Received: by with SMTP id zc10mr837083obb.80.1367427845636; Wed, 01 May 2013 10:04:05 -0700 (PDT)
MIME-Version: 1.0
Received: by with HTTP; Wed, 1 May 2013 10:03:45 -0700 (PDT)
From: James M Snell <>
Date: Wed, 1 May 2013 10:03:45 -0700
Message-ID: <>
To: "" <>
Content-Type: text/plain; charset=UTF-8
Received-SPF: pass client-ip=;;
X-W3C-Hub-Spam-Status: No, score=-3.5
X-W3C-Hub-Spam-Report: AWL=-2.700, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_LOW=-0.7, SPF_PASS=-0.001
X-W3C-Scan-Sig: 1UXaSG-0005Hl-Ea 6fb5c1b7a37e4d646ca3714c02aac4c9
Subject: Design Issue: Life-cycle of a Stream
Archived-At: <>
X-Mailing-List: <> archive/latest/17763
Precedence: list
List-Id: <>
List-Help: <>
List-Post: <>
List-Unsubscribe: <>

The current spec is rather vague on the complete life-cycle of a
stream within a session. Aside from discussing how the Mommy Endpoint
and the Daddy Endpoint get together, we ought to take just a bit of
time to make sure we're all on the same page...

In a separate thread, several of us discussed stream creation...
specifically, how is a stream initiated. Let's see if we can formalize
the process and the language. I've written the following out as
statements, if you disagree with the statement or see it a different
way, lemme know! Some of this is obvious and well established, I'm
documenting it here just to make sure we have the complete picture
captured. I've marked the items that appear to me to be the most
controversial with an asterisk.

1. Streams are initialized or opened by sending a HEADERS or
HEADERS+PRIORITY frame that uses a previously unused stream

2. Only HEADERS and HEADERS+PRIORITY frames are used to open a stream.

3. PUSH_PROMISE frames reserve a stream identifier but do not open the stream.

4. Promised streams are only opened by sending a subsequent HEADERS or
HEADERS+PRIORITY frame that uses the reserved stream identifier.

5. All streams are either fully open, half-closed by the client,
half-closed by the server, or fully closed.

6. All promised streams are associated with an originating "parent" stream.

7. A stream is half-closed by sending a frame with the FINAL bit set.

8. A stream becomes fully-closed when either: a) both endpoints send
frames with the FINAL bit set or b) either endpoint sends an RST_FRAME
with that streams identifier.

9*. Promised streams are automatically half-closed for the recipient.
That is, when the server sends a PUSH_PROMISE to a client, that
streams becomes automatically half-closed for the client. The only
frame the client can send back to the server for that stream are
RST_STREAM frames.

  -- or --

9*. Promised streams are handled just like regular streams. The server
opens the stream and half-closes. The stream does not fully close
until either the client half-closes it or a RST_STREAM frame is sent
for that stream.

10*. Sending an RST_FRAME for a parent stream fully closes that stream
as well as all associated promised streams.

  -- or --

10*. Sending an RST_FRAME for a parent stream only closes that stream
and has no affect on associated promised streams.

11*. Fully closing a parent stream using symmetric half-closes will
fully close all associated promised streams.

  -- or --

11*. Fully closing a parent stream using symmetric half-closes has no
affect on associated promised streams.

12. Half or fully closing a promised stream has no impact on the
parent stream or any associated sibling promised streams.

Ok, so that covers the lifecycle.. let's talk about processing.. this
is largely a reiteration of my previous note on this but I want to
make sure I've hit all the major points in how this is categorized.

Tier 1: Includes the following...

A. Reception and basic parsing of frames. "Basic parsing" here means
looking at the header bytes to determine the frame type, making note
of the flags, frame size and stream identifier, and performing any
necessary header block decompression and state management.

B. Handling of all session frames (stream id #0). This means that
upgrade negotiation, SETTINGS, PING, flow control and session level
error handling are all Tier 1 processes.

C. Basic lifecycle handling of stream frames. This includes
determination of whether a stream is open or closed, whether or not
additional frames are allowed for a stream, validation of proper
stream id use, reservation of stream id's with push_promise, and
handling of the FINAL flag.

Tier 2: Includes the following...

A. Frame-type specific processing. Validation and handling of frame
payloads and frame-specific flags, not including header block
processing (which is tier 1)

B. Additional stream-level error handling not related to stream-lifecycle

Tier 3: Includes all application-level handling (HTTP Semantics)

So, when we say things like "an endpoint must be prepared to continue
receiving frames on a closed stream", we mean to say that "an endpoint
must be prepared to do tier 1 processing on all frames, even those
sent for closed streams."

Please weigh in on whatever items y'all feel are controversial. I'll
work up proposed spec edits based on whatever feedback is received.

- James