feat(server): add http2_max_concurrent_streams builder option
Closes #1772
This commit is contained in:
@@ -50,9 +50,8 @@ where
|
|||||||
B: Payload,
|
B: Payload,
|
||||||
E: H2Exec<S::Future, B>,
|
E: H2Exec<S::Future, B>,
|
||||||
{
|
{
|
||||||
pub(crate) fn new(io: T, service: S, exec: E) -> Server<T, S, B, E> {
|
pub(crate) fn new(io: T, service: S, builder: &Builder, exec: E) -> Server<T, S, B, E> {
|
||||||
let handshake = Builder::new()
|
let handshake = builder.handshake(io);
|
||||||
.handshake(io);
|
|
||||||
Server {
|
Server {
|
||||||
exec,
|
exec,
|
||||||
state: State::Handshaking(handshake),
|
state: State::Handshaking(handshake),
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ use std::sync::Arc;
|
|||||||
use bytes::Bytes;
|
use bytes::Bytes;
|
||||||
use futures::{Async, Future, Poll, Stream};
|
use futures::{Async, Future, Poll, Stream};
|
||||||
use futures::future::{Either, Executor};
|
use futures::future::{Either, Executor};
|
||||||
|
use h2;
|
||||||
use tokio_io::{AsyncRead, AsyncWrite};
|
use tokio_io::{AsyncRead, AsyncWrite};
|
||||||
#[cfg(feature = "runtime")] use tokio_reactor::Handle;
|
#[cfg(feature = "runtime")] use tokio_reactor::Handle;
|
||||||
|
|
||||||
@@ -46,6 +47,7 @@ pub struct Http<E = Exec> {
|
|||||||
exec: E,
|
exec: E,
|
||||||
h1_half_close: bool,
|
h1_half_close: bool,
|
||||||
h1_writev: bool,
|
h1_writev: bool,
|
||||||
|
h2_builder: h2::server::Builder,
|
||||||
mode: ConnectionMode,
|
mode: ConnectionMode,
|
||||||
keep_alive: bool,
|
keep_alive: bool,
|
||||||
max_buf_size: Option<usize>,
|
max_buf_size: Option<usize>,
|
||||||
@@ -120,14 +122,14 @@ where
|
|||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
enum Fallback<E> {
|
enum Fallback<E> {
|
||||||
ToHttp2(E),
|
ToHttp2(h2::server::Builder, E),
|
||||||
Http1Only,
|
Http1Only,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<E> Fallback<E> {
|
impl<E> Fallback<E> {
|
||||||
fn to_h2(&self) -> bool {
|
fn to_h2(&self) -> bool {
|
||||||
match *self {
|
match *self {
|
||||||
Fallback::ToHttp2(_) => true,
|
Fallback::ToHttp2(..) => true,
|
||||||
Fallback::Http1Only => false,
|
Fallback::Http1Only => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -165,6 +167,7 @@ impl Http {
|
|||||||
exec: Exec::Default,
|
exec: Exec::Default,
|
||||||
h1_half_close: true,
|
h1_half_close: true,
|
||||||
h1_writev: true,
|
h1_writev: true,
|
||||||
|
h2_builder: h2::server::Builder::default(),
|
||||||
mode: ConnectionMode::Fallback,
|
mode: ConnectionMode::Fallback,
|
||||||
keep_alive: true,
|
keep_alive: true,
|
||||||
max_buf_size: None,
|
max_buf_size: None,
|
||||||
@@ -236,6 +239,19 @@ impl<E> Http<E> {
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Sets the [`SETTINGS_MAX_CONCURRENT_STREAMS`][spec] option for HTTP2
|
||||||
|
/// connections.
|
||||||
|
///
|
||||||
|
/// Default is no limit (`None`).
|
||||||
|
///
|
||||||
|
/// [spec]: https://http2.github.io/http2-spec/#SETTINGS_MAX_CONCURRENT_STREAMS
|
||||||
|
pub fn http2_max_concurrent_streams(&mut self, max: impl Into<Option<u32>>) -> &mut Self {
|
||||||
|
if let Some(max) = max.into() {
|
||||||
|
self.h2_builder.max_concurrent_streams(max);
|
||||||
|
}
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
/// Enables or disables HTTP keep-alive.
|
/// Enables or disables HTTP keep-alive.
|
||||||
///
|
///
|
||||||
/// Default is true.
|
/// Default is true.
|
||||||
@@ -278,6 +294,7 @@ impl<E> Http<E> {
|
|||||||
exec,
|
exec,
|
||||||
h1_half_close: self.h1_half_close,
|
h1_half_close: self.h1_half_close,
|
||||||
h1_writev: self.h1_writev,
|
h1_writev: self.h1_writev,
|
||||||
|
h2_builder: self.h2_builder,
|
||||||
mode: self.mode,
|
mode: self.mode,
|
||||||
keep_alive: self.keep_alive,
|
keep_alive: self.keep_alive,
|
||||||
max_buf_size: self.max_buf_size,
|
max_buf_size: self.max_buf_size,
|
||||||
@@ -350,7 +367,7 @@ impl<E> Http<E> {
|
|||||||
}
|
}
|
||||||
ConnectionMode::H2Only => {
|
ConnectionMode::H2Only => {
|
||||||
let rewind_io = Rewind::new(io);
|
let rewind_io = Rewind::new(io);
|
||||||
let h2 = proto::h2::Server::new(rewind_io, service, self.exec.clone());
|
let h2 = proto::h2::Server::new(rewind_io, service, &self.h2_builder, self.exec.clone());
|
||||||
Either::B(h2)
|
Either::B(h2)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -358,7 +375,7 @@ impl<E> Http<E> {
|
|||||||
Connection {
|
Connection {
|
||||||
conn: Some(either),
|
conn: Some(either),
|
||||||
fallback: if self.mode == ConnectionMode::Fallback {
|
fallback: if self.mode == ConnectionMode::Fallback {
|
||||||
Fallback::ToHttp2(self.exec.clone())
|
Fallback::ToHttp2(self.h2_builder.clone(), self.exec.clone())
|
||||||
} else {
|
} else {
|
||||||
Fallback::Http1Only
|
Fallback::Http1Only
|
||||||
},
|
},
|
||||||
@@ -538,11 +555,16 @@ where
|
|||||||
};
|
};
|
||||||
let mut rewind_io = Rewind::new(io);
|
let mut rewind_io = Rewind::new(io);
|
||||||
rewind_io.rewind(read_buf);
|
rewind_io.rewind(read_buf);
|
||||||
let exec = match self.fallback {
|
let (builder, exec) = match self.fallback {
|
||||||
Fallback::ToHttp2(ref exec) => exec.clone(),
|
Fallback::ToHttp2(ref builder, ref exec) => (builder, exec),
|
||||||
Fallback::Http1Only => unreachable!("upgrade_h2 with Fallback::Http1Only"),
|
Fallback::Http1Only => unreachable!("upgrade_h2 with Fallback::Http1Only"),
|
||||||
};
|
};
|
||||||
let h2 = proto::h2::Server::new(rewind_io, dispatch.into_service(), exec);
|
let h2 = proto::h2::Server::new(
|
||||||
|
rewind_io,
|
||||||
|
dispatch.into_service(),
|
||||||
|
builder,
|
||||||
|
exec.clone(),
|
||||||
|
);
|
||||||
|
|
||||||
debug_assert!(self.conn.is_none());
|
debug_assert!(self.conn.is_none());
|
||||||
self.conn = Some(Either::B(h2));
|
self.conn = Some(Either::B(h2));
|
||||||
|
|||||||
@@ -302,6 +302,17 @@ impl<I, E> Builder<I, E> {
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Sets the [`SETTINGS_MAX_CONCURRENT_STREAMS`][spec] option for HTTP2
|
||||||
|
/// connections.
|
||||||
|
///
|
||||||
|
/// Default is no limit (`None`).
|
||||||
|
///
|
||||||
|
/// [spec]: https://http2.github.io/http2-spec/#SETTINGS_MAX_CONCURRENT_STREAMS
|
||||||
|
pub fn http2_max_concurrent_streams(mut self, max: impl Into<Option<u32>>) -> Self {
|
||||||
|
self.protocol.http2_max_concurrent_streams(max.into());
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
/// Set the maximum buffer size.
|
/// Set the maximum buffer size.
|
||||||
///
|
///
|
||||||
/// Default is ~ 400kb.
|
/// Default is ~ 400kb.
|
||||||
|
|||||||
Reference in New Issue
Block a user