Stub out priority

This commit is contained in:
Carl Lerche
2017-08-10 23:17:21 -07:00
parent c439232ed2
commit 23b2ef49cc
6 changed files with 110 additions and 26 deletions

View File

@@ -1,4 +1,4 @@
use super::StreamId;
use super::{StreamId, StreamDependency};
use hpack;
use frame::{self, Frame, Head, Kind, Error};
use HeaderMap;
@@ -66,20 +66,6 @@ pub struct Continuation {
headers: Iter,
}
#[derive(Debug)]
pub struct StreamDependency {
/// The ID of the stream dependency target
stream_id: StreamId,
/// The weight for the stream. The value exposed (and set) here is always in
/// the range [0, 255], instead of [1, 256] (as defined in section 5.3.2.)
/// so that the value fits into a `u8`.
weight: u8,
/// True if the stream dependency is exclusive.
is_exclusive: bool,
}
#[derive(Debug, Default)]
pub struct Pseudo {
// Request
@@ -145,20 +131,16 @@ impl Headers {
// Read the stream dependency
let stream_dep = if flags.is_priority() {
// Parse the stream ID and exclusive flag
let (stream_id, is_exclusive) = StreamId::parse(&src[..4]);
let stream_dep = StreamDependency::load(&src[..5])?;
// Read the weight
let weight = src[4];
if stream_dep.dependency_id() == head.stream_id() {
return Err(Error::InvalidDependencyId);
}
// Drop the next 5 bytes
let _ = src.split_to(5);
Some(StreamDependency {
stream_id,
weight,
is_exclusive,
})
Some(stream_dep)
} else {
None
};

View File

@@ -32,6 +32,7 @@ mod go_away;
mod head;
mod headers;
mod ping;
mod priority;
mod reset;
mod settings;
mod stream_id;
@@ -43,6 +44,7 @@ pub use self::go_away::GoAway;
pub use self::head::{Head, Kind};
pub use self::headers::{Headers, PushPromise, Continuation, Pseudo};
pub use self::ping::Ping;
pub use self::priority::{Priority, StreamDependency};
pub use self::reset::Reset;
pub use self::settings::{Settings, SettingSet};
pub use self::stream_id::StreamId;
@@ -59,6 +61,7 @@ pub const HEADER_LEN: usize = 9;
pub enum Frame<T = Bytes> {
Data(Data<T>),
Headers(Headers),
Priority(Priority),
PushPromise(PushPromise),
Settings(Settings),
Ping(Ping),
@@ -98,6 +101,7 @@ impl<T> fmt::Debug for Frame<T> {
match *self {
Data(..) => write!(fmt, "Frame::Data(..)"),
Headers(ref frame) => write!(fmt, "Frame::Headers({:?})", frame),
Priority(ref frame) => write!(fmt, "Frame::Priority({:?})", frame),
PushPromise(ref frame) => write!(fmt, "Frame::PushPromise({:?})", frame),
Settings(ref frame) => write!(fmt, "Frame::Settings({:?})", frame),
Ping(ref frame) => write!(fmt, "Frame::Ping({:?})", frame),
@@ -153,6 +157,12 @@ pub enum Error {
/// identifier other than zero.
InvalidStreamId,
/// An invalid stream dependency ID was provided
///
/// This is returend if a HEADERS or PRIORITY frame is received with an
/// invalid stream identifier.
InvalidDependencyId,
/// Failed to perform HPACK decoding
Hpack(hpack::DecoderError),
}

83
src/frame/priority.rs Normal file
View File

@@ -0,0 +1,83 @@
use frame::*;
#[derive(Debug)]
pub struct Priority {
stream_id: StreamId,
dependency: StreamDependency,
}
#[derive(Debug)]
pub struct StreamDependency {
/// The ID of the stream dependency target
dependency_id: StreamId,
/// The weight for the stream. The value exposed (and set) here is always in
/// the range [0, 255], instead of [1, 256] (as defined in section 5.3.2.)
/// so that the value fits into a `u8`.
weight: u8,
/// True if the stream dependency is exclusive.
is_exclusive: bool,
}
impl Priority {
pub fn load(head: Head, payload: &[u8]) -> Result<Self, Error> {
let dependency = StreamDependency::load(payload)?;
if dependency.dependency_id() == head.stream_id() {
return Err(Error::InvalidDependencyId);
}
Ok(Priority {
stream_id: head.stream_id(),
dependency: dependency,
})
}
}
impl<B> From<Priority> for Frame<B> {
fn from(src: Priority) -> Self {
Frame::Priority(src)
}
}
// ===== impl StreamDependency =====
impl StreamDependency {
pub fn new(dependency_id: StreamId, weight: u8, is_exclusive: bool) -> Self {
StreamDependency {
dependency_id,
weight,
is_exclusive,
}
}
pub fn load(src: &[u8]) -> Result<Self, Error> {
if src.len() != 5 {
return Err(Error::InvalidPayloadLength);
}
// Parse the stream ID and exclusive flag
let (dependency_id, is_exclusive) = StreamId::parse(&src[..4]);
// Read the weight
let weight = src[4];
Ok(StreamDependency::new(
dependency_id,
weight,
is_exclusive))
}
pub fn dependency_id(&self) -> StreamId {
self.dependency_id
}
pub fn weight(&self) -> u8 {
self.weight
}
pub fn is_exclusive(&self) -> bool {
self.is_exclusive
}
}

View File

@@ -142,6 +142,10 @@ impl<T, P, B> Connection<T, P, B>
trace!("recv WINDOW_UPDATE; frame={:?}", frame);
self.streams.recv_window_update(frame)?;
}
Some(Priority(frame)) => {
trace!("recv PRIORITY; frame={:?}", frame);
// TODO: handle
}
None => {
// TODO: Is this correct?
trace!("codec closed");

View File

@@ -108,8 +108,7 @@ impl<T> FramedRead<T> {
frame::PushPromise::load(head, &bytes[frame::HEADER_LEN..])?.into()
}
Kind::Priority => {
// TODO: implement
return Ok(None);
frame::Priority::load(head, &bytes[frame::HEADER_LEN..])?.into()
}
Kind::Continuation => {
// TODO: Un-hack this

View File

@@ -153,6 +153,12 @@ impl<T, B> Sink for FramedWrite<T, B>
v.encode(self.buf.get_mut());
trace!("encoded window_update; rem={:?}", self.buf.remaining());
}
Frame::Priority(v) => {
// v.encode(self.buf.get_mut());
trace!("encoded priority; rem={:?}", self.buf.remaining());
unimplemented!();
}
Frame::Reset(v) => {
v.encode(self.buf.get_mut());
trace!("encoded reset; rem={:?}", self.buf.remaining());