#[non_exhaustive]pub struct ServerConfig {Show 16 fields
pub http_host: String,
pub http_port: u16,
pub http2_port: Option<u16>,
pub https_host: String,
pub https_port: u16,
pub https_enabled: bool,
pub database_config: bool,
pub config_file: Option<String>,
pub max_connections: usize,
pub header_read_timeout_secs: u64,
pub idle_timeout_secs: u64,
pub http2_keepalive_interval_secs: u64,
pub http2_keepalive_timeout_secs: u64,
pub tunnel_idle_timeout_secs: u64,
pub allowed_upgrade_protocols: Vec<String>,
pub trust_forwarded_headers: bool,
}Expand description
Server configuration.
Fields (Non-exhaustive)§
This struct is marked as non-exhaustive
Struct { .. } syntax; cannot be matched against without a wildcard ..; and struct update syntax will not work.http_host: StringListen address for HTTP
http_port: u16Listen port for HTTP
http2_port: Option<u16>Dedicated HTTP/2-only listen port.
Optional and additive: the main port keeps serving HTTP/1.1 and h2c by sniffing. That sniffing is why a corrupted HTTP/2 preface gets an HTTP/1 400 rather than GOAWAY(PROTOCOL_ERROR) – it is indistinguishable from a malformed HTTP/1 request. A port that only ever speaks HTTP/2 has no such ambiguity.
https_host: StringListen address for HTTPS
https_port: u16Listen port for HTTPS
https_enabled: boolEnable HTTPS listener
database_config: boolDatabase-backed config enabled
config_file: Option<String>Config file path (for file-based bootstrap)
max_connections: usizeMost client connections served at once, across every listener.
Each connection costs a socket, a task and buffers, and an upstream socket besides; without a cap, a client that opens connections faster than they close runs the process out of file descriptors and everyone else is refused along with it. At the cap the proxy stops accepting, so further connections wait in the kernel’s backlog instead of failing. An upgraded tunnel holds its slot for as long as it is open.
header_read_timeout_secs: u64How long a client has to send a complete HTTP/1 request head.
Counted from when the proxy starts waiting for a request, so it also bounds the wait for the next request on a kept-alive connection. This is what stops a client trickling one header line at a time from holding a connection open indefinitely.
idle_timeout_secs: u64How long a connection may sit with no request in flight before it is closed, for every protocol.
Covers what the header timeout cannot: a connection that sends nothing at all (the cleartext port has to read the first bytes before it knows whether to speak HTTP/1 or HTTP/2), a TLS handshake that never finishes, and an HTTP/2 connection with no open streams.
http2_keepalive_interval_secs: u64Interval between HTTP/2 keep-alive PINGs. 0 disables them.
A peer that vanishes without closing leaves an HTTP/2 connection, and every stream on it, open until something notices; the PING is what notices.
http2_keepalive_timeout_secs: u64How long to wait for a PING to be acknowledged before closing the connection.
tunnel_idle_timeout_secs: u64How long an upgraded tunnel (WebSocket) may pass no bytes in either direction before it is closed.
Longer than the connection idle timeout because a WebSocket is expected to sit quiet between messages; most clients and servers ping well within this.
allowed_upgrade_protocols: Vec<String>Protocols a client may upgrade to, by HTTP/1.1 Upgrade or HTTP/2
extended CONNECT (:protocol). Compared case-insensitively.
An upgrade turns the connection into an opaque tunnel to the backend,
and a tunnel is not subject to routing: once Upgrade: h2c had been
tunnelled, the client could send the backend any request on any path,
past every route’s method and path rules. So only protocols that are
known to be safe to splice are allowed. A request asking for anything
else is forwarded as an ordinary request with the upgrade removed,
which RFC 9110 section 7.8 permits a server to do.
trust_forwarded_headers: boolTrust the X-Forwarded-* and Forwarded headers a client sends.
Off by default: the proxy is then the first hop, anything a client says about where it came from is a claim it made up, and the headers are overwritten with what the proxy itself saw. Turn it on only when every connection reaches this proxy through another proxy you control, which sets those headers itself; the client’s chain is then kept and this hop appended to it.
Trait Implementations§
Source§impl Clone for ServerConfig
impl Clone for ServerConfig
Source§impl Debug for ServerConfig
impl Debug for ServerConfig
Source§impl Default for ServerConfig
impl Default for ServerConfig
Source§impl<'de> Deserialize<'de> for ServerConfig
impl<'de> Deserialize<'de> for ServerConfig
Source§fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
Auto Trait Implementations§
impl Freeze for ServerConfig
impl RefUnwindSafe for ServerConfig
impl Send for ServerConfig
impl Sync for ServerConfig
impl Unpin for ServerConfig
impl UnsafeUnpin for ServerConfig
impl UnwindSafe for ServerConfig
Blanket Implementations§
Source§impl<'a, T, E> AsTaggedExplicit<'a, E> for Twhere
T: 'a,
impl<'a, T, E> AsTaggedExplicit<'a, E> for Twhere
T: 'a,
Source§impl<'a, T, E> AsTaggedImplicit<'a, E> for Twhere
T: 'a,
impl<'a, T, E> AsTaggedImplicit<'a, E> for Twhere
T: 'a,
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> DeserializeOwned for Twhere
T: for<'de> Deserialize<'de>,
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more