Fix warnings
This commit is contained in:
@@ -1,10 +1,11 @@
|
|||||||
use {frame, ConnectionError, StreamId};
|
use {frame, ConnectionError};
|
||||||
use Body;
|
use Body;
|
||||||
|
use frame::StreamId;
|
||||||
use proto::{self, Connection, WindowSize};
|
use proto::{self, Connection, WindowSize};
|
||||||
use error::Reason::*;
|
use error::Reason::*;
|
||||||
|
|
||||||
use http::{self, Request, Response};
|
use http::{Request, Response};
|
||||||
use futures::{self, Future, Poll, Sink, Async, AsyncSink};
|
use futures::{Future, Poll, Sink, Async, AsyncSink};
|
||||||
use tokio_io::{AsyncRead, AsyncWrite};
|
use tokio_io::{AsyncRead, AsyncWrite};
|
||||||
use bytes::{Bytes, IntoBuf};
|
use bytes::{Bytes, IntoBuf};
|
||||||
|
|
||||||
@@ -148,9 +149,7 @@ impl<B: IntoBuf> Stream<B> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Request capacity to send data
|
/// Request capacity to send data
|
||||||
pub fn reserve_capacity(&mut self, capacity: usize)
|
pub fn reserve_capacity(&mut self, capacity: usize) {
|
||||||
-> Result<(), ConnectionError>
|
|
||||||
{
|
|
||||||
// TODO: Check for overflow
|
// TODO: Check for overflow
|
||||||
self.inner.reserve_capacity(capacity as WindowSize)
|
self.inner.reserve_capacity(capacity as WindowSize)
|
||||||
}
|
}
|
||||||
@@ -174,7 +173,7 @@ impl<B: IntoBuf> Stream<B> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Send trailers
|
/// Send trailers
|
||||||
pub fn send_trailers(&mut self, trailers: ())
|
pub fn send_trailers(&mut self, _trailers: ())
|
||||||
-> Result<(), ConnectionError>
|
-> Result<(), ConnectionError>
|
||||||
{
|
{
|
||||||
unimplemented!();
|
unimplemented!();
|
||||||
|
|||||||
@@ -3,11 +3,10 @@ use hpack;
|
|||||||
use frame::{self, Frame, Head, Kind, Error};
|
use frame::{self, Frame, Head, Kind, Error};
|
||||||
use HeaderMap;
|
use HeaderMap;
|
||||||
|
|
||||||
use http::{self, request, response, version, uri, Method, StatusCode, Uri};
|
use http::{self, version, uri, Request, Response, Method, StatusCode, Uri};
|
||||||
use http::{Request, Response};
|
|
||||||
use http::header::{self, HeaderName, HeaderValue};
|
use http::header::{self, HeaderName, HeaderValue};
|
||||||
|
|
||||||
use bytes::{BytesMut, Bytes, Buf};
|
use bytes::{BytesMut, Bytes};
|
||||||
use byteorder::{BigEndian, ByteOrder};
|
use byteorder::{BigEndian, ByteOrder};
|
||||||
use string::String;
|
use string::String;
|
||||||
|
|
||||||
@@ -291,10 +290,6 @@ impl Headers {
|
|||||||
Ok(request)
|
Ok(request)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn into_fields(self) -> HeaderMap {
|
|
||||||
self.fields
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn encode(self, encoder: &mut hpack::Encoder, dst: &mut BytesMut)
|
pub fn encode(self, encoder: &mut hpack::Encoder, dst: &mut BytesMut)
|
||||||
-> Option<Continuation>
|
-> Option<Continuation>
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
use hpack;
|
use hpack;
|
||||||
use error::{ConnectionError, Reason};
|
use error::{ConnectionError, Reason};
|
||||||
|
|
||||||
use bytes::{Bytes, Buf};
|
use bytes::Bytes;
|
||||||
|
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
@@ -56,6 +56,8 @@ pub use self::settings::{
|
|||||||
DEFAULT_MAX_FRAME_SIZE,
|
DEFAULT_MAX_FRAME_SIZE,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
pub type FrameSize = u32;
|
||||||
|
|
||||||
pub const HEADER_LEN: usize = 9;
|
pub const HEADER_LEN: usize = 9;
|
||||||
|
|
||||||
pub enum Frame<T = Bytes> {
|
pub enum Frame<T = Bytes> {
|
||||||
@@ -100,18 +102,6 @@ impl<T> Frame<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Buf> Frame<T> {
|
|
||||||
/// Returns the length of the frame as it applies to flow control.
|
|
||||||
pub fn flow_len(&self) -> usize {
|
|
||||||
use self::Frame::*;
|
|
||||||
|
|
||||||
match *self {
|
|
||||||
Data(ref frame) => frame.payload().remaining(),
|
|
||||||
_ => 0,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> fmt::Debug for Frame<T> {
|
impl<T> fmt::Debug for Frame<T> {
|
||||||
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
||||||
use self::Frame::*;
|
use self::Frame::*;
|
||||||
|
|||||||
@@ -72,12 +72,4 @@ impl StreamDependency {
|
|||||||
pub fn dependency_id(&self) -> StreamId {
|
pub fn dependency_id(&self) -> StreamId {
|
||||||
self.dependency_id
|
self.dependency_id
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn weight(&self) -> u8 {
|
|
||||||
self.weight
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn is_exclusive(&self) -> bool {
|
|
||||||
self.is_exclusive
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
use FrameSize;
|
use frame::{Frame, FrameSize, Error, Head, Kind, StreamId};
|
||||||
use frame::{Frame, Error, Head, Kind, StreamId};
|
|
||||||
use bytes::{BytesMut, BufMut, BigEndian};
|
use bytes::{BytesMut, BufMut, BigEndian};
|
||||||
|
|
||||||
#[derive(Debug, Clone, Default, Eq, PartialEq)]
|
#[derive(Debug, Clone, Default, Eq, PartialEq)]
|
||||||
@@ -54,10 +53,6 @@ impl Settings {
|
|||||||
self.flags.is_ack()
|
self.flags.is_ack()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn enable_push(&self) -> Option<bool> {
|
|
||||||
self.enable_push.map(|n| n != 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn initial_window_size(&self) -> Option<u32> {
|
pub fn initial_window_size(&self) -> Option<u32> {
|
||||||
self.initial_window_size
|
self.initial_window_size
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
use StreamId;
|
use frame::{self, Head, Kind, Error, StreamId};
|
||||||
use frame::{self, Head, Kind, Error};
|
|
||||||
|
|
||||||
use bytes::{BufMut, BigEndian};
|
use bytes::{BufMut, BigEndian};
|
||||||
|
|
||||||
|
|||||||
@@ -151,6 +151,7 @@ impl Decoder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Queues a potential size update
|
/// Queues a potential size update
|
||||||
|
#[allow(dead_code)]
|
||||||
pub fn queue_size_update(&mut self, size: usize) {
|
pub fn queue_size_update(&mut self, size: usize) {
|
||||||
let size = match self.max_size_update {
|
let size = match self.max_size_update {
|
||||||
Some(v) => cmp::max(v, size),
|
Some(v) => cmp::max(v, size),
|
||||||
|
|||||||
@@ -44,6 +44,7 @@ impl Encoder {
|
|||||||
/// Queues a max size update.
|
/// Queues a max size update.
|
||||||
///
|
///
|
||||||
/// The next call to `encode` will include a dynamic size update frame.
|
/// The next call to `encode` will include a dynamic size update frame.
|
||||||
|
#[allow(dead_code)]
|
||||||
pub fn update_max_size(&mut self, val: usize) {
|
pub fn update_max_size(&mut self, val: usize) {
|
||||||
match self.size_update {
|
match self.size_update {
|
||||||
Some(SizeUpdate::One(old)) => {
|
Some(SizeUpdate::One(old)) => {
|
||||||
|
|||||||
34
src/lib.rs
34
src/lib.rs
@@ -1,5 +1,4 @@
|
|||||||
#![allow(warnings)]
|
#![deny(warnings, missing_debug_implementations)]
|
||||||
// #![deny(missing_debug_implementations)]
|
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate futures;
|
extern crate futures;
|
||||||
@@ -35,11 +34,9 @@ mod frame;
|
|||||||
pub mod server;
|
pub mod server;
|
||||||
|
|
||||||
pub use error::{ConnectionError, Reason};
|
pub use error::{ConnectionError, Reason};
|
||||||
pub use frame::StreamId;
|
|
||||||
|
|
||||||
use bytes::Bytes;
|
use bytes::Bytes;
|
||||||
|
|
||||||
pub type FrameSize = u32;
|
|
||||||
// TODO: remove if carllerche/http#90 lands
|
// TODO: remove if carllerche/http#90 lands
|
||||||
pub type HeaderMap = http::HeaderMap<http::header::HeaderValue>;
|
pub type HeaderMap = http::HeaderMap<http::header::HeaderValue>;
|
||||||
|
|
||||||
@@ -74,32 +71,3 @@ impl<B: IntoBuf> futures::Stream for Body<B> {
|
|||||||
self.inner.poll_data()
|
self.inner.poll_data()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Delete below
|
|
||||||
|
|
||||||
/// An H2 connection frame
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub enum Frame<T, B = Bytes> {
|
|
||||||
Headers {
|
|
||||||
id: StreamId,
|
|
||||||
headers: T,
|
|
||||||
end_of_stream: bool,
|
|
||||||
},
|
|
||||||
Data {
|
|
||||||
id: StreamId,
|
|
||||||
data: B,
|
|
||||||
end_of_stream: bool,
|
|
||||||
},
|
|
||||||
Trailers {
|
|
||||||
id: StreamId,
|
|
||||||
headers: HeaderMap,
|
|
||||||
},
|
|
||||||
PushPromise {
|
|
||||||
id: StreamId,
|
|
||||||
promised_id: StreamId,
|
|
||||||
},
|
|
||||||
Reset {
|
|
||||||
id: StreamId,
|
|
||||||
error: Reason,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -56,7 +56,6 @@ impl<T, B> futures::Stream for Codec<T, B>
|
|||||||
type Error = ConnectionError;
|
type Error = ConnectionError;
|
||||||
|
|
||||||
fn poll(&mut self) -> Poll<Option<Frame>, ConnectionError> {
|
fn poll(&mut self) -> Poll<Option<Frame>, ConnectionError> {
|
||||||
use futures::Stream;
|
|
||||||
self.inner.poll()
|
self.inner.poll()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,9 @@
|
|||||||
use {client, server, ConnectionError, Frame};
|
use {client, frame, server, ConnectionError};
|
||||||
use HeaderMap;
|
|
||||||
use frame::{self, StreamId};
|
|
||||||
|
|
||||||
use proto::*;
|
use proto::*;
|
||||||
|
|
||||||
use http::{Request, Response};
|
use http::Request;
|
||||||
|
use futures::{Sink, Stream};
|
||||||
use bytes::{Bytes, IntoBuf};
|
use bytes::{Bytes, IntoBuf};
|
||||||
use tokio_io::{AsyncRead, AsyncWrite};
|
use tokio_io::{AsyncRead, AsyncWrite};
|
||||||
|
|
||||||
@@ -163,10 +162,10 @@ impl<T, P, B> Connection<T, P, B>
|
|||||||
trace!("recv SETTINGS; frame={:?}", frame);
|
trace!("recv SETTINGS; frame={:?}", frame);
|
||||||
self.settings.recv_settings(frame);
|
self.settings.recv_settings(frame);
|
||||||
}
|
}
|
||||||
Some(GoAway(frame)) => {
|
Some(GoAway(_)) => {
|
||||||
// TODO: handle the last_processed_id. Also, should this be
|
// TODO: handle the last_processed_id. Also, should this be
|
||||||
// handled as an error?
|
// handled as an error?
|
||||||
let e = ConnectionError::Proto(frame.reason());
|
// let _ = ConnectionError::Proto(frame.reason());
|
||||||
return Ok(().into());
|
return Ok(().into());
|
||||||
}
|
}
|
||||||
Some(Ping(frame)) => {
|
Some(Ping(frame)) => {
|
||||||
@@ -220,21 +219,6 @@ impl<T, P, B> Connection<T, P, B>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn convert_poll_message(frame: frame::Headers) -> Result<Frame<P::Poll>, ConnectionError> {
|
|
||||||
if frame.is_trailers() {
|
|
||||||
Ok(Frame::Trailers {
|
|
||||||
id: frame.stream_id(),
|
|
||||||
headers: frame.into_fields()
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
Ok(Frame::Headers {
|
|
||||||
id: frame.stream_id(),
|
|
||||||
end_of_stream: frame.is_end_stream(),
|
|
||||||
headers: P::convert_poll_message(frame)?,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T, B> Connection<T, client::Peer, B>
|
impl<T, B> Connection<T, client::Peer, B>
|
||||||
@@ -261,13 +245,6 @@ impl<T, B> Connection<T, server::Peer, B>
|
|||||||
// ====== impl State =====
|
// ====== impl State =====
|
||||||
|
|
||||||
impl State {
|
impl State {
|
||||||
fn is_open(&self) -> bool {
|
|
||||||
match *self {
|
|
||||||
State::Open => true,
|
|
||||||
_ => false,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn error(&self) -> Option<Reason> {
|
fn error(&self) -> Option<Reason> {
|
||||||
match *self {
|
match *self {
|
||||||
State::Error(reason) => Some(reason),
|
State::Error(reason) => Some(reason),
|
||||||
|
|||||||
@@ -6,12 +6,12 @@ use error::Reason::*;
|
|||||||
|
|
||||||
use futures::*;
|
use futures::*;
|
||||||
|
|
||||||
use bytes::{Bytes, BytesMut};
|
use bytes::BytesMut;
|
||||||
|
|
||||||
use tokio_io::AsyncRead;
|
use tokio_io::AsyncRead;
|
||||||
use tokio_io::codec::length_delimited;
|
use tokio_io::codec::length_delimited;
|
||||||
|
|
||||||
use std::io::{self, Cursor};
|
use std::io;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct FramedRead<T> {
|
pub struct FramedRead<T> {
|
||||||
|
|||||||
@@ -1,12 +1,11 @@
|
|||||||
use {hpack, ConnectionError, FrameSize};
|
use {hpack, ConnectionError};
|
||||||
use error::User::*;
|
use error::User::*;
|
||||||
use frame::{self, Frame};
|
use frame::{self, Frame, FrameSize};
|
||||||
|
|
||||||
use futures::*;
|
use futures::*;
|
||||||
use tokio_io::{AsyncRead, AsyncWrite};
|
use tokio_io::{AsyncRead, AsyncWrite};
|
||||||
use bytes::{BytesMut, Buf, BufMut};
|
use bytes::{BytesMut, Buf, BufMut};
|
||||||
|
|
||||||
use std::cmp;
|
|
||||||
use std::io::{self, Cursor};
|
use std::io::{self, Cursor};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@@ -176,9 +175,11 @@ impl<T, B> Sink for FramedWrite<T, B>
|
|||||||
trace!("encoded window_update; rem={:?}", self.buf.remaining());
|
trace!("encoded window_update; rem={:?}", self.buf.remaining());
|
||||||
}
|
}
|
||||||
|
|
||||||
Frame::Priority(v) => {
|
Frame::Priority(_) => {
|
||||||
// v.encode(self.buf.get_mut());
|
/*
|
||||||
|
v.encode(self.buf.get_mut());
|
||||||
trace!("encoded priority; rem={:?}", self.buf.remaining());
|
trace!("encoded priority; rem={:?}", self.buf.remaining());
|
||||||
|
*/
|
||||||
unimplemented!();
|
unimplemented!();
|
||||||
}
|
}
|
||||||
Frame::Reset(v) => {
|
Frame::Reset(v) => {
|
||||||
@@ -210,7 +211,7 @@ impl<T, B> Sink for FramedWrite<T, B>
|
|||||||
Some(Next::Data(frame)) => {
|
Some(Next::Data(frame)) => {
|
||||||
self.last_data_frame = Some(frame);
|
self.last_data_frame = Some(frame);
|
||||||
}
|
}
|
||||||
Some(Next::Continuation(frame)) => {
|
Some(Next::Continuation(_)) => {
|
||||||
unimplemented!();
|
unimplemented!();
|
||||||
}
|
}
|
||||||
None => {}
|
None => {}
|
||||||
|
|||||||
@@ -16,11 +16,11 @@ use self::ping_pong::PingPong;
|
|||||||
use self::settings::Settings;
|
use self::settings::Settings;
|
||||||
use self::streams::Prioritized;
|
use self::streams::Prioritized;
|
||||||
|
|
||||||
use {StreamId, ConnectionError};
|
use ConnectionError;
|
||||||
use error::Reason;
|
use error::Reason;
|
||||||
use frame::{self, Frame};
|
use frame::{self, Frame, StreamId};
|
||||||
|
|
||||||
use futures::{self, task, Poll, Async, AsyncSink, Sink, Stream as Stream2};
|
use futures::{self, task, Poll, Async, AsyncSink};
|
||||||
use futures::task::Task;
|
use futures::task::Task;
|
||||||
use bytes::{Buf, IntoBuf};
|
use bytes::{Buf, IntoBuf};
|
||||||
use tokio_io::{AsyncRead, AsyncWrite};
|
use tokio_io::{AsyncRead, AsyncWrite};
|
||||||
@@ -50,12 +50,6 @@ pub type PingPayload = [u8; 8];
|
|||||||
|
|
||||||
pub type WindowSize = u32;
|
pub type WindowSize = u32;
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone)]
|
|
||||||
pub struct WindowUpdate {
|
|
||||||
stream_id: StreamId,
|
|
||||||
increment: WindowSize,
|
|
||||||
}
|
|
||||||
|
|
||||||
// Constants
|
// Constants
|
||||||
pub const DEFAULT_INITIAL_WINDOW_SIZE: WindowSize = 65_535;
|
pub const DEFAULT_INITIAL_WINDOW_SIZE: WindowSize = 65_535;
|
||||||
pub const MAX_WINDOW_SIZE: WindowSize = (1 << 31) - 1;
|
pub const MAX_WINDOW_SIZE: WindowSize = (1 << 31) - 1;
|
||||||
@@ -94,20 +88,3 @@ pub(crate) fn from_framed_write<T, P, B>(framed_write: FramedWrite<T, Prioritize
|
|||||||
|
|
||||||
Connection::new(codec)
|
Connection::new(codec)
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WindowUpdate {
|
|
||||||
pub fn new(stream_id: StreamId, increment: WindowSize) -> WindowUpdate {
|
|
||||||
WindowUpdate {
|
|
||||||
stream_id,
|
|
||||||
increment
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn stream_id(&self) -> StreamId {
|
|
||||||
self.stream_id
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn increment(&self) -> WindowSize {
|
|
||||||
self.increment
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -2,6 +2,8 @@ use ConnectionError;
|
|||||||
use frame::Ping;
|
use frame::Ping;
|
||||||
use proto::*;
|
use proto::*;
|
||||||
|
|
||||||
|
use futures::Sink;
|
||||||
|
|
||||||
/// Acknowledges ping requests from the remote.
|
/// Acknowledges ping requests from the remote.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct PingPong<B> {
|
pub struct PingPong<B> {
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
use {frame, ConnectionError};
|
use {frame, ConnectionError};
|
||||||
use proto::*;
|
use proto::*;
|
||||||
|
|
||||||
|
use futures::Sink;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub(crate) struct Settings {
|
pub(crate) struct Settings {
|
||||||
/// Received SETTINGS frame pending processing. The ACK must be written to
|
/// Received SETTINGS frame pending processing. The ACK must be written to
|
||||||
@@ -45,7 +47,7 @@ impl Settings {
|
|||||||
trace!("ACK sent");
|
trace!("ACK sent");
|
||||||
|
|
||||||
dst.apply_remote_settings(settings);
|
dst.apply_remote_settings(settings);
|
||||||
streams.apply_remote_settings(settings);
|
streams.apply_remote_settings(settings)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
self.pending = None;
|
self.pending = None;
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
use frame::{self, Frame};
|
use frame::Frame;
|
||||||
|
|
||||||
use slab::Slab;
|
use slab::Slab;
|
||||||
|
|
||||||
|
|||||||
@@ -2,8 +2,6 @@ use ConnectionError;
|
|||||||
use proto::*;
|
use proto::*;
|
||||||
use error::Reason::*;
|
use error::Reason::*;
|
||||||
|
|
||||||
use std::cmp;
|
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug)]
|
#[derive(Copy, Clone, Debug)]
|
||||||
pub struct FlowControl {
|
pub struct FlowControl {
|
||||||
/// Window size as indicated by the peer. This can go negative.
|
/// Window size as indicated by the peer. This can go negative.
|
||||||
@@ -49,21 +47,8 @@ impl FlowControl {
|
|||||||
self.available -= capacity;
|
self.available -= capacity;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn assign_capacity(&mut self, capacity: WindowSize)
|
pub fn assign_capacity(&mut self, capacity: WindowSize) {
|
||||||
-> Result<(), ConnectionError>
|
self.available + capacity;
|
||||||
{
|
|
||||||
let (val, overflow) = self.available.overflowing_add(capacity);
|
|
||||||
|
|
||||||
if overflow {
|
|
||||||
return Err(FlowControlError.into());
|
|
||||||
}
|
|
||||||
|
|
||||||
if val > MAX_WINDOW_SIZE {
|
|
||||||
return Err(FlowControlError.into());
|
|
||||||
}
|
|
||||||
|
|
||||||
self.available = val;
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the number of bytes available but not assigned to the window.
|
/// Returns the number of bytes available but not assigned to the window.
|
||||||
|
|||||||
@@ -20,7 +20,8 @@ use self::state::State;
|
|||||||
use self::store::{Store, Entry};
|
use self::store::{Store, Entry};
|
||||||
use self::stream::Stream;
|
use self::stream::Stream;
|
||||||
|
|
||||||
use {frame, StreamId, ConnectionError};
|
use {frame, ConnectionError};
|
||||||
|
use frame::StreamId;
|
||||||
use proto::*;
|
use proto::*;
|
||||||
use error::Reason::*;
|
use error::Reason::*;
|
||||||
use error::User::*;
|
use error::User::*;
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
use bytes::buf::Take;
|
use bytes::buf::Take;
|
||||||
|
use futures::Sink;
|
||||||
|
|
||||||
use std::{fmt, cmp};
|
use std::{fmt, cmp};
|
||||||
|
|
||||||
@@ -40,8 +41,7 @@ impl<B> Prioritize<B>
|
|||||||
flow.inc_window(config.init_local_window_sz)
|
flow.inc_window(config.init_local_window_sz)
|
||||||
.ok().expect("invalid initial window size");
|
.ok().expect("invalid initial window size");
|
||||||
|
|
||||||
flow.assign_capacity(config.init_local_window_sz)
|
flow.assign_capacity(config.init_local_window_sz);
|
||||||
.ok().expect("invalid initial window size");
|
|
||||||
|
|
||||||
Prioritize {
|
Prioritize {
|
||||||
pending_send: store::Queue::new(),
|
pending_send: store::Queue::new(),
|
||||||
@@ -131,16 +131,13 @@ impl<B> Prioritize<B>
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Request capacity to send data
|
/// Request capacity to send data
|
||||||
pub fn reserve_capacity(&mut self, capacity: WindowSize, stream: &mut store::Ptr<B>)
|
pub fn reserve_capacity(&mut self, capacity: WindowSize, stream: &mut store::Ptr<B>) {
|
||||||
-> Result<(), ConnectionError>
|
|
||||||
{
|
|
||||||
// Actual capacity is `capacity` + the current amount of buffered data.
|
// Actual capacity is `capacity` + the current amount of buffered data.
|
||||||
// It it were less, then we could never send out the buffered data.
|
// It it were less, then we could never send out the buffered data.
|
||||||
let capacity = capacity + stream.buffered_send_data;
|
let capacity = capacity + stream.buffered_send_data;
|
||||||
|
|
||||||
if capacity == stream.requested_send_capacity {
|
if capacity == stream.requested_send_capacity {
|
||||||
// Nothing to do
|
// Nothing to do
|
||||||
return Ok(());
|
|
||||||
} else if capacity < stream.requested_send_capacity {
|
} else if capacity < stream.requested_send_capacity {
|
||||||
// TODO: release capacity
|
// TODO: release capacity
|
||||||
unimplemented!();
|
unimplemented!();
|
||||||
@@ -152,8 +149,6 @@ impl<B> Prioritize<B>
|
|||||||
// currently available, the stream will be queued to receive some
|
// currently available, the stream will be queued to receive some
|
||||||
// when more becomes available.
|
// when more becomes available.
|
||||||
self.try_assign_capacity(stream);
|
self.try_assign_capacity(stream);
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -184,7 +179,7 @@ impl<B> Prioritize<B>
|
|||||||
{
|
{
|
||||||
// Update the connection's window
|
// Update the connection's window
|
||||||
self.flow.inc_window(inc)?;
|
self.flow.inc_window(inc)?;
|
||||||
self.flow.assign_capacity(inc)?;
|
self.flow.assign_capacity(inc);
|
||||||
|
|
||||||
// Assign newly acquired capacity to streams pending capacity.
|
// Assign newly acquired capacity to streams pending capacity.
|
||||||
while self.flow.available() > 0 {
|
while self.flow.available() > 0 {
|
||||||
@@ -212,7 +207,7 @@ impl<B> Prioritize<B>
|
|||||||
|
|
||||||
// The amount of additional capacity that the stream requests.
|
// The amount of additional capacity that the stream requests.
|
||||||
// Don't assign more than the window has available!
|
// Don't assign more than the window has available!
|
||||||
let mut additional = cmp::min(
|
let additional = cmp::min(
|
||||||
total_requested - stream.send_flow.available(),
|
total_requested - stream.send_flow.available(),
|
||||||
stream.send_flow.window_size());
|
stream.send_flow.window_size());
|
||||||
|
|
||||||
|
|||||||
@@ -3,8 +3,8 @@ use proto::*;
|
|||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
use error::Reason::*;
|
use error::Reason::*;
|
||||||
|
use futures::Sink;
|
||||||
|
|
||||||
use std::collections::VecDeque;
|
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@@ -58,7 +58,8 @@ impl<B> Recv<B> where B: Buf {
|
|||||||
|
|
||||||
let mut flow = FlowControl::new();
|
let mut flow = FlowControl::new();
|
||||||
|
|
||||||
flow.inc_window(config.init_remote_window_sz);
|
flow.inc_window(config.init_remote_window_sz)
|
||||||
|
.ok().expect("invalid initial remote window size");
|
||||||
flow.assign_capacity(config.init_remote_window_sz);
|
flow.assign_capacity(config.init_remote_window_sz);
|
||||||
|
|
||||||
Recv {
|
Recv {
|
||||||
@@ -127,7 +128,7 @@ impl<B> Recv<B> where B: Buf {
|
|||||||
// frame vs. now.
|
// frame vs. now.
|
||||||
Ok(client::Peer::convert_poll_message(v)?.into())
|
Ok(client::Peer::convert_poll_message(v)?.into())
|
||||||
}
|
}
|
||||||
Some(frame) => unimplemented!(),
|
Some(_) => unimplemented!(),
|
||||||
None => {
|
None => {
|
||||||
stream.state.ensure_recv_open()?;
|
stream.state.ensure_recv_open()?;
|
||||||
|
|
||||||
@@ -187,7 +188,7 @@ impl<B> Recv<B> where B: Buf {
|
|||||||
-> Result<(), ConnectionError>
|
-> Result<(), ConnectionError>
|
||||||
{
|
{
|
||||||
// Transition the state
|
// Transition the state
|
||||||
stream.state.recv_close();
|
stream.state.recv_close()?;
|
||||||
|
|
||||||
// Push the frame onto the stream's recv buffer
|
// Push the frame onto the stream's recv buffer
|
||||||
stream.pending_recv.push_back(&mut self.buffer, frame.into());
|
stream.pending_recv.push_back(&mut self.buffer, frame.into());
|
||||||
@@ -199,7 +200,6 @@ impl<B> Recv<B> where B: Buf {
|
|||||||
pub fn release_capacity(&mut self,
|
pub fn release_capacity(&mut self,
|
||||||
capacity: WindowSize,
|
capacity: WindowSize,
|
||||||
stream: &mut store::Ptr<B>,
|
stream: &mut store::Ptr<B>,
|
||||||
send: &mut Send<B>,
|
|
||||||
task: &mut Option<Task>)
|
task: &mut Option<Task>)
|
||||||
-> Result<(), ConnectionError>
|
-> Result<(), ConnectionError>
|
||||||
{
|
{
|
||||||
@@ -315,7 +315,7 @@ impl<B> Recv<B> where B: Buf {
|
|||||||
send.init_window_sz(),
|
send.init_window_sz(),
|
||||||
self.init_window_sz);
|
self.init_window_sz);
|
||||||
|
|
||||||
new_stream.state.reserve_remote();
|
new_stream.state.reserve_remote()?;
|
||||||
|
|
||||||
let mut ppp = store[stream].pending_push_promises.take();
|
let mut ppp = store[stream].pending_push_promises.take();
|
||||||
|
|
||||||
@@ -471,7 +471,7 @@ impl<B> Recv<B> where B: Buf {
|
|||||||
let frame = frame::WindowUpdate::new(StreamId::zero(), incr);
|
let frame = frame::WindowUpdate::new(StreamId::zero(), incr);
|
||||||
|
|
||||||
if dst.start_send(frame.into())?.is_ready() {
|
if dst.start_send(frame.into())?.is_ready() {
|
||||||
self.flow.inc_window(incr);
|
self.flow.inc_window(incr).ok().expect("unexpected flow control state");
|
||||||
} else {
|
} else {
|
||||||
return Ok(Async::NotReady);
|
return Ok(Async::NotReady);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,9 +7,6 @@ use error::User::*;
|
|||||||
|
|
||||||
use bytes::Buf;
|
use bytes::Buf;
|
||||||
|
|
||||||
use std::collections::VecDeque;
|
|
||||||
use std::marker::PhantomData;
|
|
||||||
|
|
||||||
/// Manages state transitions related to outbound frames.
|
/// Manages state transitions related to outbound frames.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub(super) struct Send<B> {
|
pub(super) struct Send<B> {
|
||||||
@@ -104,12 +101,6 @@ impl<B> Send<B> where B: Buf {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn send_eos(&mut self, stream: &mut Stream<B>)
|
|
||||||
-> Result<(), ConnectionError>
|
|
||||||
{
|
|
||||||
stream.state.send_close()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn send_reset(&mut self, reason: Reason,
|
pub fn send_reset(&mut self, reason: Reason,
|
||||||
stream: &mut store::Ptr<B>,
|
stream: &mut store::Ptr<B>,
|
||||||
task: &mut Option<Task>)
|
task: &mut Option<Task>)
|
||||||
@@ -124,6 +115,7 @@ impl<B> Send<B> where B: Buf {
|
|||||||
|
|
||||||
let frame = frame::Reset::new(stream.id, reason);
|
let frame = frame::Reset::new(stream.id, reason);
|
||||||
|
|
||||||
|
// TODO: This could impact connection level flow control.
|
||||||
self.prioritize.clear_queue(stream);
|
self.prioritize.clear_queue(stream);
|
||||||
|
|
||||||
trace!("send_reset -- queueing; frame={:?}", frame);
|
trace!("send_reset -- queueing; frame={:?}", frame);
|
||||||
@@ -151,9 +143,7 @@ impl<B> Send<B> where B: Buf {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Request capacity to send data
|
/// Request capacity to send data
|
||||||
pub fn reserve_capacity(&mut self, capacity: WindowSize, stream: &mut store::Ptr<B>)
|
pub fn reserve_capacity(&mut self, capacity: WindowSize, stream: &mut store::Ptr<B>) {
|
||||||
-> Result<(), ConnectionError>
|
|
||||||
{
|
|
||||||
self.prioritize.reserve_capacity(capacity, stream)
|
self.prioritize.reserve_capacity(capacity, stream)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -211,6 +201,7 @@ impl<B> Send<B> where B: Buf {
|
|||||||
settings: &frame::Settings,
|
settings: &frame::Settings,
|
||||||
store: &mut Store<B>,
|
store: &mut Store<B>,
|
||||||
task: &mut Option<Task>)
|
task: &mut Option<Task>)
|
||||||
|
-> Result<(), ConnectionError>
|
||||||
{
|
{
|
||||||
if let Some(val) = settings.max_concurrent_streams() {
|
if let Some(val) = settings.max_concurrent_streams() {
|
||||||
self.max_streams = Some(val as usize);
|
self.max_streams = Some(val as usize);
|
||||||
@@ -251,15 +242,19 @@ impl<B> Send<B> where B: Buf {
|
|||||||
|
|
||||||
// TODO: Should this notify the producer?
|
// TODO: Should this notify the producer?
|
||||||
}
|
}
|
||||||
});
|
|
||||||
|
Ok(())
|
||||||
|
})?;
|
||||||
} else if val > old_val {
|
} else if val > old_val {
|
||||||
let inc = val - old_val;
|
let inc = val - old_val;
|
||||||
|
|
||||||
store.for_each(|mut stream| {
|
store.for_each(|mut stream| {
|
||||||
self.recv_stream_window_update(inc, &mut stream, task);
|
self.recv_stream_window_update(inc, &mut stream, task)
|
||||||
});
|
})?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn ensure_not_idle(&self, id: StreamId) -> Result<(), ConnectionError> {
|
pub fn ensure_not_idle(&self, id: StreamId) -> Result<(), ConnectionError> {
|
||||||
|
|||||||
@@ -2,8 +2,6 @@ use ConnectionError;
|
|||||||
use error::Reason;
|
use error::Reason;
|
||||||
use error::Reason::*;
|
use error::Reason::*;
|
||||||
use error::User::*;
|
use error::User::*;
|
||||||
use proto::*;
|
|
||||||
use super::FlowControl;
|
|
||||||
|
|
||||||
use self::Inner::*;
|
use self::Inner::*;
|
||||||
use self::Peer::*;
|
use self::Peer::*;
|
||||||
|
|||||||
@@ -49,13 +49,12 @@ struct Indices {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub(super) enum Entry<'a, B: 'a> {
|
pub(super) enum Entry<'a, B: 'a> {
|
||||||
Occupied(OccupiedEntry<'a, B>),
|
Occupied(OccupiedEntry<'a>),
|
||||||
Vacant(VacantEntry<'a, B>),
|
Vacant(VacantEntry<'a, B>),
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) struct OccupiedEntry<'a, B: 'a> {
|
pub(super) struct OccupiedEntry<'a> {
|
||||||
ids: hash_map::OccupiedEntry<'a, StreamId, usize>,
|
ids: hash_map::OccupiedEntry<'a, StreamId, usize>,
|
||||||
slab: &'a mut slab::Slab<Stream<B>>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) struct VacantEntry<'a, B: 'a> {
|
pub(super) struct VacantEntry<'a, B: 'a> {
|
||||||
@@ -108,7 +107,6 @@ impl<B> Store<B> {
|
|||||||
Occupied(e) => {
|
Occupied(e) => {
|
||||||
Entry::Occupied(OccupiedEntry {
|
Entry::Occupied(OccupiedEntry {
|
||||||
ids: e,
|
ids: e,
|
||||||
slab: &mut self.slab,
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
Vacant(e) => {
|
Vacant(e) => {
|
||||||
@@ -120,15 +118,17 @@ impl<B> Store<B> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn for_each<F>(&mut self, mut f: F)
|
pub fn for_each<F>(&mut self, mut f: F) -> Result<(), ConnectionError>
|
||||||
where F: FnMut(Ptr<B>)
|
where F: FnMut(Ptr<B>) -> Result<(), ConnectionError>,
|
||||||
{
|
{
|
||||||
for &key in self.ids.values() {
|
for &key in self.ids.values() {
|
||||||
f(Ptr {
|
f(Ptr {
|
||||||
key: Key(key),
|
key: Key(key),
|
||||||
slab: &mut self.slab,
|
slab: &mut self.slab,
|
||||||
});
|
})?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -245,10 +245,6 @@ impl<'a, B: 'a> Ptr<'a, B> {
|
|||||||
slab: &mut *self.slab,
|
slab: &mut *self.slab,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn into_mut(self) -> &'a mut Stream<B> {
|
|
||||||
&mut self.slab[self.key.0]
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, B: 'a> ops::Deref for Ptr<'a, B> {
|
impl<'a, B: 'a> ops::Deref for Ptr<'a, B> {
|
||||||
@@ -267,22 +263,10 @@ impl<'a, B: 'a> ops::DerefMut for Ptr<'a, B> {
|
|||||||
|
|
||||||
// ===== impl OccupiedEntry =====
|
// ===== impl OccupiedEntry =====
|
||||||
|
|
||||||
impl<'a, B> OccupiedEntry<'a, B> {
|
impl<'a> OccupiedEntry<'a> {
|
||||||
pub fn key(&self) -> Key {
|
pub fn key(&self) -> Key {
|
||||||
Key(*self.ids.get())
|
Key(*self.ids.get())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get(&self) -> &Stream<B> {
|
|
||||||
&self.slab[*self.ids.get()]
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_mut(&mut self) -> &mut Stream<B> {
|
|
||||||
&mut self.slab[*self.ids.get()]
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn into_mut(self) -> &'a mut Stream<B> {
|
|
||||||
&mut self.slab[*self.ids.get()]
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ===== impl VacantEntry =====
|
// ===== impl VacantEntry =====
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ use {client, server};
|
|||||||
use proto::*;
|
use proto::*;
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
use std::marker::PhantomData;
|
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@@ -134,7 +133,7 @@ impl<B> Streams<B>
|
|||||||
return Err(ProtocolError.into());
|
return Err(ProtocolError.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut stream = match me.store.find_mut(&id) {
|
let stream = match me.store.find_mut(&id) {
|
||||||
Some(stream) => stream,
|
Some(stream) => stream,
|
||||||
None => {
|
None => {
|
||||||
// TODO: Are there other error cases?
|
// TODO: Are there other error cases?
|
||||||
@@ -159,8 +158,9 @@ impl<B> Streams<B>
|
|||||||
let last_processed_id = actions.recv.last_processed_id();
|
let last_processed_id = actions.recv.last_processed_id();
|
||||||
|
|
||||||
me.store.for_each(|mut stream| {
|
me.store.for_each(|mut stream| {
|
||||||
actions.recv.recv_err(err, &mut *stream)
|
actions.recv.recv_err(err, &mut *stream);
|
||||||
});
|
Ok(())
|
||||||
|
}).ok().expect("unexpected error processing error");
|
||||||
|
|
||||||
last_processed_id
|
last_processed_id
|
||||||
}
|
}
|
||||||
@@ -180,7 +180,7 @@ impl<B> Streams<B>
|
|||||||
// considers closed. It's ok...
|
// considers closed. It's ok...
|
||||||
if let Some(mut stream) = me.store.find_mut(&id) {
|
if let Some(mut stream) = me.store.find_mut(&id) {
|
||||||
me.actions.send.recv_stream_window_update(
|
me.actions.send.recv_stream_window_update(
|
||||||
frame.size_increment(), &mut stream, &mut me.actions.task);
|
frame.size_increment(), &mut stream, &mut me.actions.task)?;
|
||||||
} else {
|
} else {
|
||||||
me.actions.recv.ensure_not_idle(id)?;
|
me.actions.recv.ensure_not_idle(id)?;
|
||||||
}
|
}
|
||||||
@@ -197,7 +197,7 @@ impl<B> Streams<B>
|
|||||||
|
|
||||||
let id = frame.stream_id();
|
let id = frame.stream_id();
|
||||||
|
|
||||||
let mut stream = match me.store.find_mut(&id) {
|
let stream = match me.store.find_mut(&id) {
|
||||||
Some(stream) => stream.key(),
|
Some(stream) => stream.key(),
|
||||||
None => return Err(ProtocolError.into()),
|
None => return Err(ProtocolError.into()),
|
||||||
};
|
};
|
||||||
@@ -253,12 +253,14 @@ impl<B> Streams<B>
|
|||||||
Ok(().into())
|
Ok(().into())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn apply_remote_settings(&mut self, frame: &frame::Settings) {
|
pub fn apply_remote_settings(&mut self, frame: &frame::Settings)
|
||||||
|
-> Result<(), ConnectionError>
|
||||||
|
{
|
||||||
let mut me = self.inner.lock().unwrap();
|
let mut me = self.inner.lock().unwrap();
|
||||||
let me = &mut *me;
|
let me = &mut *me;
|
||||||
|
|
||||||
me.actions.send.apply_remote_settings(
|
me.actions.send.apply_remote_settings(
|
||||||
frame, &mut me.store, &mut me.actions.task);
|
frame, &mut me.store, &mut me.actions.task)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn poll_send_request_ready(&mut self) -> Poll<(), ConnectionError> {
|
pub fn poll_send_request_ready(&mut self) -> Poll<(), ConnectionError> {
|
||||||
@@ -412,13 +414,11 @@ impl<B> StreamRef<B>
|
|||||||
let mut stream = me.store.resolve(self.key);
|
let mut stream = me.store.resolve(self.key);
|
||||||
|
|
||||||
me.actions.recv.release_capacity(
|
me.actions.recv.release_capacity(
|
||||||
capacity, &mut stream, &mut me.actions.send, &mut me.actions.task)
|
capacity, &mut stream, &mut me.actions.task)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Request capacity to send data
|
/// Request capacity to send data
|
||||||
pub fn reserve_capacity(&mut self, capacity: WindowSize)
|
pub fn reserve_capacity(&mut self, capacity: WindowSize) {
|
||||||
-> Result<(), ConnectionError>
|
|
||||||
{
|
|
||||||
let mut me = self.inner.lock().unwrap();
|
let mut me = self.inner.lock().unwrap();
|
||||||
let me = &mut *me;
|
let me = &mut *me;
|
||||||
|
|
||||||
|
|||||||
@@ -1,12 +1,13 @@
|
|||||||
use {frame, Body, ConnectionError, StreamId};
|
use {Body, ConnectionError};
|
||||||
|
use frame::{self, StreamId};
|
||||||
use proto::{self, Connection, WindowSize};
|
use proto::{self, Connection, WindowSize};
|
||||||
use error::Reason;
|
use error::Reason;
|
||||||
use error::Reason::*;
|
use error::Reason::*;
|
||||||
|
|
||||||
use http::{self, Request, Response};
|
use http::{Request, Response};
|
||||||
use futures::{self, Future, Sink, Poll, Async, AsyncSink, IntoFuture};
|
use futures::{self, Future, Sink, Poll, Async, AsyncSink, IntoFuture};
|
||||||
use tokio_io::{AsyncRead, AsyncWrite};
|
use tokio_io::{AsyncRead, AsyncWrite};
|
||||||
use bytes::{Bytes, IntoBuf, Buf};
|
use bytes::{Bytes, IntoBuf};
|
||||||
|
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
@@ -160,9 +161,7 @@ impl<B: IntoBuf> Stream<B> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Request capacity to send data
|
/// Request capacity to send data
|
||||||
pub fn reserve_capacity(&mut self, capacity: usize)
|
pub fn reserve_capacity(&mut self, capacity: usize) {
|
||||||
-> Result<(), ConnectionError>
|
|
||||||
{
|
|
||||||
// TODO: Check for overflow
|
// TODO: Check for overflow
|
||||||
self.inner.reserve_capacity(capacity as WindowSize)
|
self.inner.reserve_capacity(capacity as WindowSize)
|
||||||
}
|
}
|
||||||
@@ -186,7 +185,7 @@ impl<B: IntoBuf> Stream<B> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Send trailers
|
/// Send trailers
|
||||||
pub fn send_trailers(&mut self, trailers: ())
|
pub fn send_trailers(&mut self, _trailers: ())
|
||||||
-> Result<(), ConnectionError>
|
-> Result<(), ConnectionError>
|
||||||
{
|
{
|
||||||
unimplemented!();
|
unimplemented!();
|
||||||
@@ -220,8 +219,6 @@ impl<T> Future for Send<T>
|
|||||||
type Error = ConnectionError;
|
type Error = ConnectionError;
|
||||||
|
|
||||||
fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
|
fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
|
||||||
use futures::Stream;
|
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
if self.buf.is_none() {
|
if self.buf.is_none() {
|
||||||
// Get a chunk to send to the H2 stream
|
// Get a chunk to send to the H2 stream
|
||||||
|
|||||||
Reference in New Issue
Block a user