oddity_rtsp_protocol/
error.rs

1use std::convert;
2use std::error;
3use std::fmt;
4use std::io;
5
6use super::message::Uri;
7
8pub type Result<T> = std::result::Result<T, Error>;
9
10#[derive(Debug)]
11pub enum Error {
12    /// An error occurred decoding the header due to incorrect usage
13    /// of text encoding by the sender.
14    Encoding,
15    /// The request line of the head part is malformed.
16    RequestLineMalformed { line: String },
17    /// The header first line does have a method and target URI, but
18    /// it does not have a version, which is the required third part
19    /// of the first line of the head.
20    VersionMissing { line: String },
21    /// The response status line does have a version, but does not have
22    /// a status code which is required.
23    StatusCodeMissing { line: String },
24    /// The specified method is not a valid method.
25    MethodUnknown { method: String },
26    /// The header first line does have a method, but it does not have
27    /// a target URI, which is the required second part of the first
28    /// line of the head.
29    UriMissing { line: String },
30    /// The header first line has a Request-URI, but it could not be
31    /// parsed correctly.
32    UriMalformed { line: String, uri: String },
33    /// The Request-URI is correct, but represents a relative path,
34    /// which is not allowed in RTSP.
35    UriNotAbsolute { uri: Uri },
36    /// The response status line has a version and status code, but is
37    /// missing a reason phrase which is required.
38    ReasonPhraseMissing { line: String },
39    /// The version specifier is incorrect. It should start with "RTSP/"
40    /// followed by a digit, "." and another digit.
41    VersionMalformed { line: String, version: String },
42    /// The provided status code is not an unsigned integer or cannot be
43    /// converted to one. It must be a 3-digit non-negative number.
44    StatusCodeNotInteger { line: String, status_code: String },
45    /// Header line is malformed.
46    HeaderMalformed { line: String },
47    /// The Content-Length header is missing, but it is required.
48    ContentLengthMissing,
49    /// The Content-Length header is not an integer value, or cannot be
50    /// converted to an unsigned integer.
51    ContentLengthNotInteger { value: String },
52    /// This occurs when the caller invokes the state machine with a
53    /// state that signals that parsing the head part of the request
54    /// was already done before.
55    HeadAlreadyDone,
56    /// This occurs when the caller invokes the state machine with a
57    /// state that signals that parsing the body part of the request
58    /// was already done before.
59    BodyAlreadyDone,
60    /// Metadata was not parsed for some reason.
61    MetadataNotParsed,
62    /// This occurs when the caller tries to turn the parser into an
63    /// actual request, but the parser was not ready yet.
64    NotDone,
65    /// This occurs when trying to serialize a request that does not
66    /// have a known version.
67    VersionUnknown,
68    /// Transport header does not have protocol and profile string.
69    /// The transport must start with `RTP/AVP`, where `RTP` denotes
70    /// the protocol and `AVP` the profile.
71    TransportProtocolProfileMissing { value: String },
72    /// Transport header contains unknown lower protocol. Use either
73    /// `TCP` or `UDP`.
74    TransportLowerUnknown { value: String },
75    /// Transport header contains unknown parameter. Please see RFC
76    /// 2326 Section 12.39 for a list of permissable parameters.
77    TransportParameterUnknown { var: String },
78    /// Transport header contains parameter that should have a value,
79    /// but does not have one.
80    TransportParameterValueMissing { var: String },
81    /// Transport header contains parameter with invalid value.
82    TransportParameterValueInvalid { var: String, val: String },
83    /// Transport header contains invalid or malformed parameter.
84    TransportParameterInvalid { parameter: String },
85    /// Transport header channel is malformed.
86    TransportChannelMalformed { value: String },
87    /// Transport header port is malformed.
88    TransportPortMalformed { value: String },
89    /// Tried to parse interleaved data but there is no interleaved
90    /// header. Interleaved packets always start with `$` (0x24).
91    InterleavedInvalid,
92    /// Interleaved payload too large. The size cannot be larger than
93    /// the maximum value of a 16-bit unsigned integer.
94    InterleavedPayloadTooLarge,
95    /// Range header value malformed.
96    RangeMalformed { value: String },
97    /// Parser does not support provided `Range` header unit.
98    RangeUnitNotSupported { value: String },
99    /// Parser does not support effective time in `Range` header.
100    RangeTimeNotSupported { value: String },
101    /// The NPT time (either the from or to part of the time specifier)
102    /// is malformed.
103    RangeNptTimeMalfored { value: String },
104    /// RTP Info must always contain a URL.
105    RtpInfoUrlMissing { value: String },
106    /// RTP Info parameter is not known. This means that the RTP part
107    /// contains an unknown or non-existant parameter variable.
108    RtpInfoParameterUnknown { value: String },
109    /// RTP Info parameter is invalid. This happens, for example, when
110    /// the `seq` parameter is not an integer.
111    RtpInfoParameterInvalid { value: String },
112    /// RTP Info contains unexpected extra parameter.
113    RtpInfoParameterUnexpected { value: String },
114    /// Underlying socket was shut down. This is not really an error and
115    /// consumers are expected to handle it gracefully.
116    Shutdown,
117    /// I/O error occurred.
118    Io(io::Error),
119}
120
121impl fmt::Display for Error {
122    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
123        match self {
124            Error::Encoding => write!(f, "encoding incorrect"),
125            Error::RequestLineMalformed { line } => write!(f, "request line malformed: {}", &line),
126            Error::VersionMissing { line } => {
127                write!(f, "version missing in request line: {}", &line)
128            }
129            Error::StatusCodeMissing { line } => {
130                write!(f, "status code missing in response line: {}", &line)
131            }
132            Error::MethodUnknown { method } => write!(f, "method unknown: {}", &method),
133            Error::UriMissing { line } => write!(f, "uri missing in request line: {}", &line),
134            Error::UriMalformed { line, uri } => {
135                write!(f, "uri malformed: {} (in line: {})", &uri, &line)
136            }
137            Error::UriNotAbsolute { uri } => {
138                write!(f, "uri must be absolute, but it is relative: {}", &uri)
139            }
140            Error::ReasonPhraseMissing { line } => {
141                write!(f, "reason phrase missing in response line: {}", &line)
142            }
143            Error::VersionMalformed { line, version } => {
144                write!(f, "version malformed: {} (in line: {})", &version, &line)
145            }
146            Error::StatusCodeNotInteger { line, status_code } => write!(
147                f,
148                "response has invalid status code: {} (in response line: {})",
149                &status_code, &line
150            ),
151            Error::HeaderMalformed { line } => write!(f, "header line malformed: {}", &line),
152            Error::ContentLengthMissing => write!(f, "request does not have Content-Length header"),
153            Error::ContentLengthNotInteger { value } => write!(
154                f,
155                "request has invalid value for Content-Length: {}",
156                &value
157            ),
158            Error::HeadAlreadyDone => write!(f, "head already done (cycle in state machine)"),
159            Error::BodyAlreadyDone => write!(f, "body already done (cycle in state machine)"),
160            Error::MetadataNotParsed => write!(f, "metadata not parsed"),
161            Error::NotDone => write!(f, "parser not done yet"),
162            Error::VersionUnknown => write!(f, "response has unknown version"),
163            Error::TransportProtocolProfileMissing { value } => {
164                write!(f, "transport protocol and/or profile missing: {}", &value)
165            }
166            Error::TransportLowerUnknown { value } => {
167                write!(f, "transport lower protocol unknown: {}", &value)
168            }
169            Error::TransportParameterUnknown { var } => {
170                write!(f, "transport parameter unknown: {}", &var)
171            }
172            Error::TransportParameterValueMissing { var } => write!(
173                f,
174                "transport parameter should have value but does not (var: {})",
175                &var
176            ),
177            Error::TransportParameterValueInvalid { var, val } => write!(
178                f,
179                "transport parameter value is invalid or malformed (var: {}, val: {})",
180                &var, &val
181            ),
182            Error::TransportParameterInvalid { parameter } => {
183                write!(f, "transport parameter invalid: {}", &parameter)
184            }
185            Error::TransportChannelMalformed { value } => {
186                write!(f, "transport channel malformed: {}", &value)
187            }
188            Error::TransportPortMalformed { value } => {
189                write!(f, "transport port malformed: {}", &value)
190            }
191            Error::InterleavedInvalid => write!(
192                f,
193                "interleaved data does not have valid header magic character"
194            ),
195            Error::InterleavedPayloadTooLarge => write!(f, "interleaved payload too large"),
196            Error::RangeMalformed { value } => write!(f, "range malformed: {}", value),
197            Error::RangeUnitNotSupported { value } => {
198                write!(f, "range unit not supported: {}", &value)
199            }
200            Error::RangeTimeNotSupported { value } => {
201                write!(f, "range time not supported: {}", &value)
202            }
203            Error::RangeNptTimeMalfored { value } => {
204                write!(f, "range npt time malformed: {}", &value)
205            }
206            Error::RtpInfoUrlMissing { value } => write!(f, "rtp info url missing: {}", &value),
207            Error::RtpInfoParameterUnknown { value } => {
208                write!(f, "rtp info parameter unknown: {}", &value)
209            }
210            Error::RtpInfoParameterInvalid { value } => {
211                write!(f, "rtp info parameter invalid: {}", &value)
212            }
213            Error::RtpInfoParameterUnexpected { value } => {
214                write!(f, "rtp info contains unexpected parameter: {}", &value)
215            }
216            Error::Shutdown => write!(f, "underlying socket was shut down"),
217            Error::Io(err) => write!(f, "{}", err),
218        }
219    }
220}
221
222impl convert::From<io::Error> for Error {
223    fn from(error: io::Error) -> Self {
224        Error::Io(error)
225    }
226}
227
228impl error::Error for Error {}