More hackin
This commit is contained in:
@@ -3,9 +3,30 @@
|
|||||||
///
|
///
|
||||||
/// This could be either a request or a response.
|
/// This could be either a request or a response.
|
||||||
pub struct Headers {
|
pub struct Headers {
|
||||||
|
/// The ID of the stream with which this frame is associated.
|
||||||
stream_id: StreamId,
|
stream_id: StreamId,
|
||||||
|
/// The stream dependency information, if any.
|
||||||
|
stream_dep: Option<StreamDependency>,
|
||||||
|
/// The decoded headers
|
||||||
headers: HeaderMap,
|
headers: HeaderMap,
|
||||||
pseudo: Pseudo,
|
pseudo: Pseudo,
|
||||||
|
flags: HeaderFlag,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Copy, Clone, Eq, PartialEq, Default)]
|
||||||
|
pub struct HeadersFlag(u8);
|
||||||
|
|
||||||
|
pub struct PushPromise;
|
||||||
|
|
||||||
|
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,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Pseudo {
|
pub struct Pseudo {
|
||||||
@@ -18,3 +39,40 @@ pub struct Pseudo {
|
|||||||
// Response
|
// Response
|
||||||
status: Option<()>,
|
status: Option<()>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const END_STREAM: u8 = 0x1;
|
||||||
|
const END_HEADERS: u8 = 0x4;
|
||||||
|
const PADDED: u8 = 0x8;
|
||||||
|
const PRIORITY: u8 = 0x20;
|
||||||
|
const ALL: u8 = END_STREAM
|
||||||
|
| END_HEADERS
|
||||||
|
| PADDED
|
||||||
|
| PRIORITY;
|
||||||
|
|
||||||
|
// ===== impl HeadersFlag =====
|
||||||
|
|
||||||
|
impl HeadersFlag {
|
||||||
|
pub empty() -> HeadersFlag {
|
||||||
|
HeadersFlag(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn load(bits: u8) -> HeadersFlag {
|
||||||
|
HeadersFlag(bits & ALL)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn is_end_stream(&self) -> bool {
|
||||||
|
self.0 & END_STREAM == END_STREAM
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn is_end_headers(&self) -> bool {
|
||||||
|
self.0 & END_HEADERS == END_HEADERS
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn is_padded(&self) -> bool {
|
||||||
|
self.0 & PADDED == PADDED
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn is_priority(&self) -> bool {
|
||||||
|
self.0 & PRIORITY == PRIORITY
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ use frame::{self, Frame, Kind};
|
|||||||
use tokio_io::AsyncWrite;
|
use tokio_io::AsyncWrite;
|
||||||
|
|
||||||
use futures::*;
|
use futures::*;
|
||||||
use bytes::{BytesMut, Buf};
|
use bytes::{Bytes, BytesMut, Buf};
|
||||||
|
|
||||||
use std::io::{self, Write};
|
use std::io::{self, Write};
|
||||||
|
|
||||||
@@ -27,18 +27,8 @@ impl<T> FramedRead<T>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> Stream for FramedRead<T>
|
impl<T> FramedRead<T> {
|
||||||
where T: Stream<Item = BytesMut, Error = io::Error>,
|
fn decode_frame(&mut self, mut bytes: Bytes) -> Result<Option<Frame>, ConnectionError> {
|
||||||
{
|
|
||||||
type Item = Frame;
|
|
||||||
type Error = ConnectionError;
|
|
||||||
|
|
||||||
fn poll(&mut self) -> Poll<Option<Frame>, ConnectionError> {
|
|
||||||
let mut bytes = match try_ready!(self.inner.poll()) {
|
|
||||||
Some(bytes) => bytes,
|
|
||||||
None => return Ok(Async::Ready(None)),
|
|
||||||
};
|
|
||||||
|
|
||||||
// Parse the head
|
// Parse the head
|
||||||
let head = frame::Head::parse(&bytes);
|
let head = frame::Head::parse(&bytes);
|
||||||
|
|
||||||
@@ -58,12 +48,31 @@ impl<T> Stream for FramedRead<T>
|
|||||||
Kind::Continuation => unimplemented!(),
|
Kind::Continuation => unimplemented!(),
|
||||||
Kind::Unknown => {
|
Kind::Unknown => {
|
||||||
let _ = bytes.split_to(frame::HEADER_LEN);
|
let _ = bytes.split_to(frame::HEADER_LEN);
|
||||||
frame::Unknown::new(head, bytes.freeze()).into()
|
frame::Unknown::new(head, bytes).into()
|
||||||
}
|
}
|
||||||
_ => unimplemented!(),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(Async::Ready(Some(frame)))
|
Ok(Some(frame))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> Stream for FramedRead<T>
|
||||||
|
where T: Stream<Item = BytesMut, Error = io::Error>,
|
||||||
|
{
|
||||||
|
type Item = Frame;
|
||||||
|
type Error = ConnectionError;
|
||||||
|
|
||||||
|
fn poll(&mut self) -> Poll<Option<Frame>, ConnectionError> {
|
||||||
|
loop {
|
||||||
|
let mut bytes = match try_ready!(self.inner.poll()) {
|
||||||
|
Some(bytes) => bytes.freeze(),
|
||||||
|
None => return Ok(Async::Ready(None)),
|
||||||
|
};
|
||||||
|
|
||||||
|
if let Some(frame) = try!(self.decode_frame(bytes)) {
|
||||||
|
return Ok(Async::Ready(Some(frame)));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user