diff --git a/wtransport-proto/src/error.rs b/wtransport-proto/src/error.rs index 52dc964..4c3612a 100644 --- a/wtransport-proto/src/error.rs +++ b/wtransport-proto/src/error.rs @@ -53,6 +53,16 @@ pub enum ErrorCode { } impl ErrorCode { + /// Converts this stream [`ErrorCode`] to HTTP/3 error code. + /// + pub fn to_http3(self) -> VarInt { + let code = self.to_code(); + let first: u64 = 0x52e4a40fa8db; + let code = u64::from(code); + let val = first + code + (code / 0x1e); + VarInt::try_from_u64(val).expect("Valid conversion") + } + /// Returns the integer representation (code) of the error. pub fn to_code(self) -> VarInt { match self { diff --git a/wtransport/src/driver/mod.rs b/wtransport/src/driver/mod.rs index c2987be..6135478 100644 --- a/wtransport/src/driver/mod.rs +++ b/wtransport/src/driver/mod.rs @@ -137,7 +137,7 @@ impl Driver { stream .into_stream() - .stop(ErrorCode::BufferedStreamRejected.to_code()) + .stop(ErrorCode::BufferedStreamRejected.to_http3()) .expect("Stream not already stopped"); } } @@ -164,7 +164,7 @@ impl Driver { stream .into_stream() .1 - .stop(ErrorCode::BufferedStreamRejected.to_code()) + .stop(ErrorCode::BufferedStreamRejected.to_http3()) .expect("Stream not already stopped"); } } @@ -308,7 +308,7 @@ mod worker { if let DriverError::Proto(error_code) = &error { self.quic_connection - .close(varint_w2q(error_code.to_code()), b""); + .close(varint_w2q(error_code.to_http3()), b""); } self.driver_result.set(error); @@ -595,14 +595,14 @@ mod worker { Ok(session_request) => stream.into_session(session_request), Err(HeadersParseError::MethodNotConnect) => { stream - .stop(ErrorCode::RequestRejected.to_code()) + .stop(ErrorCode::RequestRejected.to_http3()) .expect("Stream not already stopped"); return Ok(()); } // TODO(biagio): we might have more granularity with errors Err(_) => { stream - .stop(ErrorCode::Message.to_code()) + .stop(ErrorCode::Message.to_http3()) .expect("Stream not already stopped"); return Ok(()); } @@ -613,7 +613,7 @@ mod worker { Err(TrySendError::Full(mut stream)) => { debug!("Discarding session request: sessions queue is full"); stream - .stop(ErrorCode::RequestRejected.to_code()) + .stop(ErrorCode::RequestRejected.to_http3()) .expect("Stream not already stopped"); } Err(TrySendError::Closed(_)) => return Err(DriverError::NotConnected), diff --git a/wtransport/src/endpoint.rs b/wtransport/src/endpoint.rs index 1b270db..aee3ce6 100644 --- a/wtransport/src/endpoint.rs +++ b/wtransport/src/endpoint.rs @@ -387,7 +387,7 @@ impl Endpoint { let frame = match stream_session.read_frame().await { Ok(frame) => frame, Err(ProtoReadError::H3(error_code)) => { - quic_connection.close(varint_w2q(error_code.to_code()), b""); + quic_connection.close(varint_w2q(error_code.to_http3()), b""); return Err(ConnectingError::ConnectionError( ConnectionError::local_h3_error(error_code), )); @@ -404,7 +404,7 @@ impl Endpoint { }; if !matches!(frame.kind(), FrameKind::Headers) { - quic_connection.close(varint_w2q(ErrorCode::FrameUnexpected.to_code()), b""); + quic_connection.close(varint_w2q(ErrorCode::FrameUnexpected.to_http3()), b""); return Err(ConnectingError::ConnectionError( ConnectionError::local_h3_error(ErrorCode::FrameUnexpected), )); @@ -413,7 +413,7 @@ impl Endpoint { let headers = match Headers::with_frame(&frame) { Ok(headers) => headers, Err(error_code) => { - quic_connection.close(varint_w2q(error_code.to_code()), b""); + quic_connection.close(varint_w2q(error_code.to_http3()), b""); return Err(ConnectingError::ConnectionError( ConnectionError::local_h3_error(error_code), )); @@ -423,7 +423,7 @@ impl Endpoint { let session_response = match SessionResponseProto::try_from(headers) { Ok(session_response) => session_response, Err(_) => { - quic_connection.close(varint_w2q(ErrorCode::Message.to_code()), b""); + quic_connection.close(varint_w2q(ErrorCode::Message.to_http3()), b""); return Err(ConnectingError::ConnectionError( ConnectionError::local_h3_error(ErrorCode::Message), )); @@ -759,7 +759,7 @@ impl SessionRequest { } Err(ProtoWriteError::Stopped) => { self.quic_connection - .close(varint_w2q(ErrorCode::ClosedCriticalStream.to_code()), b""); + .close(varint_w2q(ErrorCode::ClosedCriticalStream.to_http3()), b""); Err(ConnectionError::local_h3_error( ErrorCode::ClosedCriticalStream,