Get settings handshake working + other junk

This commit is contained in:
Carl Lerche
2017-06-23 15:51:00 -07:00
parent fa21970656
commit ac2959e956
4 changed files with 44 additions and 19 deletions

View File

@@ -83,7 +83,7 @@ impl Peer for Client {
// TODO: Factor in trailers
if !body {
frame.set_end_stream();
// frame.set_end_stream();
} else {
unimplemented!();
}

View File

@@ -3,7 +3,7 @@ use bytes::{Bytes, BytesMut, BufMut, BigEndian};
#[derive(Debug, Clone, Default, Eq, PartialEq)]
pub struct Settings {
flag: SettingsFlag,
flags: SettingsFlags,
// Fields
values: SettingSet,
}
@@ -32,7 +32,7 @@ pub enum Setting {
}
#[derive(Debug, Copy, Clone, Eq, PartialEq, Default)]
pub struct SettingsFlag(u8);
pub struct SettingsFlags(u8);
const ACK: u8 = 0x1;
const ALL: u8 = ACK;
@@ -45,18 +45,26 @@ pub const DEFAULT_MAX_FRAME_SIZE: usize = 16_384;
impl Settings {
pub fn ack() -> Settings {
Settings {
flag: SettingsFlag::ack(),
flags: SettingsFlags::ack(),
.. Settings::default()
}
}
pub fn new(values: SettingSet) -> Settings {
Settings {
flag: SettingsFlag::empty(),
flags: SettingsFlags::empty(),
values: values,
}
}
pub fn is_ack(&self) -> bool {
self.flags.is_ack()
}
pub fn into_set(self) -> SettingSet {
self.values
}
pub fn load(head: Head, payload: &[u8]) -> Result<Settings, Error> {
use self::Setting::*;
@@ -67,7 +75,7 @@ impl Settings {
}
// Load the flag
let flag = SettingsFlag::load(head.flag());
let flag = SettingsFlags::load(head.flag());
if flag.is_ack() {
// Ensure that the payload is empty
@@ -86,7 +94,7 @@ impl Settings {
}
let mut settings = Settings::default();
debug_assert!(!settings.flag.is_ack());
debug_assert!(!settings.flags.is_ack());
for raw in payload.chunks(6) {
match Setting::load(raw) {
@@ -123,7 +131,7 @@ impl Settings {
pub fn encode(&self, dst: &mut BytesMut) {
// Create & encode an appropriate frame head
let head = Head::new(Kind::Settings, self.flag.into(), 0);
let head = Head::new(Kind::Settings, self.flags.into(), 0);
let payload_len = self.payload_len();
head.encode(payload_len, dst);
@@ -221,19 +229,19 @@ impl Setting {
}
}
// ===== impl SettingsFlag =====
// ===== impl SettingsFlags =====
impl SettingsFlag {
pub fn empty() -> SettingsFlag {
SettingsFlag(0)
impl SettingsFlags {
pub fn empty() -> SettingsFlags {
SettingsFlags(0)
}
pub fn load(bits: u8) -> SettingsFlag {
SettingsFlag(bits & ALL)
pub fn load(bits: u8) -> SettingsFlags {
SettingsFlags(bits & ALL)
}
pub fn ack() -> SettingsFlag {
SettingsFlag(ACK)
pub fn ack() -> SettingsFlags {
SettingsFlags(ACK)
}
pub fn is_ack(&self) -> bool {
@@ -241,8 +249,8 @@ impl SettingsFlag {
}
}
impl From<SettingsFlag> for u8 {
fn from(src: SettingsFlag) -> u8 {
impl From<SettingsFlags> for u8 {
fn from(src: SettingsFlags) -> u8 {
src.0
}
}

View File

@@ -36,6 +36,7 @@ pub use frame::{StreamId};
pub use proto::Connection;
/// An H2 connection frame
#[derive(Debug)]
pub enum Frame<T> {
Message {
id: StreamId,

View File

@@ -78,7 +78,23 @@ impl<T> Stream for Settings<T>
type Error = ConnectionError;
fn poll(&mut self) -> Poll<Option<Frame>, ConnectionError> {
self.inner.poll()
loop {
match try_ready!(self.inner.poll()) {
Some(Frame::Settings(v)) => {
if v.is_ack() {
debug!("received remote settings ack");
// TODO: Handle acks
} else {
// Received new settings, queue an ACK
self.remaining_acks += 1;
// Save off the settings
self.remote = v.into_set();
}
}
v => return Ok(Async::Ready(v)),
}
}
}
}