Remove P generic from type
This commit is contained in:
@@ -15,9 +15,6 @@ pub struct Handshake<T, B: IntoBuf = Bytes> {
|
|||||||
inner: Box<Future<Item = Client<T, B>, Error = ConnectionError>>,
|
inner: Box<Future<Item = Client<T, B>, Error = ConnectionError>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub(crate) struct Peer;
|
|
||||||
|
|
||||||
/// Marker type indicating a client peer
|
/// Marker type indicating a client peer
|
||||||
pub struct Client<T, B: IntoBuf> {
|
pub struct Client<T, B: IntoBuf> {
|
||||||
connection: Connection<T, Peer, B>,
|
connection: Connection<T, Peer, B>,
|
||||||
@@ -25,19 +22,22 @@ pub struct Client<T, B: IntoBuf> {
|
|||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Stream<B: IntoBuf> {
|
pub struct Stream<B: IntoBuf> {
|
||||||
inner: proto::StreamRef<Peer, B::Buf>,
|
inner: proto::StreamRef<B::Buf>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Body<B: IntoBuf> {
|
pub struct Body<B: IntoBuf> {
|
||||||
inner: proto::StreamRef<Peer, B::Buf>,
|
inner: proto::StreamRef<B::Buf>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Chunk<B: IntoBuf> {
|
pub struct Chunk<B: IntoBuf> {
|
||||||
inner: proto::Chunk<Peer, B::Buf>,
|
inner: proto::Chunk<B::Buf>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub(crate) struct Peer;
|
||||||
|
|
||||||
impl<T> Client<T, Bytes>
|
impl<T> Client<T, Bytes>
|
||||||
where T: AsyncRead + AsyncWrite + 'static,
|
where T: AsyncRead + AsyncWrite + 'static,
|
||||||
{
|
{
|
||||||
@@ -160,7 +160,7 @@ impl<B: IntoBuf> Stream<B> {
|
|||||||
pub fn send_data(&mut self, data: B, end_of_stream: bool)
|
pub fn send_data(&mut self, data: B, end_of_stream: bool)
|
||||||
-> Result<(), ConnectionError>
|
-> Result<(), ConnectionError>
|
||||||
{
|
{
|
||||||
self.inner.send_data(data.into_buf(), end_of_stream)
|
self.inner.send_data::<Peer>(data.into_buf(), end_of_stream)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Send trailers
|
/// Send trailers
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ pub struct Connection<T, P, B: IntoBuf = Bytes> {
|
|||||||
// TODO: Remove <B>
|
// TODO: Remove <B>
|
||||||
ping_pong: PingPong<B::Buf>,
|
ping_pong: PingPong<B::Buf>,
|
||||||
settings: Settings,
|
settings: Settings,
|
||||||
streams: Streams<P, B::Buf>,
|
streams: Streams<B::Buf>,
|
||||||
|
|
||||||
_phantom: PhantomData<P>,
|
_phantom: PhantomData<P>,
|
||||||
}
|
}
|
||||||
@@ -31,7 +31,7 @@ impl<T, P, B> Connection<T, P, B>
|
|||||||
{
|
{
|
||||||
pub fn new(codec: Codec<T, B::Buf>) -> Connection<T, P, B> {
|
pub fn new(codec: Codec<T, B::Buf>) -> Connection<T, P, B> {
|
||||||
// TODO: Actually configure
|
// TODO: Actually configure
|
||||||
let streams = Streams::new(streams::Config {
|
let streams = Streams::new::<P>(streams::Config {
|
||||||
max_remote_initiated: None,
|
max_remote_initiated: None,
|
||||||
init_remote_window_sz: DEFAULT_INITIAL_WINDOW_SIZE,
|
init_remote_window_sz: DEFAULT_INITIAL_WINDOW_SIZE,
|
||||||
max_local_initiated: None,
|
max_local_initiated: None,
|
||||||
@@ -123,7 +123,7 @@ impl<T, P, B> Connection<T, P, B>
|
|||||||
Some(Headers(frame)) => {
|
Some(Headers(frame)) => {
|
||||||
trace!("recv HEADERS; frame={:?}", frame);
|
trace!("recv HEADERS; frame={:?}", frame);
|
||||||
|
|
||||||
if let Some(frame) = try!(self.streams.recv_headers(frame)) {
|
if let Some(frame) = try!(self.streams.recv_headers::<P>(frame)) {
|
||||||
unimplemented!();
|
unimplemented!();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -138,15 +138,15 @@ impl<T, P, B> Connection<T, P, B>
|
|||||||
}
|
}
|
||||||
Some(Data(frame)) => {
|
Some(Data(frame)) => {
|
||||||
trace!("recv DATA; frame={:?}", frame);
|
trace!("recv DATA; frame={:?}", frame);
|
||||||
try!(self.streams.recv_data(frame));
|
try!(self.streams.recv_data::<P>(frame));
|
||||||
}
|
}
|
||||||
Some(Reset(frame)) => {
|
Some(Reset(frame)) => {
|
||||||
trace!("recv RST_STREAM; frame={:?}", frame);
|
trace!("recv RST_STREAM; frame={:?}", frame);
|
||||||
try!(self.streams.recv_reset(frame));
|
try!(self.streams.recv_reset::<P>(frame));
|
||||||
}
|
}
|
||||||
Some(PushPromise(frame)) => {
|
Some(PushPromise(frame)) => {
|
||||||
trace!("recv PUSH_PROMISE; frame={:?}", frame);
|
trace!("recv PUSH_PROMISE; frame={:?}", frame);
|
||||||
self.streams.recv_push_promise(frame)?;
|
self.streams.recv_push_promise::<P>(frame)?;
|
||||||
}
|
}
|
||||||
Some(Settings(frame)) => {
|
Some(Settings(frame)) => {
|
||||||
trace!("recv SETTINGS; frame={:?}", frame);
|
trace!("recv SETTINGS; frame={:?}", frame);
|
||||||
@@ -263,7 +263,7 @@ impl<T, B> Connection<T, client::Peer, B>
|
|||||||
{
|
{
|
||||||
/// Initialize a new HTTP/2.0 stream and send the message.
|
/// Initialize a new HTTP/2.0 stream and send the message.
|
||||||
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::Buf>, ConnectionError>
|
-> Result<StreamRef<B::Buf>, ConnectionError>
|
||||||
{
|
{
|
||||||
self.streams.send_request(request, end_of_stream)
|
self.streams.send_request(request, end_of_stream)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ use std::collections::VecDeque;
|
|||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub(super) struct Recv<P, B> {
|
pub(super) struct Recv<B> {
|
||||||
/// Maximum number of remote initiated streams
|
/// Maximum number of remote initiated streams
|
||||||
max_streams: Option<usize>,
|
max_streams: Option<usize>,
|
||||||
|
|
||||||
@@ -31,7 +31,7 @@ pub(super) struct Recv<P, B> {
|
|||||||
/// 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>,
|
||||||
|
|
||||||
_p: PhantomData<(P, B)>,
|
_p: PhantomData<(B)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@@ -46,10 +46,7 @@ struct Indices {
|
|||||||
tail: store::Key,
|
tail: store::Key,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<P, B> Recv<P, B>
|
impl<B> Recv<B> where B: Buf {
|
||||||
where P: Peer,
|
|
||||||
B: Buf,
|
|
||||||
{
|
|
||||||
pub fn new(config: &Config) -> Self {
|
pub fn new(config: &Config) -> Self {
|
||||||
Recv {
|
Recv {
|
||||||
max_streams: config.max_remote_initiated,
|
max_streams: config.max_remote_initiated,
|
||||||
@@ -66,10 +63,12 @@ impl<P, B> Recv<P, B>
|
|||||||
/// Update state reflecting a new, remotely opened stream
|
/// Update state reflecting a new, remotely opened stream
|
||||||
///
|
///
|
||||||
/// Returns the stream state if successful. `None` if refused
|
/// Returns the stream state if successful. `None` if refused
|
||||||
pub fn open(&mut self, id: StreamId) -> Result<Option<Stream<B>>, ConnectionError> {
|
pub fn open<P: Peer>(&mut self, id: StreamId)
|
||||||
|
-> Result<Option<Stream<B>>, ConnectionError>
|
||||||
|
{
|
||||||
assert!(self.refused.is_none());
|
assert!(self.refused.is_none());
|
||||||
|
|
||||||
try!(self.ensure_can_open(id));
|
try!(self.ensure_can_open::<P>(id));
|
||||||
|
|
||||||
if !self.can_inc_num_streams() {
|
if !self.can_inc_num_streams() {
|
||||||
self.refused = Some(id);
|
self.refused = Some(id);
|
||||||
@@ -79,8 +78,28 @@ impl<P, B> Recv<P, B>
|
|||||||
Ok(Some(Stream::new(id)))
|
Ok(Some(Stream::new(id)))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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.state.ensure_recv_open()?;
|
||||||
|
|
||||||
|
stream.recv_task = Some(task::current());
|
||||||
|
Ok(Async::NotReady)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Transition the stream state based on receiving headers
|
/// Transition the stream state based on receiving headers
|
||||||
pub fn recv_headers(&mut self,
|
pub fn recv_headers<P: Peer>(&mut self,
|
||||||
frame: frame::Headers,
|
frame: frame::Headers,
|
||||||
stream: &mut store::Ptr<B>)
|
stream: &mut store::Ptr<B>)
|
||||||
-> Result<Option<frame::Headers>, ConnectionError>
|
-> Result<Option<frame::Headers>, ConnectionError>
|
||||||
@@ -155,11 +174,13 @@ impl<P, B> Recv<P, B>
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn recv_push_promise(&mut self, frame: frame::PushPromise, stream: &mut store::Ptr<B>)
|
pub fn recv_push_promise<P: Peer>(&mut self,
|
||||||
|
frame: frame::PushPromise,
|
||||||
|
stream: &mut store::Ptr<B>)
|
||||||
-> Result<(), ConnectionError>
|
-> Result<(), ConnectionError>
|
||||||
{
|
{
|
||||||
// First, make sure that the values are legit
|
// First, make sure that the values are legit
|
||||||
self.ensure_can_reserve(frame.promised_id())?;
|
self.ensure_can_reserve::<P>(frame.promised_id())?;
|
||||||
|
|
||||||
// Make sure that the stream state is valid
|
// Make sure that the stream state is valid
|
||||||
stream.state.ensure_recv_open()?;
|
stream.state.ensure_recv_open()?;
|
||||||
@@ -241,7 +262,9 @@ impl<P, B> Recv<P, B>
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Returns true if the remote peer can initiate a stream with the given ID.
|
/// Returns true if the remote peer can initiate a stream with the given ID.
|
||||||
fn ensure_can_open(&self, id: StreamId) -> Result<(), ConnectionError> {
|
fn ensure_can_open<P: Peer>(&self, id: StreamId)
|
||||||
|
-> Result<(), ConnectionError>
|
||||||
|
{
|
||||||
if !P::is_server() {
|
if !P::is_server() {
|
||||||
// Remote is a server and cannot open streams. PushPromise is
|
// Remote is a server and cannot open streams. PushPromise is
|
||||||
// registered by reserving, so does not go through this path.
|
// registered by reserving, so does not go through this path.
|
||||||
@@ -257,7 +280,9 @@ impl<P, B> Recv<P, B>
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Returns true if the remote peer can reserve a stream with the given ID.
|
/// Returns true if the remote peer can reserve a stream with the given ID.
|
||||||
fn ensure_can_reserve(&self, promised_id: StreamId) -> Result<(), ConnectionError> {
|
fn ensure_can_reserve<P: Peer>(&self, promised_id: StreamId)
|
||||||
|
-> Result<(), ConnectionError>
|
||||||
|
{
|
||||||
// TODO: Are there other rules?
|
// TODO: Are there other rules?
|
||||||
if P::is_server() {
|
if P::is_server() {
|
||||||
// The remote is a client and cannot reserve
|
// The remote is a client and cannot reserve
|
||||||
@@ -400,27 +425,3 @@ 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.state.ensure_recv_open()?;
|
|
||||||
|
|
||||||
stream.recv_task = Some(task::current());
|
|
||||||
Ok(Async::NotReady)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ use std::collections::VecDeque;
|
|||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub(super) struct Send<P, B> {
|
pub(super) struct Send<B> {
|
||||||
/// Maximum number of locally initiated streams
|
/// Maximum number of locally initiated streams
|
||||||
max_streams: Option<usize>,
|
max_streams: Option<usize>,
|
||||||
|
|
||||||
@@ -36,15 +36,12 @@ pub(super) struct Send<P, B> {
|
|||||||
/// be notified later. Access to poll_window_update must not be shared across tasks,
|
/// be notified later. Access to poll_window_update must not be shared across tasks,
|
||||||
/// as we only track a single task (and *not* i.e. a task per stream id).
|
/// as we only track a single task (and *not* i.e. a task per stream id).
|
||||||
blocked: Option<task::Task>,
|
blocked: Option<task::Task>,
|
||||||
|
|
||||||
_p: PhantomData<P>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<P, B> Send<P, B>
|
impl<B> Send<B> where B: Buf {
|
||||||
where P: Peer,
|
|
||||||
B: Buf,
|
/// Create a new `Send`
|
||||||
{
|
pub fn new<P: Peer>(config: &Config) -> Self {
|
||||||
pub fn new(config: &Config) -> Self {
|
|
||||||
let next_stream_id = if P::is_server() {
|
let next_stream_id = if P::is_server() {
|
||||||
2
|
2
|
||||||
} else {
|
} else {
|
||||||
@@ -60,15 +57,16 @@ impl<P, B> Send<P, B>
|
|||||||
prioritize: Prioritize::new(),
|
prioritize: Prioritize::new(),
|
||||||
pending_window_updates: VecDeque::new(),
|
pending_window_updates: VecDeque::new(),
|
||||||
blocked: None,
|
blocked: None,
|
||||||
_p: PhantomData,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Update state reflecting a new, locally opened stream
|
/// Update state reflecting a new, locally opened stream
|
||||||
///
|
///
|
||||||
/// Returns the stream state if successful. `None` if refused
|
/// Returns the stream state if successful. `None` if refused
|
||||||
pub fn open(&mut self) -> Result<Stream<B>, ConnectionError> {
|
pub fn open<P: Peer>(&mut self)
|
||||||
try!(self.ensure_can_open());
|
-> Result<Stream<B>, ConnectionError>
|
||||||
|
{
|
||||||
|
try!(self.ensure_can_open::<P>());
|
||||||
|
|
||||||
if let Some(max) = self.max_streams {
|
if let Some(max) = self.max_streams {
|
||||||
if max <= self.num_streams {
|
if max <= self.num_streams {
|
||||||
@@ -229,7 +227,7 @@ impl<P, B> Send<P, B>
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Returns true if the local actor can initiate a stream with the given ID.
|
/// Returns true if the local actor can initiate a stream with the given ID.
|
||||||
fn ensure_can_open(&self) -> Result<(), ConnectionError> {
|
fn ensure_can_open<P: Peer>(&self) -> Result<(), ConnectionError> {
|
||||||
if P::is_server() {
|
if P::is_server() {
|
||||||
// Servers cannot open streams. PushPromise must first be reserved.
|
// Servers cannot open streams. PushPromise must first be reserved.
|
||||||
return Err(UnexpectedFrameType.into());
|
return Err(UnexpectedFrameType.into());
|
||||||
|
|||||||
@@ -2,28 +2,28 @@ use client;
|
|||||||
use proto::*;
|
use proto::*;
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
|
use std::marker::PhantomData;
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
|
|
||||||
// TODO: All the VecDeques should become linked lists using the State
|
// TODO: All the VecDeques should become linked lists using the State
|
||||||
// values.
|
// values.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Streams<P, B> {
|
pub struct Streams<B> {
|
||||||
inner: Arc<Mutex<Inner<P, B>>>,
|
inner: Arc<Mutex<Inner<B>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Reference to the stream state
|
/// Reference to the stream state
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct StreamRef<P, B> {
|
pub struct StreamRef<B> {
|
||||||
inner: Arc<Mutex<Inner<P, B>>>,
|
inner: Arc<Mutex<Inner<B>>>,
|
||||||
key: store::Key,
|
key: store::Key,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Chunk<P, B>
|
pub struct Chunk<B>
|
||||||
where P: Peer,
|
where B: Buf,
|
||||||
B: Buf,
|
|
||||||
{
|
{
|
||||||
inner: Arc<Mutex<Inner<P, B>>>,
|
inner: Arc<Mutex<Inner<B>>>,
|
||||||
recv: recv::Chunk,
|
recv: recv::Chunk,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -32,30 +32,29 @@ pub struct Chunk<P, B>
|
|||||||
///
|
///
|
||||||
/// TODO: better name
|
/// TODO: better name
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct Inner<P, B> {
|
struct Inner<B> {
|
||||||
actions: Actions<P, B>,
|
actions: Actions<B>,
|
||||||
store: Store<B>,
|
store: Store<B>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct Actions<P, B> {
|
struct Actions<B> {
|
||||||
/// Manages state transitions initiated by receiving frames
|
/// Manages state transitions initiated by receiving frames
|
||||||
recv: Recv<P, B>,
|
recv: Recv<B>,
|
||||||
|
|
||||||
/// Manages state transitions initiated by sending frames
|
/// Manages state transitions initiated by sending frames
|
||||||
send: Send<P, B>,
|
send: Send<B>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<P, B> Streams<P, B>
|
impl<B> Streams<B>
|
||||||
where P: Peer,
|
where B: Buf,
|
||||||
B: Buf,
|
|
||||||
{
|
{
|
||||||
pub fn new(config: Config) -> Self {
|
pub fn new<P: Peer>(config: Config) -> Self {
|
||||||
Streams {
|
Streams {
|
||||||
inner: Arc::new(Mutex::new(Inner {
|
inner: Arc::new(Mutex::new(Inner {
|
||||||
actions: Actions {
|
actions: Actions {
|
||||||
recv: Recv::new(&config),
|
recv: Recv::new(&config),
|
||||||
send: Send::new(&config),
|
send: Send::new::<P>(&config),
|
||||||
},
|
},
|
||||||
store: Store::new(),
|
store: Store::new(),
|
||||||
})),
|
})),
|
||||||
@@ -63,7 +62,7 @@ impl<P, B> Streams<P, B>
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Process inbound headers
|
/// Process inbound headers
|
||||||
pub fn recv_headers(&mut self, frame: frame::Headers)
|
pub fn recv_headers<P: Peer>(&mut self, frame: frame::Headers)
|
||||||
-> Result<Option<frame::Headers>, ConnectionError>
|
-> Result<Option<frame::Headers>, ConnectionError>
|
||||||
{
|
{
|
||||||
let id = frame.stream_id();
|
let id = frame.stream_id();
|
||||||
@@ -81,7 +80,7 @@ impl<P, B> Streams<P, B>
|
|||||||
return Err(ProtocolError.into());
|
return Err(ProtocolError.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
match try!(me.actions.recv.open(id)) {
|
match try!(me.actions.recv.open::<P>(id)) {
|
||||||
Some(stream) => e.insert(stream),
|
Some(stream) => e.insert(stream),
|
||||||
None => return Ok(None),
|
None => return Ok(None),
|
||||||
}
|
}
|
||||||
@@ -90,7 +89,7 @@ impl<P, B> Streams<P, B>
|
|||||||
|
|
||||||
let stream = me.store.resolve(key);
|
let stream = me.store.resolve(key);
|
||||||
|
|
||||||
me.actions.transition(stream, |actions, stream| {
|
me.actions.transition::<P, _, _>(stream, |actions, stream| {
|
||||||
if frame.is_trailers() {
|
if frame.is_trailers() {
|
||||||
unimplemented!();
|
unimplemented!();
|
||||||
/*
|
/*
|
||||||
@@ -102,12 +101,12 @@ impl<P, B> Streams<P, B>
|
|||||||
try!(me.actions.recv.recv_eos(stream));
|
try!(me.actions.recv.recv_eos(stream));
|
||||||
*/
|
*/
|
||||||
} else {
|
} else {
|
||||||
actions.recv.recv_headers(frame, stream)
|
actions.recv.recv_headers::<P>(frame, stream)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn recv_data(&mut self, frame: frame::Data)
|
pub fn recv_data<P: Peer>(&mut self, frame: frame::Data)
|
||||||
-> Result<(), ConnectionError>
|
-> Result<(), ConnectionError>
|
||||||
{
|
{
|
||||||
let mut me = self.inner.lock().unwrap();
|
let mut me = self.inner.lock().unwrap();
|
||||||
@@ -120,12 +119,12 @@ impl<P, B> Streams<P, B>
|
|||||||
None => return Err(ProtocolError.into()),
|
None => return Err(ProtocolError.into()),
|
||||||
};
|
};
|
||||||
|
|
||||||
me.actions.transition(stream, |actions, stream| {
|
me.actions.transition::<P, _, _>(stream, |actions, stream| {
|
||||||
actions.recv.recv_data(frame, stream)
|
actions.recv.recv_data(frame, stream)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn recv_reset(&mut self, frame: frame::Reset)
|
pub fn recv_reset<P: Peer>(&mut self, frame: frame::Reset)
|
||||||
-> Result<(), ConnectionError>
|
-> Result<(), ConnectionError>
|
||||||
{
|
{
|
||||||
let mut me = self.inner.lock().unwrap();
|
let mut me = self.inner.lock().unwrap();
|
||||||
@@ -139,7 +138,7 @@ impl<P, B> Streams<P, B>
|
|||||||
None => return Ok(()),
|
None => return Ok(()),
|
||||||
};
|
};
|
||||||
|
|
||||||
me.actions.transition(stream, |actions, stream| {
|
me.actions.transition::<P, _, _>(stream, |actions, stream| {
|
||||||
actions.recv.recv_reset(frame, stream)?;
|
actions.recv.recv_reset(frame, stream)?;
|
||||||
assert!(stream.state.is_closed());
|
assert!(stream.state.is_closed());
|
||||||
Ok(())
|
Ok(())
|
||||||
@@ -173,7 +172,7 @@ impl<P, B> Streams<P, B>
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn recv_push_promise(&mut self, frame: frame::PushPromise)
|
pub fn recv_push_promise<P: Peer>(&mut self, frame: frame::PushPromise)
|
||||||
-> Result<(), ConnectionError>
|
-> Result<(), ConnectionError>
|
||||||
{
|
{
|
||||||
let mut me = self.inner.lock().unwrap();
|
let mut me = self.inner.lock().unwrap();
|
||||||
@@ -186,7 +185,7 @@ impl<P, B> Streams<P, B>
|
|||||||
None => return Err(ProtocolError.into()),
|
None => return Err(ProtocolError.into()),
|
||||||
};
|
};
|
||||||
|
|
||||||
me.actions.recv.recv_push_promise(frame, &mut stream)
|
me.actions.recv.recv_push_promise::<P>(frame, &mut stream)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn send_headers(&mut self, headers: frame::Headers)
|
pub fn send_headers(&mut self, headers: frame::Headers)
|
||||||
@@ -274,11 +273,11 @@ impl<P, B> Streams<P, B>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<B> Streams<client::Peer, B>
|
impl<B> Streams<B>
|
||||||
where B: Buf,
|
where B: Buf,
|
||||||
{
|
{
|
||||||
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<B>, ConnectionError>
|
||||||
{
|
{
|
||||||
// TODO: There is a hazard with assigning a stream ID before the
|
// TODO: There is a hazard with assigning a stream ID before the
|
||||||
// prioritize layer. If prioritization reorders new streams, this
|
// prioritize layer. If prioritization reorders new streams, this
|
||||||
@@ -290,7 +289,7 @@ impl<B> Streams<client::Peer, B>
|
|||||||
let me = &mut *me;
|
let me = &mut *me;
|
||||||
|
|
||||||
// Initialize a new stream. This fails if the connection is at capacity.
|
// Initialize a new stream. This fails if the connection is at capacity.
|
||||||
let mut stream = me.actions.send.open()?;
|
let mut stream = me.actions.send.open::<client::Peer>()?;
|
||||||
|
|
||||||
// Convert the message
|
// Convert the message
|
||||||
let headers = client::Peer::convert_send_message(
|
let headers = client::Peer::convert_send_message(
|
||||||
@@ -316,11 +315,10 @@ impl<B> Streams<client::Peer, B>
|
|||||||
|
|
||||||
// ===== impl StreamRef =====
|
// ===== impl StreamRef =====
|
||||||
|
|
||||||
impl<P, B> StreamRef<P, B>
|
impl<B> StreamRef<B>
|
||||||
where P: Peer,
|
where B: Buf,
|
||||||
B: Buf,
|
|
||||||
{
|
{
|
||||||
pub fn send_data(&mut self, data: B, end_of_stream: bool)
|
pub fn send_data<P: Peer>(&mut self, data: B, end_of_stream: bool)
|
||||||
-> Result<(), ConnectionError>
|
-> Result<(), ConnectionError>
|
||||||
{
|
{
|
||||||
let mut me = self.inner.lock().unwrap();
|
let mut me = self.inner.lock().unwrap();
|
||||||
@@ -331,13 +329,22 @@ impl<P, B> StreamRef<P, B>
|
|||||||
// Create the data frame
|
// Create the data frame
|
||||||
let frame = frame::Data::from_buf(stream.id, data, end_of_stream);
|
let frame = frame::Data::from_buf(stream.id, data, end_of_stream);
|
||||||
|
|
||||||
me.actions.transition(stream, |actions, stream| {
|
me.actions.transition::<P, _, _>(stream, |actions, stream| {
|
||||||
// Send the data frame
|
// Send the data frame
|
||||||
actions.send.send_data(frame, stream)
|
actions.send.send_data(frame, stream)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn poll_data(&mut self) -> Poll<Option<Chunk<P, B>>, ConnectionError> {
|
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)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn poll_data(&mut self) -> Poll<Option<Chunk<B>>, ConnectionError> {
|
||||||
let recv = {
|
let recv = {
|
||||||
let mut me = self.inner.lock().unwrap();
|
let mut me = self.inner.lock().unwrap();
|
||||||
let me = &mut *me;
|
let me = &mut *me;
|
||||||
@@ -359,22 +366,7 @@ impl<P, B> StreamRef<P, B>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<B> StreamRef<client::Peer, B>
|
impl<B> Clone for StreamRef<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> Clone for StreamRef<P, B> {
|
|
||||||
fn clone(&self) -> Self {
|
fn clone(&self) -> Self {
|
||||||
StreamRef {
|
StreamRef {
|
||||||
inner: self.inner.clone(),
|
inner: self.inner.clone(),
|
||||||
@@ -385,9 +377,8 @@ impl<P, B> Clone for StreamRef<P, B> {
|
|||||||
|
|
||||||
// ===== impl Chunk =====
|
// ===== impl Chunk =====
|
||||||
|
|
||||||
impl<P, B> Chunk<P, B>
|
impl<B> Chunk<B>
|
||||||
where P: Peer,
|
where B: Buf,
|
||||||
B: Buf,
|
|
||||||
{
|
{
|
||||||
// TODO: Come up w/ a better API
|
// TODO: Come up w/ a better API
|
||||||
pub fn pop_bytes(&mut self) -> Option<Bytes> {
|
pub fn pop_bytes(&mut self) -> Option<Bytes> {
|
||||||
@@ -398,9 +389,8 @@ impl<P, B> Chunk<P, B>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<P, B> Drop for Chunk<P, B>
|
impl<B> Drop for Chunk<B>
|
||||||
where P: Peer,
|
where B: Buf,
|
||||||
B: Buf,
|
|
||||||
{
|
{
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
let mut me = self.inner.lock().unwrap();
|
let mut me = self.inner.lock().unwrap();
|
||||||
@@ -413,32 +403,32 @@ impl<P, B> Drop for Chunk<P, B>
|
|||||||
|
|
||||||
// ===== impl Actions =====
|
// ===== impl Actions =====
|
||||||
|
|
||||||
impl<P, B> Actions<P, B>
|
impl<B> Actions<B>
|
||||||
where P: Peer,
|
where B: Buf,
|
||||||
B: Buf,
|
|
||||||
{
|
{
|
||||||
fn dec_num_streams(&mut self, id: StreamId) {
|
fn dec_num_streams<P: Peer>(&mut self, id: StreamId) {
|
||||||
if self.is_local_init(id) {
|
if self.is_local_init::<P>(id) {
|
||||||
self.send.dec_num_streams();
|
self.send.dec_num_streams();
|
||||||
} else {
|
} else {
|
||||||
self.recv.dec_num_streams();
|
self.recv.dec_num_streams();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_local_init(&self, id: StreamId) -> bool {
|
fn is_local_init<P: Peer>(&self, id: StreamId) -> bool {
|
||||||
assert!(!id.is_zero());
|
assert!(!id.is_zero());
|
||||||
P::is_server() == id.is_server_initiated()
|
P::is_server() == id.is_server_initiated()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn transition<F, U>(&mut self, mut stream: store::Ptr<B>, f: F) -> U
|
fn transition<P, F, U>(&mut self, mut stream: store::Ptr<B>, f: F) -> U
|
||||||
where F: FnOnce(&mut Self, &mut store::Ptr<B>) -> U,
|
where F: FnOnce(&mut Self, &mut store::Ptr<B>) -> U,
|
||||||
|
P: Peer,
|
||||||
{
|
{
|
||||||
let is_counted = stream.state.is_counted();
|
let is_counted = stream.state.is_counted();
|
||||||
|
|
||||||
let ret = f(self, &mut stream);
|
let ret = f(self, &mut stream);
|
||||||
|
|
||||||
if is_counted && stream.state.is_closed() {
|
if is_counted && stream.state.is_closed() {
|
||||||
self.dec_num_streams(stream.id);
|
self.dec_num_streams::<P>(stream.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
ret
|
ret
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
#![allow(warnings)]
|
|
||||||
|
|
||||||
use {frame, proto, Peer, ConnectionError, StreamId};
|
use {frame, proto, Peer, ConnectionError, StreamId};
|
||||||
|
|
||||||
use http;
|
use http;
|
||||||
@@ -12,14 +10,19 @@ use std::fmt;
|
|||||||
/// In progress H2 connection binding
|
/// In progress H2 connection binding
|
||||||
pub struct Handshake<T, B: IntoBuf = Bytes> {
|
pub struct Handshake<T, B: IntoBuf = Bytes> {
|
||||||
// TODO: unbox
|
// TODO: unbox
|
||||||
inner: Box<Future<Item = Connection<T, B>, Error = ConnectionError>>,
|
inner: Box<Future<Item = Server<T, B>, Error = ConnectionError>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Marker type indicating a client peer
|
/// Marker type indicating a client peer
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Server;
|
pub struct Server<T, B: IntoBuf> {
|
||||||
|
connection: Connection<T, Peer, B>,
|
||||||
|
}
|
||||||
|
|
||||||
pub type Connection<T, B = Bytes> = super::Connection<T, Server, B>;
|
#[derive(Debug)]
|
||||||
|
pub struct Stream<B: IntoBuf> {
|
||||||
|
inner: proto::StreamRef<Peer, B::Buf>,
|
||||||
|
}
|
||||||
|
|
||||||
/// Flush a Sink
|
/// Flush a Sink
|
||||||
struct Flush<T> {
|
struct Flush<T> {
|
||||||
|
|||||||
Reference in New Issue
Block a user