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 // TODO: Factor in trailers
if !body { if !body {
frame.set_end_stream(); // frame.set_end_stream();
} else { } else {
unimplemented!(); unimplemented!();
} }

View File

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

View File

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

View File

@@ -78,7 +78,23 @@ impl<T> Stream for Settings<T>
type Error = ConnectionError; type Error = ConnectionError;
fn poll(&mut self) -> Poll<Option<Frame>, 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)),
}
}
} }
} }