Stub out priority
This commit is contained in:
@@ -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
|
||||
};
|
||||
|
||||
@@ -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
83
src/frame/priority.rs
Normal 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
|
||||
}
|
||||
}
|
||||
@@ -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");
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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());
|
||||
|
||||
Reference in New Issue
Block a user