More work
This commit is contained in:
@@ -126,8 +126,8 @@ impl<T, B> fmt::Debug for Handshake<T, B>
|
|||||||
|
|
||||||
impl<B: IntoBuf> Stream<B> {
|
impl<B: IntoBuf> Stream<B> {
|
||||||
/// Receive the HTTP/2.0 response, if it is ready.
|
/// Receive the HTTP/2.0 response, if it is ready.
|
||||||
pub fn poll_response(&mut self) -> Poll<(), ConnectionError> {
|
pub fn poll_response(&mut self) -> Poll<Response<()>, ConnectionError> {
|
||||||
unimplemented!();
|
self.inner.poll_response()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Send data
|
/// Send data
|
||||||
|
|||||||
@@ -90,6 +90,112 @@ impl<T, P, B> Connection<T, P, B>
|
|||||||
Ok(().into())
|
Ok(().into())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Advances the internal state of the connection.
|
||||||
|
pub fn poll(&mut self) -> Poll<Option<()>, ConnectionError> {
|
||||||
|
use frame::Frame::*;
|
||||||
|
|
||||||
|
loop {
|
||||||
|
// First, ensure that the `Connection` is able to receive a frame
|
||||||
|
try_ready!(self.poll_recv_ready());
|
||||||
|
|
||||||
|
trace!("polling codec");
|
||||||
|
|
||||||
|
let frame = match try!(self.codec.poll()) {
|
||||||
|
Async::Ready(frame) => frame,
|
||||||
|
Async::NotReady => {
|
||||||
|
// Flush any pending writes
|
||||||
|
let _ = try!(self.poll_complete());
|
||||||
|
return Ok(Async::NotReady);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
match frame {
|
||||||
|
Some(Headers(frame)) => {
|
||||||
|
trace!("recv HEADERS; frame={:?}", frame);
|
||||||
|
|
||||||
|
if let Some(frame) = try!(self.streams.recv_headers(frame)) {
|
||||||
|
unimplemented!();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
// Update stream state while ensuring that the headers frame
|
||||||
|
// can be received.
|
||||||
|
if let Some(frame) = try!(self.streams.recv_headers(frame)) {
|
||||||
|
let frame = Self::convert_poll_message(frame)?;
|
||||||
|
return Ok(Some(frame).into());
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
Some(Data(frame)) => {
|
||||||
|
unimplemented!();
|
||||||
|
/*
|
||||||
|
trace!("recv DATA; frame={:?}", frame);
|
||||||
|
try!(self.streams.recv_data(&frame));
|
||||||
|
|
||||||
|
let frame = Frame::Data {
|
||||||
|
id: frame.stream_id(),
|
||||||
|
end_of_stream: frame.is_end_stream(),
|
||||||
|
data: frame.into_payload(),
|
||||||
|
};
|
||||||
|
|
||||||
|
return Ok(Some(frame).into());
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
Some(Reset(frame)) => {
|
||||||
|
unimplemented!();
|
||||||
|
/*
|
||||||
|
trace!("recv RST_STREAM; frame={:?}", frame);
|
||||||
|
try!(self.streams.recv_reset(&frame));
|
||||||
|
|
||||||
|
let frame = Frame::Reset {
|
||||||
|
id: frame.stream_id(),
|
||||||
|
error: frame.reason(),
|
||||||
|
};
|
||||||
|
|
||||||
|
return Ok(Some(frame).into());
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
Some(PushPromise(frame)) => {
|
||||||
|
unimplemented!();
|
||||||
|
/*
|
||||||
|
trace!("recv PUSH_PROMISE; frame={:?}", frame);
|
||||||
|
try!(self.streams.recv_push_promise(frame));
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
Some(Settings(frame)) => {
|
||||||
|
trace!("recv SETTINGS; frame={:?}", frame);
|
||||||
|
self.settings.recv_settings(frame);
|
||||||
|
|
||||||
|
// TODO: ACK must be sent THEN settings applied.
|
||||||
|
}
|
||||||
|
Some(Ping(frame)) => {
|
||||||
|
unimplemented!();
|
||||||
|
/*
|
||||||
|
trace!("recv PING; frame={:?}", frame);
|
||||||
|
self.ping_pong.recv_ping(frame);
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
Some(WindowUpdate(frame)) => {
|
||||||
|
unimplemented!();
|
||||||
|
/*
|
||||||
|
trace!("recv WINDOW_UPDATE; frame={:?}", frame);
|
||||||
|
try!(self.streams.recv_window_update(frame));
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
None => {
|
||||||
|
unimplemented!();
|
||||||
|
/*
|
||||||
|
trace!("codec closed");
|
||||||
|
return Ok(Async::Ready(None));
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Flush the write buffer
|
||||||
|
unimplemented!();
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
pub fn send_data(self,
|
pub fn send_data(self,
|
||||||
id: StreamId,
|
id: StreamId,
|
||||||
@@ -138,96 +244,17 @@ impl<T, P, B> Connection<T, P, B>
|
|||||||
/// This function is currently used by poll_complete, but at some point it
|
/// This function is currently used by poll_complete, but at some point it
|
||||||
/// will probably not be required.
|
/// will probably not be required.
|
||||||
fn poll_send_ready(&mut self) -> Poll<(), ConnectionError> {
|
fn poll_send_ready(&mut self) -> Poll<(), ConnectionError> {
|
||||||
|
// TODO: Is this function needed?
|
||||||
try_ready!(self.poll_recv_ready());
|
try_ready!(self.poll_recv_ready());
|
||||||
|
|
||||||
// Ensure all window updates have been sent.
|
|
||||||
try_ready!(self.streams.send_pending_window_updates(&mut self.codec));
|
|
||||||
|
|
||||||
Ok(().into())
|
Ok(().into())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Try to receive the next frame
|
|
||||||
fn recv_frame(&mut self) -> Poll<Option<Frame<P::Poll>>, ConnectionError> {
|
|
||||||
use frame::Frame::*;
|
|
||||||
|
|
||||||
loop {
|
|
||||||
// First, ensure that the `Connection` is able to receive a frame
|
|
||||||
try_ready!(self.poll_recv_ready());
|
|
||||||
|
|
||||||
trace!("polling codec");
|
|
||||||
|
|
||||||
let frame = match try!(self.codec.poll()) {
|
|
||||||
Async::Ready(frame) => frame,
|
|
||||||
Async::NotReady => {
|
|
||||||
// Receiving new frames may depend on ensuring that the write buffer
|
|
||||||
// is clear (e.g. if window updates need to be sent), so `poll_complete`
|
|
||||||
// is called here.
|
|
||||||
let _ = try!(self.poll_complete());
|
|
||||||
return Ok(Async::NotReady);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
match frame {
|
|
||||||
Some(Headers(frame)) => {
|
|
||||||
trace!("recv HEADERS; frame={:?}", frame);
|
|
||||||
// Update stream state while ensuring that the headers frame
|
|
||||||
// can be received.
|
|
||||||
if let Some(frame) = try!(self.streams.recv_headers(frame)) {
|
|
||||||
let frame = Self::convert_poll_message(frame)?;
|
|
||||||
return Ok(Some(frame).into());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Some(Data(frame)) => {
|
|
||||||
trace!("recv DATA; frame={:?}", frame);
|
|
||||||
try!(self.streams.recv_data(&frame));
|
|
||||||
|
|
||||||
let frame = Frame::Data {
|
|
||||||
id: frame.stream_id(),
|
|
||||||
end_of_stream: frame.is_end_stream(),
|
|
||||||
data: frame.into_payload(),
|
|
||||||
};
|
|
||||||
|
|
||||||
return Ok(Some(frame).into());
|
|
||||||
}
|
|
||||||
Some(Reset(frame)) => {
|
|
||||||
trace!("recv RST_STREAM; frame={:?}", frame);
|
|
||||||
try!(self.streams.recv_reset(&frame));
|
|
||||||
|
|
||||||
let frame = Frame::Reset {
|
|
||||||
id: frame.stream_id(),
|
|
||||||
error: frame.reason(),
|
|
||||||
};
|
|
||||||
|
|
||||||
return Ok(Some(frame).into());
|
|
||||||
}
|
|
||||||
Some(PushPromise(frame)) => {
|
|
||||||
trace!("recv PUSH_PROMISE; frame={:?}", frame);
|
|
||||||
try!(self.streams.recv_push_promise(frame));
|
|
||||||
}
|
|
||||||
Some(Settings(frame)) => {
|
|
||||||
trace!("recv SETTINGS; frame={:?}", frame);
|
|
||||||
self.settings.recv_settings(frame);
|
|
||||||
|
|
||||||
// TODO: ACK must be sent THEN settings applied.
|
|
||||||
}
|
|
||||||
Some(Ping(frame)) => {
|
|
||||||
trace!("recv PING; frame={:?}", frame);
|
|
||||||
self.ping_pong.recv_ping(frame);
|
|
||||||
}
|
|
||||||
Some(WindowUpdate(frame)) => {
|
|
||||||
trace!("recv WINDOW_UPDATE; frame={:?}", frame);
|
|
||||||
try!(self.streams.recv_window_update(frame));
|
|
||||||
}
|
|
||||||
None => {
|
|
||||||
trace!("codec closed");
|
|
||||||
return Ok(Async::Ready(None));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn poll_complete(&mut self) -> Poll<(), ConnectionError> {
|
fn poll_complete(&mut self) -> Poll<(), ConnectionError> {
|
||||||
try_ready!(self.poll_send_ready());
|
try_ready!(self.poll_send_ready());
|
||||||
|
|
||||||
|
// Ensure all window updates have been sent.
|
||||||
|
try_ready!(self.streams.poll_complete(&mut self.codec));
|
||||||
try_ready!(self.codec.poll_complete());
|
try_ready!(self.codec.poll_complete());
|
||||||
|
|
||||||
Ok(().into())
|
Ok(().into())
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ use error::Reason::*;
|
|||||||
use error::User::*;
|
use error::User::*;
|
||||||
|
|
||||||
use http::{Request, Response};
|
use http::{Request, Response};
|
||||||
|
use bytes::Bytes;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Config {
|
pub struct Config {
|
||||||
|
|||||||
@@ -14,7 +14,9 @@ struct Indices {
|
|||||||
tail: store::Key,
|
tail: store::Key,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<B> Prioritize<B> {
|
impl<B> Prioritize<B>
|
||||||
|
where B: Buf,
|
||||||
|
{
|
||||||
pub fn new() -> Prioritize<B> {
|
pub fn new() -> Prioritize<B> {
|
||||||
Prioritize {
|
Prioritize {
|
||||||
pending_send: None,
|
pending_send: None,
|
||||||
@@ -58,4 +60,34 @@ impl<B> Prioritize<B> {
|
|||||||
|
|
||||||
stream.is_pending_send = true;
|
stream.is_pending_send = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn poll_complete<T>(&mut self,
|
||||||
|
store: &mut Store<B>,
|
||||||
|
dst: &mut Codec<T, B>)
|
||||||
|
-> Poll<(), ConnectionError>
|
||||||
|
where T: AsyncWrite,
|
||||||
|
{
|
||||||
|
loop {
|
||||||
|
// Ensure codec is ready
|
||||||
|
try_ready!(dst.poll_ready());
|
||||||
|
|
||||||
|
match self.pop_frame(store) {
|
||||||
|
Some(frame) => {
|
||||||
|
// TODO: data frames should be handled specially...
|
||||||
|
let res = dst.start_send(frame)?;
|
||||||
|
|
||||||
|
// We already verified that `dst` is ready to accept the
|
||||||
|
// write
|
||||||
|
assert!(res.is_ready());
|
||||||
|
}
|
||||||
|
None => break,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(().into())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn pop_frame(&mut self, store: &mut Store<B>) -> Option<Frame<B>> {
|
||||||
|
unimplemented!();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
use {frame, ConnectionError};
|
use {client, frame, ConnectionError};
|
||||||
use proto::*;
|
use proto::*;
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
@@ -23,6 +23,9 @@ pub(super) struct Recv<P, B> {
|
|||||||
|
|
||||||
pending_window_updates: VecDeque<StreamId>,
|
pending_window_updates: VecDeque<StreamId>,
|
||||||
|
|
||||||
|
/// Holds frames that are waiting to be read
|
||||||
|
buffer: Buffer<Bytes>,
|
||||||
|
|
||||||
/// Refused StreamId, this represents a frame that must be sent out.
|
/// Refused StreamId, this represents a frame that must be sent out.
|
||||||
refused: Option<StreamId>,
|
refused: Option<StreamId>,
|
||||||
|
|
||||||
@@ -40,6 +43,7 @@ impl<P, B> Recv<P, B>
|
|||||||
init_window_sz: config.init_remote_window_sz,
|
init_window_sz: config.init_remote_window_sz,
|
||||||
flow_control: FlowControl::new(config.init_remote_window_sz),
|
flow_control: FlowControl::new(config.init_remote_window_sz),
|
||||||
pending_window_updates: VecDeque::new(),
|
pending_window_updates: VecDeque::new(),
|
||||||
|
buffer: Buffer::new(),
|
||||||
refused: None,
|
refused: None,
|
||||||
_p: PhantomData,
|
_p: PhantomData,
|
||||||
}
|
}
|
||||||
@@ -67,10 +71,24 @@ impl<P, B> Recv<P, B>
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Transition the stream state based on receiving headers
|
/// Transition the stream state based on receiving headers
|
||||||
pub fn recv_headers(&mut self, stream: &mut Stream<B>, eos: bool)
|
pub fn recv_headers(&mut self,
|
||||||
-> Result<(), ConnectionError>
|
frame: frame::Headers,
|
||||||
|
stream: &mut store::Ptr<B>)
|
||||||
|
-> Result<Option<frame::Headers>, ConnectionError>
|
||||||
{
|
{
|
||||||
stream.state.recv_open(self.init_window_sz, eos)
|
stream.state.recv_open(self.init_window_sz, frame.is_end_stream())?;
|
||||||
|
|
||||||
|
// Only servers can receive a headers frame that initiates the stream.
|
||||||
|
// This is verified in `Streams` before calling this function.
|
||||||
|
if P::is_server() {
|
||||||
|
Ok(Some(frame))
|
||||||
|
} else {
|
||||||
|
// Push the frame onto the recv buffer
|
||||||
|
stream.pending_recv.push_back(&mut self.buffer, frame.into());
|
||||||
|
stream.notify_recv();
|
||||||
|
|
||||||
|
Ok(None)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn recv_eos(&mut self, stream: &mut Stream<B>)
|
pub fn recv_eos(&mut self, stream: &mut Stream<B>)
|
||||||
@@ -233,3 +251,25 @@ impl<P, B> Recv<P, B>
|
|||||||
unimplemented!();
|
unimplemented!();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<B> Recv<client::Peer, B>
|
||||||
|
where B: Buf,
|
||||||
|
{
|
||||||
|
pub fn poll_response(&mut self, stream: &mut store::Ptr<B>)
|
||||||
|
-> Poll<Response<()>, ConnectionError> {
|
||||||
|
// If the buffer is not empty, then the first frame must be a HEADERS
|
||||||
|
// frame or the user violated the contract.
|
||||||
|
match stream.pending_recv.pop_front(&mut self.buffer) {
|
||||||
|
Some(Frame::Headers(v)) => {
|
||||||
|
// TODO: This error should probably be caught on receipt of the
|
||||||
|
// frame vs. now.
|
||||||
|
Ok(client::Peer::convert_poll_message(v)?.into())
|
||||||
|
}
|
||||||
|
Some(frame) => unimplemented!(),
|
||||||
|
None => {
|
||||||
|
stream.recv_task = Some(task::current());
|
||||||
|
Ok(Async::NotReady)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -151,6 +151,15 @@ impl<P, B> Send<P, B>
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn poll_complete<T>(&mut self,
|
||||||
|
store: &mut Store<B>,
|
||||||
|
dst: &mut Codec<T, B>)
|
||||||
|
-> Poll<(), ConnectionError>
|
||||||
|
where T: AsyncWrite,
|
||||||
|
{
|
||||||
|
self.prioritize.poll_complete(store, dst)
|
||||||
|
}
|
||||||
|
|
||||||
/// Get pending window updates
|
/// Get pending window updates
|
||||||
pub fn poll_window_update(&mut self, streams: &mut Store<B>)
|
pub fn poll_window_update(&mut self, streams: &mut Store<B>)
|
||||||
-> Poll<WindowUpdate, ConnectionError>
|
-> Poll<WindowUpdate, ConnectionError>
|
||||||
|
|||||||
@@ -47,6 +47,13 @@ impl<B> Store<B> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn resolve(&mut self, key: Key) -> Ptr<B> {
|
||||||
|
Ptr {
|
||||||
|
key: key,
|
||||||
|
store: self,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn find_mut(&mut self, id: &StreamId) -> Option<&mut Stream<B>> {
|
pub fn find_mut(&mut self, id: &StreamId) -> Option<&mut Stream<B>> {
|
||||||
if let Some(handle) = self.ids.get(id) {
|
if let Some(handle) = self.ids.get(id) {
|
||||||
Some(&mut self.slab[*handle])
|
Some(&mut self.slab[*handle])
|
||||||
@@ -117,6 +124,10 @@ impl<'a, B: 'a> ops::DerefMut for Ptr<'a, B> {
|
|||||||
// ===== impl OccupiedEntry =====
|
// ===== impl OccupiedEntry =====
|
||||||
|
|
||||||
impl<'a, B> OccupiedEntry<'a, B> {
|
impl<'a, B> OccupiedEntry<'a, B> {
|
||||||
|
pub fn key(&self) -> Key {
|
||||||
|
Key(*self.ids.get())
|
||||||
|
}
|
||||||
|
|
||||||
pub fn get(&self) -> &Stream<B> {
|
pub fn get(&self) -> &Stream<B> {
|
||||||
&self.slab[*self.ids.get()]
|
&self.slab[*self.ids.get()]
|
||||||
}
|
}
|
||||||
@@ -133,13 +144,13 @@ impl<'a, B> OccupiedEntry<'a, B> {
|
|||||||
// ===== impl VacantEntry =====
|
// ===== impl VacantEntry =====
|
||||||
//
|
//
|
||||||
impl<'a, B> VacantEntry<'a, B> {
|
impl<'a, B> VacantEntry<'a, B> {
|
||||||
pub fn insert(self, value: Stream<B>) -> &'a mut Stream<B> {
|
pub fn insert(self, value: Stream<B>) -> Key {
|
||||||
// Insert the value in the slab
|
// Insert the value in the slab
|
||||||
let handle = self.slab.insert(value);
|
let key = self.slab.insert(value);
|
||||||
|
|
||||||
// Insert the handle in the ID map
|
// Insert the handle in the ID map
|
||||||
self.ids.insert(handle);
|
self.ids.insert(key);
|
||||||
|
|
||||||
&mut self.slab[handle]
|
Key(key)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,12 @@ pub(super) struct Stream<B> {
|
|||||||
/// Current state of the stream
|
/// Current state of the stream
|
||||||
pub state: State,
|
pub state: State,
|
||||||
|
|
||||||
|
/// Frames pending for this stream to read
|
||||||
|
pub pending_recv: buffer::Deque<Bytes>,
|
||||||
|
|
||||||
|
/// Task tracking receiving frames
|
||||||
|
pub recv_task: Option<task::Task>,
|
||||||
|
|
||||||
/// Frames pending for this stream being sent to the socket
|
/// Frames pending for this stream being sent to the socket
|
||||||
pub pending_send: buffer::Deque<B>,
|
pub pending_send: buffer::Deque<B>,
|
||||||
|
|
||||||
@@ -19,6 +25,8 @@ impl<B> Stream<B> {
|
|||||||
pub fn new() -> Stream<B> {
|
pub fn new() -> Stream<B> {
|
||||||
Stream {
|
Stream {
|
||||||
state: State::default(),
|
state: State::default(),
|
||||||
|
pending_recv: buffer::Deque::new(),
|
||||||
|
recv_task: None,
|
||||||
pending_send: buffer::Deque::new(),
|
pending_send: buffer::Deque::new(),
|
||||||
next_pending_send: None,
|
next_pending_send: None,
|
||||||
is_pending_send: false,
|
is_pending_send: false,
|
||||||
@@ -32,4 +40,10 @@ impl<B> Stream<B> {
|
|||||||
pub fn recv_flow_control(&mut self) -> Option<&mut FlowControl> {
|
pub fn recv_flow_control(&mut self) -> Option<&mut FlowControl> {
|
||||||
self.state.recv_flow_control()
|
self.state.recv_flow_control()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn notify_recv(&mut self) {
|
||||||
|
if let Some(ref mut task) = self.recv_task {
|
||||||
|
task.notify();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ pub struct Streams<P, B> {
|
|||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct StreamRef<P, B> {
|
pub struct StreamRef<P, B> {
|
||||||
inner: Arc<Mutex<Inner<P, B>>>,
|
inner: Arc<Mutex<Inner<P, B>>>,
|
||||||
id: StreamId,
|
key: store::Key,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Fields needed to manage state related to managing the set of streams. This
|
/// Fields needed to manage state related to managing the set of streams. This
|
||||||
@@ -53,6 +53,7 @@ impl<P, B> Streams<P, B>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Process inbound headers
|
||||||
pub fn recv_headers(&mut self, frame: frame::Headers)
|
pub fn recv_headers(&mut self, frame: frame::Headers)
|
||||||
-> Result<Option<frame::Headers>, ConnectionError>
|
-> Result<Option<frame::Headers>, ConnectionError>
|
||||||
{
|
{
|
||||||
@@ -60,8 +61,8 @@ impl<P, B> Streams<P, B>
|
|||||||
let mut me = self.inner.lock().unwrap();
|
let mut me = self.inner.lock().unwrap();
|
||||||
let me = &mut *me;
|
let me = &mut *me;
|
||||||
|
|
||||||
let stream = match me.store.find_entry(id) {
|
let key = match me.store.find_entry(id) {
|
||||||
Entry::Occupied(e) => e.into_mut(),
|
Entry::Occupied(e) => e.key(),
|
||||||
Entry::Vacant(e) => {
|
Entry::Vacant(e) => {
|
||||||
// Trailers cannot open a stream. Trailers are header frames
|
// Trailers cannot open a stream. Trailers are header frames
|
||||||
// that do not contain pseudo headers. Requests MUST contain a
|
// that do not contain pseudo headers. Requests MUST contain a
|
||||||
@@ -78,22 +79,28 @@ impl<P, B> Streams<P, B>
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if frame.is_trailers() {
|
let mut stream = me.store.resolve(key);
|
||||||
|
|
||||||
|
let ret = if frame.is_trailers() {
|
||||||
|
unimplemented!();
|
||||||
|
/*
|
||||||
if !frame.is_end_stream() {
|
if !frame.is_end_stream() {
|
||||||
// TODO: What error should this return?
|
// TODO: What error should this return?
|
||||||
unimplemented!();
|
unimplemented!();
|
||||||
}
|
}
|
||||||
|
|
||||||
try!(me.actions.recv.recv_eos(stream));
|
try!(me.actions.recv.recv_eos(stream));
|
||||||
|
*/
|
||||||
} else {
|
} else {
|
||||||
try!(me.actions.recv.recv_headers(stream, frame.is_end_stream()));
|
try!(me.actions.recv.recv_headers(frame, &mut stream))
|
||||||
}
|
};
|
||||||
|
|
||||||
|
// TODO: move this into a fn
|
||||||
if stream.state.is_closed() {
|
if stream.state.is_closed() {
|
||||||
me.actions.dec_num_streams(id);
|
me.actions.dec_num_streams(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(Some(frame))
|
Ok(ret)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn recv_data(&mut self, frame: &frame::Data)
|
pub fn recv_data(&mut self, frame: &frame::Data)
|
||||||
@@ -241,16 +248,20 @@ impl<P, B> Streams<P, B>
|
|||||||
me.actions.recv.send_pending_refusal(dst)
|
me.actions.recv.send_pending_refusal(dst)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn send_pending_window_updates<T>(&mut self, dst: &mut Codec<T, B>)
|
pub fn poll_complete<T>(&mut self, dst: &mut Codec<T, B>)
|
||||||
-> Poll<(), ConnectionError>
|
-> Poll<(), ConnectionError>
|
||||||
where T: AsyncWrite,
|
where T: AsyncWrite,
|
||||||
{
|
{
|
||||||
let mut me = self.inner.lock().unwrap();
|
let mut me = self.inner.lock().unwrap();
|
||||||
let me = &mut *me;
|
let me = &mut *me;
|
||||||
|
|
||||||
|
// TODO: sending window updates should be part of Prioritize
|
||||||
|
/*
|
||||||
try_ready!(me.actions.recv.send_connection_window_update(dst));
|
try_ready!(me.actions.recv.send_connection_window_update(dst));
|
||||||
try_ready!(me.actions.recv.send_stream_window_update(&mut me.store, dst));
|
try_ready!(me.actions.recv.send_stream_window_update(&mut me.store, dst));
|
||||||
|
*/
|
||||||
|
|
||||||
Ok(().into())
|
me.actions.send.poll_complete(&mut me.store, dst)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -260,7 +271,7 @@ impl<B> Streams<client::Peer, B>
|
|||||||
pub fn send_request(&mut self, request: Request<()>, end_of_stream: bool)
|
pub fn send_request(&mut self, request: Request<()>, end_of_stream: bool)
|
||||||
-> Result<StreamRef<client::Peer, B>, ConnectionError>
|
-> Result<StreamRef<client::Peer, B>, ConnectionError>
|
||||||
{
|
{
|
||||||
let id = {
|
let key = {
|
||||||
let mut me = self.inner.lock().unwrap();
|
let mut me = self.inner.lock().unwrap();
|
||||||
let me = &mut *me;
|
let me = &mut *me;
|
||||||
|
|
||||||
@@ -279,16 +290,29 @@ impl<B> Streams<client::Peer, B>
|
|||||||
// closed state.
|
// closed state.
|
||||||
debug_assert!(!stream.state.is_closed());
|
debug_assert!(!stream.state.is_closed());
|
||||||
|
|
||||||
id
|
stream.key()
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(StreamRef {
|
Ok(StreamRef {
|
||||||
inner: self.inner.clone(),
|
inner: self.inner.clone(),
|
||||||
id: id,
|
key: key,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<B> StreamRef<client::Peer, B>
|
||||||
|
where B: Buf,
|
||||||
|
{
|
||||||
|
pub fn poll_response(&mut self) -> Poll<Response<()>, ConnectionError> {
|
||||||
|
let mut me = self.inner.lock().unwrap();
|
||||||
|
let me = &mut *me;
|
||||||
|
|
||||||
|
let mut stream = me.store.resolve(self.key);
|
||||||
|
|
||||||
|
me.actions.recv.poll_response(&mut stream)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<P, B> Actions<P, B>
|
impl<P, B> Actions<P, B>
|
||||||
where P: Peer,
|
where P: Peer,
|
||||||
B: Buf,
|
B: Buf,
|
||||||
|
|||||||
Reference in New Issue
Block a user