H3: settings and errors documentation

This commit is contained in:
stammw
2020-04-04 13:55:56 +02:00
committed by Dirkjan Ochtman
parent 8ee24df4d6
commit 28e211cf4b
2 changed files with 71 additions and 4 deletions
+43 -4
View File
@@ -34,46 +34,60 @@ use std::io::ErrorKind;
use proto::ErrorCode;
/// A future that resolves when the handshake ends durinng a 0-RTT exchange
pub type ZeroRttAccepted = quinn::ZeroRttAccepted;
/// General error enum for this crate
#[derive(Debug, Error)]
pub enum Error {
/// Cannot make a new request, bescause the connection is closing
#[error(display = "Connection is closing, resquest aborted")]
Aborted,
/// Protocol violation detected by the internal HTTP/3 protocol state machine
#[error(display = "H3 protocol error: {:?}", _0)]
Proto(proto::connection::Error),
/// Error occurred at the `QUIC` level
#[error(display = "QUIC protocol error: {}", _0)]
Quic(quinn::ConnectionError),
/// A `QUIC`-specific read error occurred
#[error(display = "QUIC read error: {}", _0)]
Read(ReadError),
/// A `QUIC`-specific write error occurred
#[error(display = "QUIC write error: {}", _0)]
Write(WriteError),
/// Programming error within the crate's code
#[error(display = "Internal error: {}", _0)]
Internal(String),
/// The peer's behavior was detected as incorrect or malicious
#[error(display = "Incorrect peer behavior: {}", _0)]
Peer(String),
/// The peer tried to open an unidirectional stream with an unknown type code
#[error(display = "unknown stream type {}", _0)]
UnknownStream(u64),
/// An IO error occurred
#[error(display = "IO error: {}", _0)]
Io(std::io::Error),
/// An overflow occurred into the `QPACK` decoder
#[error(display = "Overflow max data size")]
Overflow,
/// A future has been polled after it was already finished
#[error(display = "Polled after finished")]
Poll,
/// The peer issued an HTTP/3 error code and an optional text description
#[error(display = "Http error: {:?}", _0)]
Http(HttpError, Option<String>),
}
impl Error {
pub fn peer<T: Into<String>>(msg: T) -> Self {
pub(crate) fn peer<T: Into<String>>(msg: T) -> Self {
Error::Peer(msg.into())
}
pub fn internal<T: Into<String>>(msg: T) -> Self {
pub(crate) fn internal<T: Into<String>>(msg: T) -> Self {
Error::Internal(msg.into())
}
pub fn try_into_quic(&self) -> Option<&quinn_proto::ConnectionError> {
pub(crate) fn try_into_quic(&self) -> Option<&quinn_proto::ConnectionError> {
match self {
Error::Quic(e) => Some(e),
Error::Write(quinn::WriteError::ConnectionClosed(e)) => Some(e),
@@ -159,27 +173,52 @@ impl From<proto::headers::Error> for Error {
}
}
/// Errors defined by the HTTP/3 protocol
///
/// Read the [`HTTP/3 specification`] for more details.
///
/// [`HTTP/3 specification`]: https://quicwg.org/base-drafts/draft-ietf-quic-http.html#name-http-3-error-codes
#[derive(Debug)]
pub enum HttpError {
/// This is used when the connection or stream needs to be closed, but there is no error to signal
NoError,
/// Peer violated protocol requirements in a way which doesn't match a more specific error code, or endpoint declines to use the more specific error code
GeneralProtocolError,
/// An internal error has occurred in the HTTP stack
InternalError,
/// The endpoint detected that its peer created a stream that it will not accept
StreamCreationError,
/// A stream required by the connection was closed or reset
ClosedCriticalStream,
/// A frame was received which was not permitted in the current state or on the current stream
FrameUnexpected,
/// A frame that fails to satisfy layout requirements or with an invalid size was received
FrameError,
/// The endpoint detected that its peer is exhibiting a behavior that might be generating excessive load
ExcessiveLoad,
/// A Stream ID or Push ID was used incorrectly, such as exceeding a limit, reducing a limit, or being reused
IdError,
/// An endpoint detected an error in the payload of a SETTINGS frame
SettingsError,
/// No SETTINGS frame was received at the beginning of the control stream
MissingSettings,
/// A server rejected a request without performing any application processing
RequestRejected,
/// The request or its response (including pushed response) is cancelled
RequestCancelled,
/// The client's stream terminated without containing a fully-formed request
RequestIncomplete,
/// The connection established in response to a CONNECT request was reset or abnormally closed
ConnectError,
/// The requested operation cannot be served over HTTP/3. The peer should retry over HTTP/1.1
VersionFallback,
/// Decompression of a header block failed
QpackDecompressionFailed,
/// Error on the encoder stream
QpackEncoderStreamError,
/// Error on the decoder stream
QpackDecoderStreamError,
/// Unknown error code
Unknown(u32),
}
@@ -210,7 +249,7 @@ impl From<ErrorCode> for HttpError {
}
}
/// TLS ALPN value for H3
/// TLS ALPN value for the HTTP/3 protocol
pub const ALPN: &[u8] = b"h3-27";
impl From<frame::Error> for (ErrorCode, String, Error) {
+28
View File
@@ -36,6 +36,14 @@ impl Codec for SettingId {
}
}
/// Settings for a HTTP/3 connection
///
/// The HTTP/3 protocol offers a few settings to configure limits and header encoding
/// parameters of a connection.
///
/// See the [QPACK] specification for more details.
///
/// [QPACK]: https://quicwg.org/base-drafts/draft-ietf-quic-qpack.html
#[derive(Clone, Debug)]
pub struct Settings {
max_header_list_size: u64,
@@ -56,6 +64,8 @@ impl Default for Settings {
impl Settings {
/// Create settings with quinn-h3's recomended values
///
/// Enables `QPACK`.
pub fn new() -> Self {
Self {
max_header_list_size: 0,
@@ -64,6 +74,9 @@ impl Settings {
}
}
/// The maximum number of entries in headers and trailers
///
/// `0` means infinity.
pub fn max_header_list_size(&self) -> u64 {
if self.max_header_list_size == 0 {
return std::u64::MAX;
@@ -71,14 +84,23 @@ impl Settings {
self.max_header_list_size
}
/// The maximum size for `QPACK` encoding dynamic table
///
/// `0` means `QPACK` is disabled.
pub fn qpack_max_table_capacity(&self) -> u64 {
self.qpack_max_table_capacity
}
/// The maximum number of request waiting to be decoded with arriving encoder data
///
/// If `0`, the peer won't send any dynamically encoded headers.
pub fn qpack_max_blocked_streams(&self) -> u64 {
self.qpack_max_blocked_streams
}
/// Set the maximum number of entries in headers and trailers
///
/// `0` means infinity.
pub fn set_max_header_list_size(&mut self, value: u64) -> Result<&mut Self, InvalidValue> {
if value > VarInt::MAX.into_inner() as u64 {
return Err(InvalidValue(SettingId::QPACK_MAX_TABLE_CAPACITY, value));
@@ -87,6 +109,9 @@ impl Settings {
Ok(self)
}
/// Set the maximum size for `QPACK` encoding dynamic table
///
/// If `0`, the peer won't send any dynamically encoded headers.
pub fn set_qpack_max_blocked_streams(&mut self, value: u64) -> Result<&mut Self, InvalidValue> {
if value > MAX_BLOCKED_STREAMS_MAX {
return Err(InvalidValue(SettingId::QPACK_MAX_BLOCKED_STREAMS, value));
@@ -95,6 +120,9 @@ impl Settings {
Ok(self)
}
/// Set the maximum number of request waiting to be decoded with arriving encoder data
///
/// Set this to `0` to disable `QPACK`.
pub fn set_qpack_max_table_capacity(&mut self, value: u64) -> Result<&mut Self, InvalidValue> {
if value > MAX_TABLE_CAPACITY_MAX {
return Err(InvalidValue(SettingId::QPACK_MAX_TABLE_CAPACITY, value));