Skip to main content

msf_rtsp/
response.rs

1//! Response types.
2
3use bytes::{Bytes, BytesMut};
4use tokio_util::codec::{Decoder, Encoder};
5
6use crate::{
7    CodecError, Protocol, Version,
8    header::{FieldIter, HeaderField, HeaderFieldValue, Iter},
9    ttpkit::response::{
10        ResponseHeader as GenericResponseHeader,
11        ResponseHeaderBuilder as GenericResponseHeaderBuilder,
12        ResponseHeaderDecoder as GenericResponseHeaderDecoder,
13        ResponseHeaderEncoder as GenericResponseHeaderEncoder, Status as GenericStatus,
14    },
15};
16
17pub use crate::ttpkit::response::{ResponseHeaderDecoderOptions, StatusMessage};
18
19/// RTSP response status.
20#[repr(transparent)]
21#[derive(Debug, Clone)]
22pub struct Status {
23    inner: GenericStatus,
24}
25
26impl Status {
27    pub const OK: Self = Self::from_static_str(200, "OK");
28    pub const NO_CONTENT: Self = Self::from_static_str(204, "No Content");
29    pub const BAD_REQUEST: Self = Self::from_static_str(400, "Bad Request");
30    pub const UNAUTHORIZED: Self = Self::from_static_str(401, "Unauthorized");
31    pub const NOT_FOUND: Self = Self::from_static_str(404, "Not Found");
32    pub const METHOD_NOT_ALLOWED: Self = Self::from_static_str(405, "Method Not Allowed");
33    pub const SESSION_NOT_FOUND: Self = Self::from_static_str(454, "Session Not Found");
34    pub const METHOD_NOT_VALID_IN_THIS_STATE: Self =
35        Self::from_static_str(455, "Method Not Valid in This State");
36    pub const HEADER_FIELD_NOT_VALID_FOR_RESOURCE: Self =
37        Self::from_static_str(456, "Header Field Not Valid for Resource");
38    pub const INVALID_RANGE: Self = Self::from_static_str(457, "Invalid Range");
39    pub const UNSUPPORTED_TRANSPORT: Self = Self::from_static_str(461, "Unsupported Transport");
40    pub const DESTINATION_PROHIBITED: Self = Self::from_static_str(463, "Destination Prohibited");
41    pub const INTERNAL_SERVER_ERROR: Self = Self::from_static_str(500, "Internal Server Error");
42    pub const NOT_IMPLEMENTED: Self = Self::from_static_str(501, "Not Implemented");
43    pub const BAD_GATEWAY: Self = Self::from_static_str(502, "Bad Gateway");
44    pub const RTSP_VERSION_NOT_SUPPORTED: Self =
45        Self::from_static_str(505, "RTSP Version Not Supported");
46    pub const OPTION_NOT_SUPPORTED: Self = Self::from_static_str(551, "Option Not Supported");
47
48    /// Create a new status with a given code and a message.
49    pub fn new<T>(code: u16, msg: T) -> Self
50    where
51        T: Into<StatusMessage>,
52    {
53        Self {
54            inner: GenericStatus::new(code, msg.into()),
55        }
56    }
57
58    /// Create a new status with a given code and a message.
59    #[inline]
60    pub const fn from_static_str(code: u16, msg: &'static str) -> Self {
61        Self {
62            inner: GenericStatus::from_static_str(code, msg),
63        }
64    }
65
66    /// Create a new status with a given code and a message.
67    #[inline]
68    pub const fn from_static_bytes(code: u16, msg: &'static [u8]) -> Self {
69        Self {
70            inner: GenericStatus::from_static_bytes(code, msg),
71        }
72    }
73
74    /// Create a status reference from a generic status reference.
75    #[inline]
76    const fn from_generic_ref(status: &GenericStatus) -> &Self {
77        let ptr = status as *const GenericStatus;
78
79        // SAFETY: `Self` is `repr(transparent)` over `GenericStatus`.
80        unsafe { &*(ptr as *const Self) }
81    }
82
83    /// Get the status code.
84    #[inline]
85    pub fn code(&self) -> u16 {
86        self.inner.code()
87    }
88
89    /// Get the status message.
90    #[inline]
91    pub fn message(&self) -> &StatusMessage {
92        self.inner.message()
93    }
94}
95
96/// RTSP response header.
97#[derive(Clone)]
98pub struct ResponseHeader {
99    inner: GenericResponseHeader<Protocol, Version>,
100}
101
102impl ResponseHeader {
103    /// Create a new header.
104    #[inline]
105    pub(crate) const fn new(inner: GenericResponseHeader<Protocol, Version>) -> Self {
106        Self { inner }
107    }
108
109    /// Get the response status.
110    #[inline]
111    pub fn status(&self) -> &Status {
112        Status::from_generic_ref(self.inner.status())
113    }
114
115    /// Get the status code.
116    #[inline]
117    pub fn status_code(&self) -> u16 {
118        self.inner.status_code()
119    }
120
121    /// Get the status message.
122    #[inline]
123    pub fn status_message(&self) -> &StatusMessage {
124        self.inner.status_message()
125    }
126
127    /// Get all header fields.
128    #[inline]
129    pub fn get_all_header_fields(&self) -> Iter<'_> {
130        self.inner.get_all_header_fields()
131    }
132
133    /// Get header fields corresponding to a given name.
134    pub fn get_header_fields<'a, N>(&'a self, name: &'a N) -> FieldIter<'a>
135    where
136        N: AsRef<[u8]> + ?Sized,
137    {
138        self.inner.get_header_fields(name)
139    }
140
141    /// Get the last header field of a given name.
142    pub fn get_header_field<'a, N>(&'a self, name: &'a N) -> Option<&'a HeaderField>
143    where
144        N: AsRef<[u8]> + ?Sized,
145    {
146        self.inner.get_header_field(name)
147    }
148
149    /// Get value of the last header field with a given name.
150    pub fn get_header_field_value<'a, N>(&'a self, name: &'a N) -> Option<&'a HeaderFieldValue>
151    where
152        N: AsRef<[u8]> + ?Sized,
153    {
154        self.inner.get_header_field_value(name)
155    }
156}
157
158/// RTSP response builder.
159pub struct ResponseBuilder {
160    header: GenericResponseHeaderBuilder<Protocol, Version>,
161}
162
163impl ResponseBuilder {
164    /// Create a new response builder.
165    #[inline]
166    pub const fn new() -> Self {
167        Self {
168            header: GenericResponseHeader::builder(
169                Protocol,
170                Version::Version10,
171                GenericStatus::from_static_str(200, "OK"),
172            ),
173        }
174    }
175
176    /// Create a new response builder with a given status.
177    #[inline]
178    pub fn new_with_status(status: Status) -> Self {
179        Self {
180            header: GenericResponseHeader::builder(Protocol, Version::Version10, status.inner),
181        }
182    }
183
184    /// Set the RTSP version.
185    #[inline]
186    pub fn set_version(mut self, version: Version) -> Self {
187        self.header = self.header.set_version(version);
188        self
189    }
190
191    /// Set the response status.
192    #[inline]
193    pub fn set_status(mut self, status: Status) -> Self {
194        self.header = self.header.set_status(status.inner);
195        self
196    }
197
198    /// Replace the current header fields having the same name (if any).
199    pub fn set_header_field<T>(mut self, field: T) -> Self
200    where
201        T: Into<HeaderField>,
202    {
203        self.header = self.header.set_header_field(field);
204        self
205    }
206
207    /// Add a given header field.
208    pub fn add_header_field<T>(mut self, field: T) -> Self
209    where
210        T: Into<HeaderField>,
211    {
212        self.header = self.header.add_header_field(field);
213        self
214    }
215
216    /// Remove all header fields with a given name.
217    pub fn remove_header_fields<N>(mut self, name: &N) -> Self
218    where
219        N: AsRef<[u8]> + ?Sized,
220    {
221        self.header = self.header.remove_header_fields(name);
222        self
223    }
224
225    /// Build just the response header.
226    #[inline]
227    pub fn header(self) -> ResponseHeader {
228        ResponseHeader::new(self.header.build())
229    }
230
231    /// Build the response.
232    pub fn body(self, body: Bytes) -> Response {
233        Response::new(self.header(), body)
234    }
235}
236
237impl Default for ResponseBuilder {
238    #[inline]
239    fn default() -> Self {
240        Self::new()
241    }
242}
243
244impl From<ResponseHeader> for ResponseBuilder {
245    #[inline]
246    fn from(header: ResponseHeader) -> ResponseBuilder {
247        Self {
248            header: header.inner.into(),
249        }
250    }
251}
252
253/// RTSP response.
254#[derive(Clone)]
255pub struct Response {
256    header: ResponseHeader,
257    body: Bytes,
258}
259
260impl Response {
261    /// Get a response builder.
262    #[inline]
263    pub const fn builder() -> ResponseBuilder {
264        ResponseBuilder::new()
265    }
266
267    /// Create a new response.
268    #[inline]
269    pub(crate) const fn new(header: ResponseHeader, body: Bytes) -> Self {
270        Self { header, body }
271    }
272
273    /// Get the response header.
274    #[inline]
275    pub fn header(&self) -> &ResponseHeader {
276        &self.header
277    }
278
279    /// Get the response status.
280    #[inline]
281    pub fn status(&self) -> &Status {
282        self.header.status()
283    }
284
285    /// Get the status code.
286    #[inline]
287    pub fn status_code(&self) -> u16 {
288        self.header.status_code()
289    }
290
291    /// Get the status message.
292    #[inline]
293    pub fn status_message(&self) -> &StatusMessage {
294        self.header.status_message()
295    }
296
297    /// Get all header fields.
298    #[inline]
299    pub fn get_all_header_fields(&self) -> Iter<'_> {
300        self.header.get_all_header_fields()
301    }
302
303    /// Get header fields corresponding to a given name.
304    pub fn get_header_fields<'a, N>(&'a self, name: &'a N) -> FieldIter<'a>
305    where
306        N: AsRef<[u8]> + ?Sized,
307    {
308        self.header.get_header_fields(name)
309    }
310
311    /// Get the last header field of a given name.
312    pub fn get_header_field<'a, N>(&'a self, name: &'a N) -> Option<&'a HeaderField>
313    where
314        N: AsRef<[u8]> + ?Sized,
315    {
316        self.header.get_header_field(name)
317    }
318
319    /// Get value of the last header field with a given name.
320    pub fn get_header_field_value<'a, N>(&'a self, name: &'a N) -> Option<&'a HeaderFieldValue>
321    where
322        N: AsRef<[u8]> + ?Sized,
323    {
324        self.header.get_header_field_value(name)
325    }
326
327    /// Get the response body.
328    #[inline]
329    pub fn body(&self) -> &Bytes {
330        &self.body
331    }
332
333    /// Split the response into its header and body.
334    #[inline]
335    pub fn deconstruct(self) -> (ResponseHeader, Bytes) {
336        (self.header, self.body)
337    }
338}
339
340/// Response header decoder.
341pub struct ResponseHeaderDecoder {
342    inner: GenericResponseHeaderDecoder<Protocol, Version>,
343}
344
345impl ResponseHeaderDecoder {
346    /// Create a new decoder.
347    #[inline]
348    pub fn new(options: ResponseHeaderDecoderOptions) -> Self {
349        Self {
350            inner: GenericResponseHeaderDecoder::new(options),
351        }
352    }
353
354    /// Reset the decoder and make it ready for parsing a new response header.
355    #[inline]
356    pub fn reset(&mut self) {
357        self.inner.reset();
358    }
359
360    /// Decode a given response header chunk.
361    pub fn decode(&mut self, data: &mut BytesMut) -> Result<Option<ResponseHeader>, CodecError> {
362        let res = self.inner.decode(data)?.map(ResponseHeader::new);
363
364        Ok(res)
365    }
366
367    /// Decode a given response header chunk at the end of the stream.
368    pub fn decode_eof(
369        &mut self,
370        data: &mut BytesMut,
371    ) -> Result<Option<ResponseHeader>, CodecError> {
372        let res = self.inner.decode_eof(data)?.map(ResponseHeader::new);
373
374        Ok(res)
375    }
376}
377
378impl Decoder for ResponseHeaderDecoder {
379    type Item = ResponseHeader;
380    type Error = CodecError;
381
382    #[inline]
383    fn decode(&mut self, buf: &mut BytesMut) -> Result<Option<Self::Item>, Self::Error> {
384        Self::decode(self, buf)
385    }
386
387    #[inline]
388    fn decode_eof(&mut self, buf: &mut BytesMut) -> Result<Option<Self::Item>, Self::Error> {
389        Self::decode_eof(self, buf)
390    }
391}
392
393/// Response header encoder.
394pub struct ResponseHeaderEncoder {
395    inner: GenericResponseHeaderEncoder,
396}
397
398impl ResponseHeaderEncoder {
399    /// Create a new encoder.
400    #[inline]
401    pub const fn new() -> Self {
402        Self {
403            inner: GenericResponseHeaderEncoder::new(),
404        }
405    }
406
407    /// Encode a given response header into a given buffer.
408    #[inline]
409    pub fn encode(&mut self, header: &ResponseHeader, dst: &mut BytesMut) {
410        self.inner.encode(&header.inner, dst);
411    }
412}
413
414impl Default for ResponseHeaderEncoder {
415    #[inline]
416    fn default() -> Self {
417        Self::new()
418    }
419}
420
421impl Encoder<&ResponseHeader> for ResponseHeaderEncoder {
422    type Error = CodecError;
423
424    #[inline]
425    fn encode(&mut self, header: &ResponseHeader, dst: &mut BytesMut) -> Result<(), Self::Error> {
426        Self::encode(self, header, dst);
427
428        Ok(())
429    }
430}