Add stream_id accessors to public API types (#292)

Problem:

Applications may want to access the underlying h2 stream ID for
diagnostics, etc. Stream IDs were not previously exposed in public APIs.

Solution:

Added a new public `share::StreamId` type, which has a more restricted 
API than the internal `frame::StreamId` type. The public API types 
`SendStream`, `RecvStream`, `ReleaseCapacity`, 
`client::ResponseFuture`, and `server::SendResponse` now all have 
`stream_id` methods which return the stream ID of the corresponding 
stream.

Closes #289.

Signed-off-by: Eliza Weisman <eliza@buoyant.io>
This commit is contained in:
Eliza Weisman
2018-07-12 21:01:57 -07:00
committed by GitHub
parent 41aae14c64
commit f3806d5144
6 changed files with 101 additions and 1 deletions

View File

@@ -1,6 +1,16 @@
use byteorder::{BigEndian, ByteOrder};
use std::u32;
/// A stream identifier, as described in [Section 5.1.1] of RFC 7540.
///
/// Streams are identified with an unsigned 31-bit integer. Streams
/// initiated by a client MUST use odd-numbered stream identifiers; those
/// initiated by the server MUST use even-numbered stream identifiers. A
/// stream identifier of zero (0x0) is used for connection control
/// messages; the stream identifier of zero cannot be used to establish a
/// new stream.
///
/// [Section 5.1.1]: https://tools.ietf.org/html/rfc7540#section-5.1.1
#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub struct StreamId(u32);
@@ -10,8 +20,10 @@ pub struct StreamIdOverflow;
const STREAM_ID_MASK: u32 = 1 << 31;
impl StreamId {
/// Stream ID 0.
pub const ZERO: StreamId = StreamId(0);
/// The maximum allowed stream ID.
pub const MAX: StreamId = StreamId(u32::MAX >> 1);
/// Parse the stream ID
@@ -25,25 +37,34 @@ impl StreamId {
(StreamId(unpacked & !STREAM_ID_MASK), flag)
}
/// Returns true if this stream ID corresponds to a stream that
/// was initiated by the client.
pub fn is_client_initiated(&self) -> bool {
let id = self.0;
id != 0 && id % 2 == 1
}
/// Returns true if this stream ID corresponds to a stream that
/// was initiated by the server.
pub fn is_server_initiated(&self) -> bool {
let id = self.0;
id != 0 && id % 2 == 0
}
/// Return a new `StreamId` for stream 0.
#[inline]
pub fn zero() -> StreamId {
StreamId::ZERO
}
/// Returns true if this stream ID is zero.
pub fn is_zero(&self) -> bool {
self.0 == 0
}
/// Returns the next stream ID initiated by the same peer as this stream
/// ID, or an error if incrementing this stream ID would overflow the
/// maximum.
pub fn next_id(&self) -> Result<StreamId, StreamIdOverflow> {
let next = self.0 + 2;
if next > StreamId::MAX.0 {