Refactor errors (#46)
This patch does a bunch of refactoring, mostly around error types, but it also
paves the way to allow `Codec` to be used standalone.
* `Codec` (and `FramedRead` / `FramedWrite`) is broken out into a codec module.
* An h2-codec crate is created that re-exports the frame and codec modules.
* New error types are introduced in the internals:
* `RecvError` represents errors caused by trying to receive a frame.
* `SendError` represents errors caused by trying to send a frame.
* `UserError` is an enum of potential errors caused by invalid usage
by the user of the lib.
* `ProtoError` is either a `Reason` or an `io::Error`. However it doesn't
specify connection or stream level.
* `h2::Error` is an opaque error type and is the only error type exposed
by the public API (used to be `ConnectionError`).
There are misc code changes to enable this as well. The biggest is a new "sink"
API for `Codec`. It provides buffer which queues up a frame followed by flush
which writes everything that is queued. This departs from the `Sink` trait in
order to provide more accurate error values. For example, buffer can never fail
(but it will panic if `poll_ready` is not called first).
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
use ConnectionError;
|
||||
use frame::Reason;
|
||||
use frame::Reason::*;
|
||||
use proto::*;
|
||||
use error::Reason::*;
|
||||
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
pub struct FlowControl {
|
||||
@@ -67,15 +67,15 @@ impl FlowControl {
|
||||
/// Increase the window size.
|
||||
///
|
||||
/// This is called after receiving a WINDOW_UPDATE frame
|
||||
pub fn inc_window(&mut self, sz: WindowSize) -> Result<(), ConnectionError> {
|
||||
pub fn inc_window(&mut self, sz: WindowSize) -> Result<(), Reason> {
|
||||
let (val, overflow) = self.window_size.overflowing_add(sz as i32);
|
||||
|
||||
if overflow {
|
||||
return Err(FlowControlError.into());
|
||||
return Err(FlowControlError);
|
||||
}
|
||||
|
||||
if val > MAX_WINDOW_SIZE as i32 {
|
||||
return Err(FlowControlError.into());
|
||||
return Err(FlowControlError);
|
||||
}
|
||||
|
||||
trace!("inc_window; sz={}; old={}; new={}", sz, self.window_size, val);
|
||||
|
||||
@@ -20,11 +20,9 @@ use self::state::State;
|
||||
use self::store::{Store, Entry};
|
||||
use self::stream::Stream;
|
||||
|
||||
use {frame, ConnectionError};
|
||||
use frame::StreamId;
|
||||
use proto::*;
|
||||
use error::Reason::*;
|
||||
use error::User::*;
|
||||
|
||||
use http::{Request, Response};
|
||||
use bytes::Bytes;
|
||||
|
||||
@@ -1,9 +1,14 @@
|
||||
use super::*;
|
||||
use super::store::Resolve;
|
||||
|
||||
use bytes::buf::Take;
|
||||
use futures::Sink;
|
||||
use frame::Reason;
|
||||
|
||||
use codec::UserError;
|
||||
use codec::UserError::*;
|
||||
|
||||
use bytes::buf::Take;
|
||||
|
||||
use std::io;
|
||||
use std::{fmt, cmp};
|
||||
|
||||
#[derive(Debug)]
|
||||
@@ -80,7 +85,7 @@ impl<B, P> Prioritize<B, P>
|
||||
frame: frame::Data<B>,
|
||||
stream: &mut store::Ptr<B, P>,
|
||||
task: &mut Option<Task>)
|
||||
-> Result<(), ConnectionError>
|
||||
-> Result<(), UserError>
|
||||
{
|
||||
let sz = frame.payload().remaining();
|
||||
|
||||
@@ -93,9 +98,9 @@ impl<B, P> Prioritize<B, P>
|
||||
|
||||
if !stream.state.is_send_streaming() {
|
||||
if stream.state.is_closed() {
|
||||
return Err(InactiveStreamId.into());
|
||||
return Err(InactiveStreamId);
|
||||
} else {
|
||||
return Err(UnexpectedFrameType.into());
|
||||
return Err(UnexpectedFrameType);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -115,7 +120,7 @@ impl<B, P> Prioritize<B, P>
|
||||
}
|
||||
|
||||
if frame.is_end_stream() {
|
||||
try!(stream.state.send_close());
|
||||
stream.state.send_close();
|
||||
}
|
||||
|
||||
trace!("send_data (2); available={}; buffered={}",
|
||||
@@ -161,7 +166,7 @@ impl<B, P> Prioritize<B, P>
|
||||
pub fn recv_stream_window_update(&mut self,
|
||||
inc: WindowSize,
|
||||
stream: &mut store::Ptr<B, P>)
|
||||
-> Result<(), ConnectionError>
|
||||
-> Result<(), Reason>
|
||||
{
|
||||
trace!("recv_stream_window_update; stream={:?}; state={:?}; inc={}; flow={:?}",
|
||||
stream.id, stream.state, inc, stream.send_flow);
|
||||
@@ -179,7 +184,7 @@ impl<B, P> Prioritize<B, P>
|
||||
pub fn recv_connection_window_update(&mut self,
|
||||
inc: WindowSize,
|
||||
store: &mut Store<B, P>)
|
||||
-> Result<(), ConnectionError>
|
||||
-> Result<(), Reason>
|
||||
{
|
||||
// Update the connection's window
|
||||
self.flow.inc_window(inc)?;
|
||||
@@ -284,7 +289,7 @@ impl<B, P> Prioritize<B, P>
|
||||
pub fn poll_complete<T>(&mut self,
|
||||
store: &mut Store<B, P>,
|
||||
dst: &mut Codec<T, Prioritized<B>>)
|
||||
-> Poll<(), ConnectionError>
|
||||
-> Poll<(), io::Error>
|
||||
where T: AsyncWrite,
|
||||
{
|
||||
// Ensure codec is ready
|
||||
@@ -303,22 +308,17 @@ impl<B, P> Prioritize<B, P>
|
||||
Some(frame) => {
|
||||
trace!("writing frame={:?}", frame);
|
||||
|
||||
let res = dst.start_send(frame)?;
|
||||
|
||||
// We already verified that `dst` is ready to accept the
|
||||
// write
|
||||
assert!(res.is_ready());
|
||||
dst.buffer(frame).ok().expect("invalid frame");
|
||||
|
||||
// Ensure the codec is ready to try the loop again.
|
||||
try_ready!(dst.poll_ready());
|
||||
|
||||
// Because, always try to reclaim...
|
||||
self.reclaim_frame(store, dst);
|
||||
|
||||
}
|
||||
None => {
|
||||
// Try to flush the codec.
|
||||
try_ready!(dst.poll_complete());
|
||||
try_ready!(dst.flush());
|
||||
|
||||
// This might release a data frame...
|
||||
if !self.reclaim_frame(store, dst) {
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
use {client, server, frame, HeaderMap, ConnectionError};
|
||||
use {client, server, frame, proto};
|
||||
use frame::Reason;
|
||||
use codec::{RecvError, UserError};
|
||||
use proto::*;
|
||||
use super::*;
|
||||
|
||||
use error::Reason::*;
|
||||
use futures::Sink;
|
||||
use http::HeaderMap;
|
||||
|
||||
use std::io;
|
||||
use std::marker::PhantomData;
|
||||
|
||||
#[derive(Debug)]
|
||||
@@ -41,14 +43,14 @@ pub(super) struct Recv<B, P>
|
||||
/// Refused StreamId, this represents a frame that must be sent out.
|
||||
refused: Option<StreamId>,
|
||||
|
||||
_p: PhantomData<(B)>,
|
||||
_p: PhantomData<B>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub(super) enum Event<T> {
|
||||
Headers(T),
|
||||
Data(Bytes),
|
||||
Trailers(::HeaderMap),
|
||||
Trailers(HeaderMap),
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
@@ -103,7 +105,7 @@ impl<B, P> Recv<B, P>
|
||||
///
|
||||
/// Returns the stream state if successful. `None` if refused
|
||||
pub fn open(&mut self, id: StreamId)
|
||||
-> Result<Option<StreamId>, ConnectionError>
|
||||
-> Result<Option<StreamId>, RecvError>
|
||||
{
|
||||
assert!(self.refused.is_none());
|
||||
|
||||
@@ -123,7 +125,7 @@ impl<B, P> Recv<B, P>
|
||||
pub fn recv_headers(&mut self,
|
||||
frame: frame::Headers,
|
||||
stream: &mut store::Ptr<B, P>)
|
||||
-> Result<(), ProtoError>
|
||||
-> Result<(), RecvError>
|
||||
{
|
||||
trace!("opening stream; init_window={}", self.init_window_sz);
|
||||
let is_initial = stream.state.recv_open(frame.is_end_stream())?;
|
||||
@@ -137,7 +139,7 @@ impl<B, P> Recv<B, P>
|
||||
self.next_stream_id = frame.stream_id();
|
||||
self.next_stream_id.increment();
|
||||
} else {
|
||||
return Err(ProtoError::Connection(ProtocolError));
|
||||
return Err(RecvError::Connection(ProtocolError));
|
||||
}
|
||||
|
||||
// TODO: be smarter about this logic
|
||||
@@ -184,13 +186,13 @@ impl<B, P> Recv<B, P>
|
||||
pub fn recv_trailers(&mut self,
|
||||
frame: frame::Headers,
|
||||
stream: &mut store::Ptr<B, P>)
|
||||
-> Result<(), ProtoError>
|
||||
-> Result<(), RecvError>
|
||||
{
|
||||
// Transition the state
|
||||
stream.state.recv_close()?;
|
||||
|
||||
if stream.ensure_content_length_zero().is_err() {
|
||||
return Err(ProtoError::Stream {
|
||||
return Err(RecvError::Stream {
|
||||
id: stream.id,
|
||||
reason: ProtocolError,
|
||||
});
|
||||
@@ -205,11 +207,12 @@ impl<B, P> Recv<B, P>
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Releases capacity back to the connection
|
||||
pub fn release_capacity(&mut self,
|
||||
capacity: WindowSize,
|
||||
stream: &mut store::Ptr<B, P>,
|
||||
task: &mut Option<Task>)
|
||||
-> Result<(), ConnectionError>
|
||||
-> Result<(), UserError>
|
||||
{
|
||||
if capacity > stream.in_flight_recv_data {
|
||||
// TODO: Handle error
|
||||
@@ -246,7 +249,7 @@ impl<B, P> Recv<B, P>
|
||||
pub fn recv_data(&mut self,
|
||||
frame: frame::Data,
|
||||
stream: &mut store::Ptr<B, P>)
|
||||
-> Result<(), ProtoError>
|
||||
-> Result<(), RecvError>
|
||||
{
|
||||
let sz = frame.payload().len();
|
||||
|
||||
@@ -259,7 +262,7 @@ impl<B, P> Recv<B, P>
|
||||
if !stream.state.is_recv_streaming() {
|
||||
// Receiving a DATA frame when not expecting one is a protocol
|
||||
// error.
|
||||
return Err(ProtoError::Connection(ProtocolError));
|
||||
return Err(RecvError::Connection(ProtocolError));
|
||||
}
|
||||
|
||||
trace!("recv_data; size={}; connection={}; stream={}",
|
||||
@@ -268,7 +271,7 @@ impl<B, P> Recv<B, P>
|
||||
// Ensure that there is enough capacity on the connection before acting
|
||||
// on the stream.
|
||||
if self.flow.window_size() < sz || stream.recv_flow.window_size() < sz {
|
||||
return Err(ProtoError::Connection(FlowControlError));
|
||||
return Err(RecvError::Connection(FlowControlError));
|
||||
}
|
||||
|
||||
// Update connection level flow control
|
||||
@@ -281,7 +284,7 @@ impl<B, P> Recv<B, P>
|
||||
stream.in_flight_recv_data += sz;
|
||||
|
||||
if stream.dec_content_length(frame.payload().len()).is_err() {
|
||||
return Err(ProtoError::Stream {
|
||||
return Err(RecvError::Stream {
|
||||
id: stream.id,
|
||||
reason: ProtocolError,
|
||||
});
|
||||
@@ -289,14 +292,14 @@ impl<B, P> Recv<B, P>
|
||||
|
||||
if frame.is_end_stream() {
|
||||
if stream.ensure_content_length_zero().is_err() {
|
||||
return Err(ProtoError::Stream {
|
||||
return Err(RecvError::Stream {
|
||||
id: stream.id,
|
||||
reason: ProtocolError,
|
||||
});
|
||||
}
|
||||
|
||||
if stream.state.recv_close().is_err() {
|
||||
return Err(ProtoError::Connection(ProtocolError));
|
||||
return Err(RecvError::Connection(ProtocolError));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -314,13 +317,14 @@ impl<B, P> Recv<B, P>
|
||||
send: &Send<B, P>,
|
||||
stream: store::Key,
|
||||
store: &mut Store<B, P>)
|
||||
-> Result<(), ConnectionError>
|
||||
-> Result<(), RecvError>
|
||||
{
|
||||
// First, make sure that the values are legit
|
||||
self.ensure_can_reserve(frame.promised_id())?;
|
||||
|
||||
// Make sure that the stream state is valid
|
||||
store[stream].state.ensure_recv_open()?;
|
||||
store[stream].state.ensure_recv_open()
|
||||
.map_err(|e| e.into_connection_recv_error())?;
|
||||
|
||||
// TODO: Streams in the reserved states do not count towards the concurrency
|
||||
// limit. However, it seems like there should be a cap otherwise this
|
||||
@@ -361,18 +365,19 @@ impl<B, P> Recv<B, P>
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn ensure_not_idle(&self, id: StreamId) -> Result<(), ConnectionError> {
|
||||
/// Ensures that `id` is not in the `Idle` state.
|
||||
pub fn ensure_not_idle(&self, id: StreamId) -> Result<(), Reason> {
|
||||
if id >= self.next_stream_id {
|
||||
return Err(ProtocolError.into());
|
||||
return Err(ProtocolError);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn recv_reset(&mut self, frame: frame::Reset, stream: &mut Stream<B, P>)
|
||||
-> Result<(), ConnectionError>
|
||||
-> Result<(), RecvError>
|
||||
{
|
||||
let err = ConnectionError::Proto(frame.reason());
|
||||
let err = proto::Error::Proto(frame.reason());
|
||||
|
||||
// Notify the stream
|
||||
stream.state.recv_err(&err);
|
||||
@@ -381,7 +386,7 @@ impl<B, P> Recv<B, P>
|
||||
}
|
||||
|
||||
/// Handle a received error
|
||||
pub fn recv_err(&mut self, err: &ConnectionError, stream: &mut Stream<B, P>) {
|
||||
pub fn recv_err(&mut self, err: &proto::Error, stream: &mut Stream<B, P>) {
|
||||
// Receive an error
|
||||
stream.state.recv_err(err);
|
||||
|
||||
@@ -415,17 +420,17 @@ impl<B, P> Recv<B, P>
|
||||
|
||||
/// Returns true if the remote peer can initiate a stream with the given ID.
|
||||
fn ensure_can_open(&self, id: StreamId)
|
||||
-> Result<(), ConnectionError>
|
||||
-> Result<(), RecvError>
|
||||
{
|
||||
if !P::is_server() {
|
||||
// Remote is a server and cannot open streams. PushPromise is
|
||||
// registered by reserving, so does not go through this path.
|
||||
return Err(ProtocolError.into());
|
||||
return Err(RecvError::Connection(ProtocolError));
|
||||
}
|
||||
|
||||
// Ensure that the ID is a valid server initiated ID
|
||||
if !id.is_client_initiated() {
|
||||
return Err(ProtocolError.into());
|
||||
return Err(RecvError::Connection(ProtocolError));
|
||||
}
|
||||
|
||||
Ok(())
|
||||
@@ -433,16 +438,16 @@ impl<B, P> Recv<B, P>
|
||||
|
||||
/// Returns true if the remote peer can reserve a stream with the given ID.
|
||||
fn ensure_can_reserve(&self, promised_id: StreamId)
|
||||
-> Result<(), ConnectionError>
|
||||
-> Result<(), RecvError>
|
||||
{
|
||||
// TODO: Are there other rules?
|
||||
if P::is_server() {
|
||||
// The remote is a client and cannot reserve
|
||||
return Err(ProtocolError.into());
|
||||
return Err(RecvError::Connection(ProtocolError));
|
||||
}
|
||||
|
||||
if !promised_id.is_server_initiated() {
|
||||
return Err(ProtocolError.into());
|
||||
return Err(RecvError::Connection(ProtocolError));
|
||||
}
|
||||
|
||||
Ok(())
|
||||
@@ -450,31 +455,28 @@ impl<B, P> Recv<B, P>
|
||||
|
||||
/// Send any pending refusals.
|
||||
pub fn send_pending_refusal<T>(&mut self, dst: &mut Codec<T, Prioritized<B>>)
|
||||
-> Poll<(), ConnectionError>
|
||||
-> Poll<(), io::Error>
|
||||
where T: AsyncWrite,
|
||||
{
|
||||
if let Some(stream_id) = self.refused.take() {
|
||||
if let Some(stream_id) = self.refused {
|
||||
try_ready!(dst.poll_ready());
|
||||
|
||||
// Create the RST_STREAM frame
|
||||
let frame = frame::Reset::new(stream_id, RefusedStream);
|
||||
|
||||
match dst.start_send(frame.into())? {
|
||||
AsyncSink::Ready => {
|
||||
self.reset(stream_id, RefusedStream);
|
||||
return Ok(Async::Ready(()));
|
||||
}
|
||||
AsyncSink::NotReady(_) => {
|
||||
self.refused = Some(stream_id);
|
||||
return Ok(Async::NotReady);
|
||||
}
|
||||
}
|
||||
// Buffer the frame
|
||||
dst.buffer(frame.into()).ok().expect("invalid RST_STREAM frame");
|
||||
}
|
||||
|
||||
self.refused = None;
|
||||
|
||||
Ok(Async::Ready(()))
|
||||
}
|
||||
|
||||
pub fn poll_complete<T>(&mut self,
|
||||
store: &mut Store<B, P>,
|
||||
dst: &mut Codec<T, Prioritized<B>>)
|
||||
-> Poll<(), ConnectionError>
|
||||
-> Poll<(), io::Error>
|
||||
where T: AsyncWrite,
|
||||
{
|
||||
// Send any pending connection level window updates
|
||||
@@ -488,7 +490,7 @@ impl<B, P> Recv<B, P>
|
||||
|
||||
/// Send connection level window update
|
||||
fn send_connection_window_update<T>(&mut self, dst: &mut Codec<T, Prioritized<B>>)
|
||||
-> Poll<(), ConnectionError>
|
||||
-> Poll<(), io::Error>
|
||||
where T: AsyncWrite,
|
||||
{
|
||||
let incr = self.flow.unclaimed_capacity();
|
||||
@@ -496,11 +498,14 @@ impl<B, P> Recv<B, P>
|
||||
if incr > 0 {
|
||||
let frame = frame::WindowUpdate::new(StreamId::zero(), incr);
|
||||
|
||||
if dst.start_send(frame.into())?.is_ready() {
|
||||
self.flow.inc_window(incr).ok().expect("unexpected flow control state");
|
||||
} else {
|
||||
return Ok(Async::NotReady);
|
||||
}
|
||||
// Ensure the codec has capacity
|
||||
try_ready!(dst.poll_ready());
|
||||
|
||||
// Buffer the WINDOW_UPDATE frame
|
||||
dst.buffer(frame.into()).ok().expect("invalid WINDOW_UPDATE frame");
|
||||
|
||||
// Update flow control
|
||||
self.flow.inc_window(incr).ok().expect("unexpected flow control state");
|
||||
}
|
||||
|
||||
Ok(().into())
|
||||
@@ -511,7 +516,7 @@ impl<B, P> Recv<B, P>
|
||||
pub fn send_stream_window_updates<T>(&mut self,
|
||||
store: &mut Store<B, P>,
|
||||
dst: &mut Codec<T, Prioritized<B>>)
|
||||
-> Poll<(), ConnectionError>
|
||||
-> Poll<(), io::Error>
|
||||
where T: AsyncWrite,
|
||||
{
|
||||
loop {
|
||||
@@ -534,10 +539,11 @@ impl<B, P> Recv<B, P>
|
||||
let incr = stream.recv_flow.unclaimed_capacity();
|
||||
|
||||
if incr > 0 {
|
||||
// Create the WINDOW_UPDATE frame
|
||||
let frame = frame::WindowUpdate::new(stream.id, incr);
|
||||
let res = dst.start_send(frame.into())?;
|
||||
|
||||
assert!(res.is_ready());
|
||||
// Buffer it
|
||||
dst.buffer(frame.into()).ok().expect("invalid WINDOW_UPDATE frame");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -548,8 +554,9 @@ impl<B, P> Recv<B, P>
|
||||
}
|
||||
|
||||
pub fn poll_data(&mut self, stream: &mut Stream<B, P>)
|
||||
-> Poll<Option<Bytes>, ConnectionError>
|
||||
-> Poll<Option<Bytes>, proto::Error>
|
||||
{
|
||||
// TODO: Return error when the stream is reset
|
||||
match stream.pending_recv.pop_front(&mut self.buffer) {
|
||||
Some(Event::Data(payload)) => {
|
||||
Ok(Some(payload).into())
|
||||
@@ -575,7 +582,7 @@ impl<B, P> Recv<B, P>
|
||||
}
|
||||
|
||||
pub fn poll_trailers(&mut self, stream: &mut Stream<B, P>)
|
||||
-> Poll<Option<HeaderMap>, ConnectionError>
|
||||
-> Poll<Option<HeaderMap>, proto::Error>
|
||||
{
|
||||
match stream.pending_recv.pop_front(&mut self.buffer) {
|
||||
Some(Event::Trailers(trailers)) => {
|
||||
@@ -599,10 +606,6 @@ impl<B, P> Recv<B, P>
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn reset(&mut self, _stream_id: StreamId, _reason: Reason) {
|
||||
unimplemented!();
|
||||
}
|
||||
}
|
||||
|
||||
impl<B> Recv<B, server::Peer>
|
||||
@@ -610,15 +613,10 @@ impl<B> Recv<B, server::Peer>
|
||||
{
|
||||
/// TODO: Should this fn return `Result`?
|
||||
pub fn take_request(&mut self, stream: &mut store::Ptr<B, server::Peer>)
|
||||
-> Result<Request<()>, ConnectionError>
|
||||
-> Request<()>
|
||||
{
|
||||
match stream.pending_recv.pop_front(&mut self.buffer) {
|
||||
Some(Event::Headers(request)) => Ok(request),
|
||||
/*
|
||||
// TODO: This error should probably be caught on receipt of the
|
||||
// frame vs. now.
|
||||
Ok(server::Peer::convert_poll_message(frame)?)
|
||||
*/
|
||||
Some(Event::Headers(request)) => request,
|
||||
_ => panic!(),
|
||||
}
|
||||
}
|
||||
@@ -628,7 +626,7 @@ impl<B> Recv<B, client::Peer>
|
||||
where B: Buf,
|
||||
{
|
||||
pub fn poll_response(&mut self, stream: &mut store::Ptr<B, client::Peer>)
|
||||
-> Poll<Response<()>, ConnectionError> {
|
||||
-> Poll<Response<()>, proto::Error> {
|
||||
// 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) {
|
||||
|
||||
@@ -1,11 +1,14 @@
|
||||
use {frame, ConnectionError};
|
||||
use client;
|
||||
use frame::{self, Reason};
|
||||
use codec::{RecvError, UserError};
|
||||
use codec::UserError::*;
|
||||
use proto::*;
|
||||
use super::*;
|
||||
|
||||
use error::User::*;
|
||||
|
||||
use bytes::Buf;
|
||||
|
||||
use std::io;
|
||||
|
||||
/// Manages state transitions related to outbound frames.
|
||||
#[derive(Debug)]
|
||||
pub(super) struct Send<B, P>
|
||||
@@ -53,24 +56,11 @@ where B: Buf,
|
||||
self.init_window_sz
|
||||
}
|
||||
|
||||
pub fn poll_open_ready(&mut self) -> Poll<(), ConnectionError> {
|
||||
try!(self.ensure_can_open());
|
||||
|
||||
if let Some(max) = self.max_streams {
|
||||
if max <= self.num_streams {
|
||||
self.blocked_open = Some(task::current());
|
||||
return Ok(Async::NotReady);
|
||||
}
|
||||
}
|
||||
|
||||
return Ok(Async::Ready(()));
|
||||
}
|
||||
|
||||
/// Update state reflecting a new, locally opened stream
|
||||
///
|
||||
/// Returns the stream state if successful. `None` if refused
|
||||
pub fn open(&mut self)
|
||||
-> Result<StreamId, ConnectionError>
|
||||
-> Result<StreamId, UserError>
|
||||
{
|
||||
try!(self.ensure_can_open());
|
||||
|
||||
@@ -93,7 +83,7 @@ where B: Buf,
|
||||
frame: frame::Headers,
|
||||
stream: &mut store::Ptr<B, P>,
|
||||
task: &mut Option<Task>)
|
||||
-> Result<(), ConnectionError>
|
||||
-> Result<(), UserError>
|
||||
{
|
||||
trace!("send_headers; frame={:?}; init_window={:?}", frame, self.init_window_sz);
|
||||
// Update the state
|
||||
@@ -145,7 +135,7 @@ where B: Buf,
|
||||
frame: frame::Data<B>,
|
||||
stream: &mut store::Ptr<B, P>,
|
||||
task: &mut Option<Task>)
|
||||
-> Result<(), ConnectionError>
|
||||
-> Result<(), UserError>
|
||||
{
|
||||
self.prioritize.send_data(frame, stream, task)
|
||||
}
|
||||
@@ -154,14 +144,14 @@ where B: Buf,
|
||||
frame: frame::Headers,
|
||||
stream: &mut store::Ptr<B, P>,
|
||||
task: &mut Option<Task>)
|
||||
-> Result<(), ConnectionError>
|
||||
-> Result<(), UserError>
|
||||
{
|
||||
// TODO: Should this logic be moved into state.rs?
|
||||
if !stream.state.is_send_streaming() {
|
||||
return Err(UnexpectedFrameType.into());
|
||||
}
|
||||
|
||||
stream.state.send_close()?;
|
||||
stream.state.send_close();
|
||||
|
||||
trace!("send_trailers -- queuing; frame={:?}", frame);
|
||||
self.prioritize.queue_frame(frame.into(), stream, task);
|
||||
@@ -172,7 +162,7 @@ where B: Buf,
|
||||
pub fn poll_complete<T>(&mut self,
|
||||
store: &mut Store<B, P>,
|
||||
dst: &mut Codec<T, Prioritized<B>>)
|
||||
-> Poll<(), ConnectionError>
|
||||
-> Poll<(), io::Error>
|
||||
where T: AsyncWrite,
|
||||
{
|
||||
self.prioritize.poll_complete(store, dst)
|
||||
@@ -184,7 +174,7 @@ where B: Buf,
|
||||
}
|
||||
|
||||
pub fn poll_capacity(&mut self, stream: &mut store::Ptr<B, P>)
|
||||
-> Poll<Option<WindowSize>, ConnectionError>
|
||||
-> Poll<Option<WindowSize>, UserError>
|
||||
{
|
||||
if !stream.state.is_send_streaming() {
|
||||
return Ok(Async::Ready(None));
|
||||
@@ -214,7 +204,7 @@ where B: Buf,
|
||||
pub fn recv_connection_window_update(&mut self,
|
||||
frame: frame::WindowUpdate,
|
||||
store: &mut Store<B, P>)
|
||||
-> Result<(), ConnectionError>
|
||||
-> Result<(), Reason>
|
||||
{
|
||||
self.prioritize.recv_connection_window_update(frame.size_increment(), store)
|
||||
}
|
||||
@@ -223,11 +213,13 @@ where B: Buf,
|
||||
sz: WindowSize,
|
||||
stream: &mut store::Ptr<B, P>,
|
||||
task: &mut Option<Task>)
|
||||
-> Result<(), ConnectionError>
|
||||
-> Result<(), Reason>
|
||||
{
|
||||
if let Err(e) = self.prioritize.recv_stream_window_update(sz, stream) {
|
||||
debug!("recv_stream_window_update !!; err={:?}", e);
|
||||
self.send_reset(FlowControlError.into(), stream, task);
|
||||
|
||||
return Err(e);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
@@ -237,7 +229,7 @@ where B: Buf,
|
||||
settings: &frame::Settings,
|
||||
store: &mut Store<B, P>,
|
||||
task: &mut Option<Task>)
|
||||
-> Result<(), ConnectionError>
|
||||
-> Result<(), RecvError>
|
||||
{
|
||||
if let Some(val) = settings.max_concurrent_streams() {
|
||||
self.max_streams = Some(val as usize);
|
||||
@@ -283,13 +275,14 @@ where B: Buf,
|
||||
|
||||
// TODO: Should this notify the producer?
|
||||
|
||||
Ok(())
|
||||
Ok::<_, RecvError>(())
|
||||
})?;
|
||||
} else if val > old_val {
|
||||
let inc = val - old_val;
|
||||
|
||||
store.for_each(|mut stream| {
|
||||
self.recv_stream_window_update(inc, &mut stream, task)
|
||||
.map_err(RecvError::Connection)
|
||||
})?;
|
||||
}
|
||||
}
|
||||
@@ -297,9 +290,9 @@ where B: Buf,
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn ensure_not_idle(&self, id: StreamId) -> Result<(), ConnectionError> {
|
||||
pub fn ensure_not_idle(&self, id: StreamId) -> Result<(), Reason> {
|
||||
if id >= self.next_stream_id {
|
||||
return Err(ProtocolError.into());
|
||||
return Err(ProtocolError);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
@@ -316,10 +309,10 @@ where B: Buf,
|
||||
}
|
||||
|
||||
/// 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(&self) -> Result<(), UserError> {
|
||||
if P::is_server() {
|
||||
// Servers cannot open streams. PushPromise must first be reserved.
|
||||
return Err(UnexpectedFrameType.into());
|
||||
return Err(UnexpectedFrameType);
|
||||
}
|
||||
|
||||
// TODO: Handle StreamId overflow
|
||||
@@ -327,3 +320,18 @@ where B: Buf,
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl<B> Send<B, client::Peer>
|
||||
where B: Buf,
|
||||
{
|
||||
pub fn poll_open_ready(&mut self) -> Async<()> {
|
||||
if let Some(max) = self.max_streams {
|
||||
if max <= self.num_streams {
|
||||
self.blocked_open = Some(task::current());
|
||||
return Async::NotReady;
|
||||
}
|
||||
}
|
||||
|
||||
return Async::Ready(());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
use ConnectionError;
|
||||
use proto::ProtoError;
|
||||
use error::Reason;
|
||||
use error::Reason::*;
|
||||
use error::User::*;
|
||||
use frame::Reason;
|
||||
use frame::Reason::*;
|
||||
use codec::{RecvError, UserError};
|
||||
use codec::UserError::*;
|
||||
use proto;
|
||||
|
||||
use self::Inner::*;
|
||||
use self::Peer::*;
|
||||
@@ -82,7 +82,7 @@ enum Cause {
|
||||
|
||||
impl State {
|
||||
/// Opens the send-half of a stream if it is not already open.
|
||||
pub fn send_open(&mut self, eos: bool) -> Result<(), ConnectionError> {
|
||||
pub fn send_open(&mut self, eos: bool) -> Result<(), UserError> {
|
||||
let local = Peer::Streaming;
|
||||
|
||||
self.inner = match self.inner {
|
||||
@@ -115,7 +115,7 @@ impl State {
|
||||
}
|
||||
_ => {
|
||||
// All other transitions result in a protocol error
|
||||
return Err(UnexpectedFrameType.into());
|
||||
return Err(UnexpectedFrameType);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -126,7 +126,7 @@ impl State {
|
||||
/// frame is received.
|
||||
///
|
||||
/// Returns true if this transitions the state to Open
|
||||
pub fn recv_open(&mut self, eos: bool) -> Result<bool, ProtoError> {
|
||||
pub fn recv_open(&mut self, eos: bool) -> Result<bool, RecvError> {
|
||||
let remote = Peer::Streaming;
|
||||
let mut initial = false;
|
||||
|
||||
@@ -174,7 +174,7 @@ impl State {
|
||||
}
|
||||
_ => {
|
||||
// All other transitions result in a protocol error
|
||||
return Err(ProtoError::Connection(ProtocolError));
|
||||
return Err(RecvError::Connection(ProtocolError));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -182,18 +182,18 @@ impl State {
|
||||
}
|
||||
|
||||
/// Transition from Idle -> ReservedRemote
|
||||
pub fn reserve_remote(&mut self) -> Result<(), ConnectionError> {
|
||||
pub fn reserve_remote(&mut self) -> Result<(), RecvError> {
|
||||
match self.inner {
|
||||
Idle => {
|
||||
self.inner = ReservedRemote;
|
||||
Ok(())
|
||||
}
|
||||
_ => Err(ProtocolError.into()),
|
||||
_ => Err(RecvError::Connection(ProtocolError)),
|
||||
}
|
||||
}
|
||||
|
||||
/// Indicates that the remote side will not send more data to the local.
|
||||
pub fn recv_close(&mut self) -> Result<(), ProtoError> {
|
||||
pub fn recv_close(&mut self) -> Result<(), RecvError> {
|
||||
match self.inner {
|
||||
Open { local, .. } => {
|
||||
// The remote side will continue to receive data.
|
||||
@@ -206,39 +206,38 @@ impl State {
|
||||
self.inner = Closed(None);
|
||||
Ok(())
|
||||
}
|
||||
_ => Err(ProtoError::Connection(ProtocolError)),
|
||||
_ => Err(RecvError::Connection(ProtocolError)),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn recv_err(&mut self, err: &ConnectionError) {
|
||||
pub fn recv_err(&mut self, err: &proto::Error) {
|
||||
use proto::Error::*;
|
||||
|
||||
match self.inner {
|
||||
Closed(..) => {}
|
||||
_ => {
|
||||
trace!("recv_err; err={:?}", err);
|
||||
self.inner = Closed(match *err {
|
||||
ConnectionError::Proto(reason) => Some(Cause::Proto(reason)),
|
||||
ConnectionError::Io(..) => Some(Cause::Io),
|
||||
ref e => panic!("cannot terminate stream with user error; err={:?}", e),
|
||||
Proto(reason) => Some(Cause::Proto(reason)),
|
||||
Io(..) => Some(Cause::Io),
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Indicates that the local side will not send more data to the local.
|
||||
pub fn send_close(&mut self) -> Result<(), ConnectionError> {
|
||||
pub fn send_close(&mut self) {
|
||||
match self.inner {
|
||||
Open { remote, .. } => {
|
||||
// The remote side will continue to receive data.
|
||||
trace!("send_close: Open => HalfClosedLocal({:?})", remote);
|
||||
self.inner = HalfClosedLocal(remote);
|
||||
Ok(())
|
||||
}
|
||||
HalfClosedRemote(..) => {
|
||||
trace!("send_close: HalfClosedRemote => Closed");
|
||||
self.inner = Closed(None);
|
||||
Ok(())
|
||||
}
|
||||
_ => Err(ProtocolError.into()),
|
||||
_ => panic!("transition send_close on unexpected state"),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -307,16 +306,16 @@ impl State {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn ensure_recv_open(&self) -> Result<(), ConnectionError> {
|
||||
pub fn ensure_recv_open(&self) -> Result<(), proto::Error> {
|
||||
use std::io;
|
||||
|
||||
// TODO: Is this correct?
|
||||
match self.inner {
|
||||
Closed(Some(Cause::Proto(reason))) => {
|
||||
Err(ConnectionError::Proto(reason))
|
||||
Err(proto::Error::Proto(reason))
|
||||
}
|
||||
Closed(Some(Cause::Io)) => {
|
||||
Err(ConnectionError::Io(io::ErrorKind::BrokenPipe.into()))
|
||||
Err(proto::Error::Io(io::ErrorKind::BrokenPipe.into()))
|
||||
}
|
||||
_ => Ok(()),
|
||||
}
|
||||
|
||||
@@ -127,8 +127,8 @@ impl<B, P> Store<B, P>
|
||||
}
|
||||
}
|
||||
|
||||
pub fn for_each<F>(&mut self, mut f: F) -> Result<(), ConnectionError>
|
||||
where F: FnMut(Ptr<B, P>) -> Result<(), ConnectionError>,
|
||||
pub fn for_each<F, E>(&mut self, mut f: F) -> Result<(), E>
|
||||
where F: FnMut(Ptr<B, P>) -> Result<(), E>,
|
||||
{
|
||||
for &key in self.ids.values() {
|
||||
f(Ptr {
|
||||
|
||||
@@ -1,8 +1,13 @@
|
||||
use {client, server, HeaderMap};
|
||||
use {client, server, proto};
|
||||
use frame::Reason;
|
||||
use codec::{SendError, RecvError, UserError};
|
||||
use proto::*;
|
||||
use super::*;
|
||||
use super::store::Resolve;
|
||||
|
||||
use http::HeaderMap;
|
||||
|
||||
use std::io;
|
||||
use std::sync::{Arc, Mutex};
|
||||
|
||||
#[derive(Debug)]
|
||||
@@ -66,7 +71,7 @@ impl<B, P> Streams<B, P>
|
||||
|
||||
/// Process inbound headers
|
||||
pub fn recv_headers(&mut self, frame: frame::Headers)
|
||||
-> Result<(), ConnectionError>
|
||||
-> Result<(), RecvError>
|
||||
{
|
||||
let id = frame.stream_id();
|
||||
let mut me = self.inner.lock().unwrap();
|
||||
@@ -97,7 +102,7 @@ impl<B, P> Streams<B, P>
|
||||
} else {
|
||||
if !frame.is_end_stream() {
|
||||
// TODO: Is this the right error
|
||||
return Err(ProtocolError.into());
|
||||
return Err(RecvError::Connection(ProtocolError));
|
||||
}
|
||||
|
||||
actions.recv.recv_trailers(frame, stream)
|
||||
@@ -105,20 +110,18 @@ impl<B, P> Streams<B, P>
|
||||
|
||||
// TODO: extract this
|
||||
match res {
|
||||
Ok(()) => Ok(()),
|
||||
Err(ProtoError::Connection(reason)) => Err(reason.into()),
|
||||
Err(ProtoError::Stream { reason, .. }) => {
|
||||
Err(RecvError::Stream { reason, .. }) => {
|
||||
// Reset the stream.
|
||||
actions.send.send_reset(reason, stream, &mut actions.task);
|
||||
Ok(())
|
||||
}
|
||||
Err(ProtoError::Io(_)) => unreachable!(),
|
||||
res => res,
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
pub fn recv_data(&mut self, frame: frame::Data)
|
||||
-> Result<(), ConnectionError>
|
||||
-> Result<(), RecvError>
|
||||
{
|
||||
let mut me = self.inner.lock().unwrap();
|
||||
let me = &mut *me;
|
||||
@@ -127,25 +130,23 @@ impl<B, P> Streams<B, P>
|
||||
|
||||
let stream = match me.store.find_mut(&id) {
|
||||
Some(stream) => stream,
|
||||
None => return Err(ProtocolError.into()),
|
||||
None => return Err(RecvError::Connection(ProtocolError)),
|
||||
};
|
||||
|
||||
me.actions.transition(stream, |actions, stream| {
|
||||
match actions.recv.recv_data(frame, stream) {
|
||||
Ok(()) => Ok(()),
|
||||
Err(ProtoError::Connection(reason)) => Err(reason.into()),
|
||||
Err(ProtoError::Stream { reason, .. }) => {
|
||||
Err(RecvError::Stream { reason, .. }) => {
|
||||
// Reset the stream.
|
||||
actions.send.send_reset(reason, stream, &mut actions.task);
|
||||
Ok(())
|
||||
}
|
||||
Err(ProtoError::Io(_)) => unreachable!(),
|
||||
res => res,
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
pub fn recv_reset(&mut self, frame: frame::Reset)
|
||||
-> Result<(), ConnectionError>
|
||||
-> Result<(), RecvError>
|
||||
{
|
||||
let mut me = self.inner.lock().unwrap();
|
||||
let me = &mut *me;
|
||||
@@ -153,14 +154,16 @@ impl<B, P> Streams<B, P>
|
||||
let id = frame.stream_id();
|
||||
|
||||
if id.is_zero() {
|
||||
return Err(ProtocolError.into());
|
||||
return Err(RecvError::Connection(ProtocolError));
|
||||
}
|
||||
|
||||
let stream = match me.store.find_mut(&id) {
|
||||
Some(stream) => stream,
|
||||
None => {
|
||||
// TODO: Are there other error cases?
|
||||
me.actions.ensure_not_idle(id)?;
|
||||
me.actions.ensure_not_idle(id)
|
||||
.map_err(RecvError::Connection)?;
|
||||
|
||||
return Ok(());
|
||||
}
|
||||
};
|
||||
@@ -173,7 +176,7 @@ impl<B, P> Streams<B, P>
|
||||
}
|
||||
|
||||
/// Handle a received error and return the ID of the last processed stream.
|
||||
pub fn recv_err(&mut self, err: &ConnectionError) -> StreamId {
|
||||
pub fn recv_err(&mut self, err: &proto::Error) -> StreamId {
|
||||
let mut me = self.inner.lock().unwrap();
|
||||
let me = &mut *me;
|
||||
|
||||
@@ -182,14 +185,14 @@ impl<B, P> Streams<B, P>
|
||||
|
||||
me.store.for_each(|mut stream| {
|
||||
actions.recv.recv_err(err, &mut *stream);
|
||||
Ok(())
|
||||
Ok::<_, ()>(())
|
||||
}).ok().expect("unexpected error processing error");
|
||||
|
||||
last_processed_id
|
||||
}
|
||||
|
||||
pub fn recv_window_update(&mut self, frame: frame::WindowUpdate)
|
||||
-> Result<(), ConnectionError>
|
||||
-> Result<(), RecvError>
|
||||
{
|
||||
let id = frame.stream_id();
|
||||
let mut me = self.inner.lock().unwrap();
|
||||
@@ -197,15 +200,22 @@ impl<B, P> Streams<B, P>
|
||||
|
||||
if id.is_zero() {
|
||||
me.actions.send.recv_connection_window_update(
|
||||
frame, &mut me.store)?;
|
||||
frame, &mut me.store)
|
||||
.map_err(RecvError::Connection)?;
|
||||
} else {
|
||||
// The remote may send window updates for streams that the local now
|
||||
// considers closed. It's ok...
|
||||
if let Some(mut stream) = me.store.find_mut(&id) {
|
||||
me.actions.send.recv_stream_window_update(
|
||||
frame.size_increment(), &mut stream, &mut me.actions.task)?;
|
||||
// This result is ignored as there is nothing to do when there
|
||||
// is an error. The stream is reset by the function on error and
|
||||
// the error is informational.
|
||||
let _ = me.actions.send.recv_stream_window_update(
|
||||
frame.size_increment(),
|
||||
&mut stream,
|
||||
&mut me.actions.task);
|
||||
} else {
|
||||
me.actions.recv.ensure_not_idle(id)?;
|
||||
me.actions.recv.ensure_not_idle(id)
|
||||
.map_err(RecvError::Connection)?;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -213,7 +223,7 @@ impl<B, P> Streams<B, P>
|
||||
}
|
||||
|
||||
pub fn recv_push_promise(&mut self, frame: frame::PushPromise)
|
||||
-> Result<(), ConnectionError>
|
||||
-> Result<(), RecvError>
|
||||
{
|
||||
let mut me = self.inner.lock().unwrap();
|
||||
let me = &mut *me;
|
||||
@@ -222,7 +232,7 @@ impl<B, P> Streams<B, P>
|
||||
|
||||
let stream = match me.store.find_mut(&id) {
|
||||
Some(stream) => stream.key(),
|
||||
None => return Err(ProtocolError.into()),
|
||||
None => return Err(RecvError::Connection(ProtocolError)),
|
||||
};
|
||||
|
||||
me.actions.recv.recv_push_promise(
|
||||
@@ -246,7 +256,7 @@ impl<B, P> Streams<B, P>
|
||||
}
|
||||
|
||||
pub fn send_pending_refusal<T>(&mut self, dst: &mut Codec<T, Prioritized<B>>)
|
||||
-> Poll<(), ConnectionError>
|
||||
-> Poll<(), io::Error>
|
||||
where T: AsyncWrite,
|
||||
{
|
||||
let mut me = self.inner.lock().unwrap();
|
||||
@@ -255,7 +265,7 @@ impl<B, P> Streams<B, P>
|
||||
}
|
||||
|
||||
pub fn poll_complete<T>(&mut self, dst: &mut Codec<T, Prioritized<B>>)
|
||||
-> Poll<(), ConnectionError>
|
||||
-> Poll<(), io::Error>
|
||||
where T: AsyncWrite,
|
||||
{
|
||||
let mut me = self.inner.lock().unwrap();
|
||||
@@ -277,7 +287,7 @@ impl<B, P> Streams<B, P>
|
||||
}
|
||||
|
||||
pub fn apply_remote_settings(&mut self, frame: &frame::Settings)
|
||||
-> Result<(), ConnectionError>
|
||||
-> Result<(), RecvError>
|
||||
{
|
||||
let mut me = self.inner.lock().unwrap();
|
||||
let me = &mut *me;
|
||||
@@ -286,15 +296,8 @@ impl<B, P> Streams<B, P>
|
||||
frame, &mut me.store, &mut me.actions.task)
|
||||
}
|
||||
|
||||
pub fn poll_send_request_ready(&mut self) -> Poll<(), ConnectionError> {
|
||||
let mut me = self.inner.lock().unwrap();
|
||||
let me = &mut *me;
|
||||
|
||||
me.actions.send.poll_open_ready()
|
||||
}
|
||||
|
||||
pub fn send_request(&mut self, request: Request<()>, end_of_stream: bool)
|
||||
-> Result<StreamRef<B, P>, ConnectionError>
|
||||
-> Result<StreamRef<B, P>, SendError>
|
||||
{
|
||||
use http::method;
|
||||
use super::stream::ContentLength;
|
||||
@@ -370,6 +373,17 @@ impl<B, P> Streams<B, P>
|
||||
}
|
||||
}
|
||||
|
||||
impl<B> Streams<B, client::Peer>
|
||||
where B: Buf,
|
||||
{
|
||||
pub fn poll_send_request_ready(&mut self) -> Async<()> {
|
||||
let mut me = self.inner.lock().unwrap();
|
||||
let me = &mut *me;
|
||||
|
||||
me.actions.send.poll_open_ready()
|
||||
}
|
||||
}
|
||||
|
||||
// ===== impl StreamRef =====
|
||||
|
||||
impl<B, P> StreamRef<B, P>
|
||||
@@ -377,7 +391,7 @@ impl<B, P> StreamRef<B, P>
|
||||
P: Peer,
|
||||
{
|
||||
pub fn send_data(&mut self, data: B, end_of_stream: bool)
|
||||
-> Result<(), ConnectionError>
|
||||
-> Result<(), UserError>
|
||||
{
|
||||
let mut me = self.inner.lock().unwrap();
|
||||
let me = &mut *me;
|
||||
@@ -393,7 +407,8 @@ impl<B, P> StreamRef<B, P>
|
||||
})
|
||||
}
|
||||
|
||||
pub fn send_trailers(&mut self, trailers: HeaderMap) -> Result<(), ConnectionError>
|
||||
pub fn send_trailers(&mut self, trailers: HeaderMap)
|
||||
-> Result<(), UserError>
|
||||
{
|
||||
let mut me = self.inner.lock().unwrap();
|
||||
let me = &mut *me;
|
||||
@@ -420,7 +435,7 @@ impl<B, P> StreamRef<B, P>
|
||||
}
|
||||
|
||||
pub fn send_response(&mut self, response: Response<()>, end_of_stream: bool)
|
||||
-> Result<(), ConnectionError>
|
||||
-> Result<(), UserError>
|
||||
{
|
||||
let mut me = self.inner.lock().unwrap();
|
||||
let me = &mut *me;
|
||||
@@ -444,7 +459,7 @@ impl<B, P> StreamRef<B, P>
|
||||
me.actions.recv.body_is_empty(&stream)
|
||||
}
|
||||
|
||||
pub fn poll_data(&mut self) -> Poll<Option<Bytes>, ConnectionError> {
|
||||
pub fn poll_data(&mut self) -> Poll<Option<Bytes>, proto::Error> {
|
||||
let mut me = self.inner.lock().unwrap();
|
||||
let me = &mut *me;
|
||||
|
||||
@@ -453,7 +468,7 @@ impl<B, P> StreamRef<B, P>
|
||||
me.actions.recv.poll_data(&mut stream)
|
||||
}
|
||||
|
||||
pub fn poll_trailers(&mut self) -> Poll<Option<HeaderMap>, ConnectionError> {
|
||||
pub fn poll_trailers(&mut self) -> Poll<Option<HeaderMap>, proto::Error> {
|
||||
let mut me = self.inner.lock().unwrap();
|
||||
let me = &mut *me;
|
||||
|
||||
@@ -465,7 +480,7 @@ impl<B, P> StreamRef<B, P>
|
||||
/// Releases recv capacity back to the peer. This will result in sending
|
||||
/// WINDOW_UPDATE frames on both the stream and connection.
|
||||
pub fn release_capacity(&mut self, capacity: WindowSize)
|
||||
-> Result<(), ConnectionError>
|
||||
-> Result<(), UserError>
|
||||
{
|
||||
let mut me = self.inner.lock().unwrap();
|
||||
let me = &mut *me;
|
||||
@@ -497,7 +512,7 @@ impl<B, P> StreamRef<B, P>
|
||||
}
|
||||
|
||||
/// Request to be notified when the stream's capacity increases
|
||||
pub fn poll_capacity(&mut self) -> Poll<Option<WindowSize>, ConnectionError> {
|
||||
pub fn poll_capacity(&mut self) -> Poll<Option<WindowSize>, UserError> {
|
||||
let mut me = self.inner.lock().unwrap();
|
||||
let me = &mut *me;
|
||||
|
||||
@@ -517,7 +532,7 @@ impl<B> StreamRef<B, server::Peer>
|
||||
/// # Panics
|
||||
///
|
||||
/// This function panics if the request isn't present.
|
||||
pub fn take_request(&self) -> Result<Request<()>, ConnectionError> {
|
||||
pub fn take_request(&self) -> Request<()> {
|
||||
let mut me = self.inner.lock().unwrap();
|
||||
let me = &mut *me;
|
||||
|
||||
@@ -529,7 +544,7 @@ impl<B> StreamRef<B, server::Peer>
|
||||
impl<B> StreamRef<B, client::Peer>
|
||||
where B: Buf,
|
||||
{
|
||||
pub fn poll_response(&mut self) -> Poll<Response<()>, ConnectionError> {
|
||||
pub fn poll_response(&mut self) -> Poll<Response<()>, proto::Error> {
|
||||
let mut me = self.inner.lock().unwrap();
|
||||
let me = &mut *me;
|
||||
|
||||
@@ -557,7 +572,7 @@ impl<B, P> Actions<B, P>
|
||||
P: Peer,
|
||||
{
|
||||
fn ensure_not_idle(&mut self, id: StreamId)
|
||||
-> Result<(), ConnectionError>
|
||||
-> Result<(), Reason>
|
||||
{
|
||||
if self.is_local_init(id) {
|
||||
self.send.ensure_not_idle(id)
|
||||
|
||||
Reference in New Issue
Block a user