Stub out priority
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
use super::StreamId;
|
use super::{StreamId, StreamDependency};
|
||||||
use hpack;
|
use hpack;
|
||||||
use frame::{self, Frame, Head, Kind, Error};
|
use frame::{self, Frame, Head, Kind, Error};
|
||||||
use HeaderMap;
|
use HeaderMap;
|
||||||
@@ -66,20 +66,6 @@ pub struct Continuation {
|
|||||||
headers: Iter,
|
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)]
|
#[derive(Debug, Default)]
|
||||||
pub struct Pseudo {
|
pub struct Pseudo {
|
||||||
// Request
|
// Request
|
||||||
@@ -145,20 +131,16 @@ impl Headers {
|
|||||||
|
|
||||||
// Read the stream dependency
|
// Read the stream dependency
|
||||||
let stream_dep = if flags.is_priority() {
|
let stream_dep = if flags.is_priority() {
|
||||||
// Parse the stream ID and exclusive flag
|
let stream_dep = StreamDependency::load(&src[..5])?;
|
||||||
let (stream_id, is_exclusive) = StreamId::parse(&src[..4]);
|
|
||||||
|
|
||||||
// Read the weight
|
if stream_dep.dependency_id() == head.stream_id() {
|
||||||
let weight = src[4];
|
return Err(Error::InvalidDependencyId);
|
||||||
|
}
|
||||||
|
|
||||||
// Drop the next 5 bytes
|
// Drop the next 5 bytes
|
||||||
let _ = src.split_to(5);
|
let _ = src.split_to(5);
|
||||||
|
|
||||||
Some(StreamDependency {
|
Some(stream_dep)
|
||||||
stream_id,
|
|
||||||
weight,
|
|
||||||
is_exclusive,
|
|
||||||
})
|
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ mod go_away;
|
|||||||
mod head;
|
mod head;
|
||||||
mod headers;
|
mod headers;
|
||||||
mod ping;
|
mod ping;
|
||||||
|
mod priority;
|
||||||
mod reset;
|
mod reset;
|
||||||
mod settings;
|
mod settings;
|
||||||
mod stream_id;
|
mod stream_id;
|
||||||
@@ -43,6 +44,7 @@ pub use self::go_away::GoAway;
|
|||||||
pub use self::head::{Head, Kind};
|
pub use self::head::{Head, Kind};
|
||||||
pub use self::headers::{Headers, PushPromise, Continuation, Pseudo};
|
pub use self::headers::{Headers, PushPromise, Continuation, Pseudo};
|
||||||
pub use self::ping::Ping;
|
pub use self::ping::Ping;
|
||||||
|
pub use self::priority::{Priority, StreamDependency};
|
||||||
pub use self::reset::Reset;
|
pub use self::reset::Reset;
|
||||||
pub use self::settings::{Settings, SettingSet};
|
pub use self::settings::{Settings, SettingSet};
|
||||||
pub use self::stream_id::StreamId;
|
pub use self::stream_id::StreamId;
|
||||||
@@ -59,6 +61,7 @@ pub const HEADER_LEN: usize = 9;
|
|||||||
pub enum Frame<T = Bytes> {
|
pub enum Frame<T = Bytes> {
|
||||||
Data(Data<T>),
|
Data(Data<T>),
|
||||||
Headers(Headers),
|
Headers(Headers),
|
||||||
|
Priority(Priority),
|
||||||
PushPromise(PushPromise),
|
PushPromise(PushPromise),
|
||||||
Settings(Settings),
|
Settings(Settings),
|
||||||
Ping(Ping),
|
Ping(Ping),
|
||||||
@@ -98,6 +101,7 @@ impl<T> fmt::Debug for Frame<T> {
|
|||||||
match *self {
|
match *self {
|
||||||
Data(..) => write!(fmt, "Frame::Data(..)"),
|
Data(..) => write!(fmt, "Frame::Data(..)"),
|
||||||
Headers(ref frame) => write!(fmt, "Frame::Headers({:?})", frame),
|
Headers(ref frame) => write!(fmt, "Frame::Headers({:?})", frame),
|
||||||
|
Priority(ref frame) => write!(fmt, "Frame::Priority({:?})", frame),
|
||||||
PushPromise(ref frame) => write!(fmt, "Frame::PushPromise({:?})", frame),
|
PushPromise(ref frame) => write!(fmt, "Frame::PushPromise({:?})", frame),
|
||||||
Settings(ref frame) => write!(fmt, "Frame::Settings({:?})", frame),
|
Settings(ref frame) => write!(fmt, "Frame::Settings({:?})", frame),
|
||||||
Ping(ref frame) => write!(fmt, "Frame::Ping({:?})", frame),
|
Ping(ref frame) => write!(fmt, "Frame::Ping({:?})", frame),
|
||||||
@@ -153,6 +157,12 @@ pub enum Error {
|
|||||||
/// identifier other than zero.
|
/// identifier other than zero.
|
||||||
InvalidStreamId,
|
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
|
/// Failed to perform HPACK decoding
|
||||||
Hpack(hpack::DecoderError),
|
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);
|
trace!("recv WINDOW_UPDATE; frame={:?}", frame);
|
||||||
self.streams.recv_window_update(frame)?;
|
self.streams.recv_window_update(frame)?;
|
||||||
}
|
}
|
||||||
|
Some(Priority(frame)) => {
|
||||||
|
trace!("recv PRIORITY; frame={:?}", frame);
|
||||||
|
// TODO: handle
|
||||||
|
}
|
||||||
None => {
|
None => {
|
||||||
// TODO: Is this correct?
|
// TODO: Is this correct?
|
||||||
trace!("codec closed");
|
trace!("codec closed");
|
||||||
|
|||||||
@@ -108,8 +108,7 @@ impl<T> FramedRead<T> {
|
|||||||
frame::PushPromise::load(head, &bytes[frame::HEADER_LEN..])?.into()
|
frame::PushPromise::load(head, &bytes[frame::HEADER_LEN..])?.into()
|
||||||
}
|
}
|
||||||
Kind::Priority => {
|
Kind::Priority => {
|
||||||
// TODO: implement
|
frame::Priority::load(head, &bytes[frame::HEADER_LEN..])?.into()
|
||||||
return Ok(None);
|
|
||||||
}
|
}
|
||||||
Kind::Continuation => {
|
Kind::Continuation => {
|
||||||
// TODO: Un-hack this
|
// TODO: Un-hack this
|
||||||
|
|||||||
@@ -153,6 +153,12 @@ impl<T, B> Sink for FramedWrite<T, B>
|
|||||||
v.encode(self.buf.get_mut());
|
v.encode(self.buf.get_mut());
|
||||||
trace!("encoded window_update; rem={:?}", self.buf.remaining());
|
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) => {
|
Frame::Reset(v) => {
|
||||||
v.encode(self.buf.get_mut());
|
v.encode(self.buf.get_mut());
|
||||||
trace!("encoded reset; rem={:?}", self.buf.remaining());
|
trace!("encoded reset; rem={:?}", self.buf.remaining());
|
||||||
|
|||||||
Reference in New Issue
Block a user