1 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
2 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
3 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
4 // option. This file may not be copied, modified, or distributed
5 // except according to those terms.
6 
7 #![cfg_attr(feature = "deny-warnings", deny(warnings))]
8 #![warn(clippy::use_self)]
9 
10 mod client_events;
11 mod connection;
12 pub mod connection_client;
13 mod connection_server;
14 mod control_stream_local;
15 mod control_stream_remote;
16 pub mod hframe;
17 mod hsettings_frame;
18 mod response_stream;
19 pub mod server;
20 mod server_connection_events;
21 mod server_events;
22 mod stream_type_reader;
23 mod transaction_client;
24 pub mod transaction_server;
25 //pub mod server;
26 
27 use neqo_qpack::Error as QpackError;
28 pub use neqo_transport::Output;
29 use neqo_transport::{AppError, Error as TransportError};
30 
31 pub use client_events::Http3ClientEvent;
32 pub use connection::Http3State;
33 pub use connection_client::Http3Client;
34 pub use neqo_qpack::Header;
35 pub use server::Http3Server;
36 pub use server_events::Http3ServerEvent;
37 pub use transaction_server::TransactionServer;
38 
39 type Res<T> = Result<T, Error>;
40 
41 #[derive(Clone, Debug, PartialEq)]
42 pub enum Error {
43     HttpNoError,
44     HttpGeneralProtocolError,
45     HttpInternalError,
46     HttpStreamCreationError,
47     HttpClosedCriticalStream,
48     HttpFrameUnexpected,
49     HttpFrameError,
50     HttpExcessiveLoad,
51     HttpIdError,
52     HttpSettingsError,
53     HttpMissingSettings,
54     HttpRequestRejected,
55     HttpRequestCancelled,
56     HttpRequestIncomplete,
57     HttpEarlyResponse,
58     HttpConnectError,
59     HttpVersionFallback,
60     QpackError(neqo_qpack::Error),
61 
62     // Internal errors from here.
63     AlreadyClosed,
64     DecodingFrame,
65     InvalidStreamId,
66     NoMoreData,
67     NotEnoughData,
68     TransportError(TransportError),
69     Unavailable,
70     Unexpected,
71     InvalidResumptionToken,
72 }
73 
74 impl Error {
code(&self) -> AppError75     pub fn code(&self) -> AppError {
76         match self {
77             Self::HttpNoError => 0x100,
78             Self::HttpGeneralProtocolError => 0x101,
79             Self::HttpInternalError => 0x102,
80             Self::HttpStreamCreationError => 0x103,
81             Self::HttpClosedCriticalStream => 0x104,
82             Self::HttpFrameUnexpected => 0x105,
83             Self::HttpFrameError => 0x106,
84             Self::HttpExcessiveLoad => 0x107,
85             Self::HttpIdError => 0x108,
86             Self::HttpSettingsError => 0x109,
87             Self::HttpMissingSettings => 0x10a,
88             Self::HttpRequestRejected => 0x10b,
89             Self::HttpRequestCancelled => 0x10c,
90             Self::HttpRequestIncomplete => 0x10d,
91             Self::HttpEarlyResponse => 0x10e,
92             Self::HttpConnectError => 0x10f,
93             Self::HttpVersionFallback => 0x110,
94             Self::QpackError(e) => e.code(),
95             // These are all internal errors.
96             _ => 3,
97         }
98     }
99 }
100 
101 impl From<TransportError> for Error {
from(err: TransportError) -> Self102     fn from(err: TransportError) -> Self {
103         Self::TransportError(err)
104     }
105 }
106 
107 impl From<QpackError> for Error {
from(err: QpackError) -> Self108     fn from(err: QpackError) -> Self {
109         Self::QpackError(err)
110     }
111 }
112 
113 impl From<AppError> for Error {
from(error: AppError) -> Self114     fn from(error: AppError) -> Self {
115         match error {
116             0x100 => Self::HttpNoError,
117             0x101 => Self::HttpGeneralProtocolError,
118             0x102 => Self::HttpInternalError,
119             0x103 => Self::HttpStreamCreationError,
120             0x104 => Self::HttpClosedCriticalStream,
121             0x105 => Self::HttpFrameUnexpected,
122             0x106 => Self::HttpFrameError,
123             0x107 => Self::HttpExcessiveLoad,
124             0x108 => Self::HttpIdError,
125             0x109 => Self::HttpSettingsError,
126             0x10a => Self::HttpMissingSettings,
127             0x10b => Self::HttpRequestRejected,
128             0x10c => Self::HttpRequestCancelled,
129             0x10d => Self::HttpRequestIncomplete,
130             0x10e => Self::HttpEarlyResponse,
131             0x10f => Self::HttpConnectError,
132             0x110 => Self::HttpVersionFallback,
133             0x200 => Self::QpackError(QpackError::DecompressionFailed),
134             0x201 => Self::QpackError(QpackError::EncoderStream),
135             0x202 => Self::QpackError(QpackError::DecoderStream),
136             _ => Self::HttpInternalError,
137         }
138     }
139 }
140 
141 impl ::std::error::Error for Error {
source(&self) -> Option<&(dyn ::std::error::Error + 'static)>142     fn source(&self) -> Option<&(dyn ::std::error::Error + 'static)> {
143         match self {
144             Self::TransportError(e) => Some(e),
145             Self::QpackError(e) => Some(e),
146             _ => None,
147         }
148     }
149 }
150 
151 impl ::std::fmt::Display for Error {
fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result152     fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
153         write!(f, "HTTP/3 error: {:?}", self)
154     }
155 }
156