1#[doc(hidden)]
2pub use tokenizer::Tokenizer;
3
4use crate::{
5 common::{
6 method::{self, Method},
7 uri::{self, Uri},
8 version::{self, Version},
9 },
10 headers::{header, Headers},
11 Error, SipMessage,
12};
13use std::convert::{TryFrom, TryInto};
14
15#[derive(Debug, PartialEq, Eq, Clone)]
28pub struct Request {
29 pub method: Method,
30 pub uri: Uri,
31 pub version: Version,
32 pub headers: Headers,
33 pub body: Vec<u8>,
34}
35
36impl Request {
37 pub fn method(&self) -> &Method {
38 &self.method
39 }
40
41 pub fn uri(&self) -> &Uri {
42 &self.uri
43 }
44
45 pub fn version(&self) -> &Version {
46 &self.version
47 }
48
49 pub fn body(&self) -> &Vec<u8> {
50 &self.body
51 }
52
53 pub fn body_mut(&mut self) -> &mut Vec<u8> {
54 &mut self.body
55 }
56}
57
58impl super::HasHeaders for Request {
59 fn headers(&self) -> &Headers {
60 &self.headers
61 }
62
63 fn headers_mut(&mut self) -> &mut Headers {
64 &mut self.headers
65 }
66}
67
68impl std::fmt::Display for Request {
69 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
70 write!(
71 f,
72 "{} {} {}\r\n{}\r\n{}",
73 self.method,
74 self.uri,
75 self.version,
76 self.headers,
77 String::from_utf8_lossy(&self.body)
78 )
79 }
80}
81
82impl TryFrom<SipMessage> for Request {
83 type Error = crate::Error;
84
85 fn try_from(sip_message: crate::SipMessage) -> Result<Self, Self::Error> {
86 match sip_message {
87 crate::SipMessage::Request(request) => Ok(request),
88 crate::SipMessage::Response(_) => Err(Error::Unexpected(
89 "Can't convert a models::SipMessage::Response into Request !".into(),
90 )),
91 }
92 }
93}
94
95impl TryFrom<&[u8]> for Request {
96 type Error = Error;
97
98 fn try_from(from: &[u8]) -> Result<Self, Self::Error> {
99 Tokenizer::tokenize(from)?.1.try_into()
100 }
101}
102
103impl TryFrom<Vec<u8>> for Request {
104 type Error = Error;
105
106 fn try_from(from: Vec<u8>) -> Result<Self, Self::Error> {
107 Tokenizer::tokenize(&from)?.1.try_into()
108 }
109}
110
111impl TryFrom<&str> for Request {
112 type Error = Error;
113
114 fn try_from(from: &str) -> Result<Self, Self::Error> {
115 Tokenizer::tokenize(from.as_bytes())?.1.try_into()
116 }
117}
118
119impl TryFrom<String> for Request {
120 type Error = Error;
121
122 fn try_from(from: String) -> Result<Self, Self::Error> {
123 Tokenizer::tokenize(from.as_bytes())?.1.try_into()
124 }
125}
126
127impl TryFrom<bytes::Bytes> for Request {
128 type Error = Error;
129
130 fn try_from(from: bytes::Bytes) -> Result<Self, Self::Error> {
131 Tokenizer::tokenize(&from)?.1.try_into()
132 }
133}
134
135impl From<Request> for String {
136 fn from(req: Request) -> Self {
137 req.to_string()
138 }
139}
140
141impl From<Request> for Vec<u8> {
142 fn from(req: Request) -> Self {
143 req.to_string().into_bytes()
144 }
145}
146
147impl From<Request> for bytes::Bytes {
148 fn from(req: Request) -> Self {
149 Self::from(req.to_string())
150 }
151}
152
153#[doc(hidden)]
154pub mod tokenizer {
155 use super::{header, method, uri, version, Request};
156 use crate::{Error, IResult, NomError, TokenizerError};
157 use std::convert::TryInto;
158
159 impl<'a> TryInto<Request> for Tokenizer<'a> {
160 type Error = Error;
161
162 fn try_into(self) -> Result<Request, Error> {
163 Ok(Request {
164 method: self.method.try_into()?,
165 uri: self.uri.try_into()?,
166 version: self.version.try_into()?,
167 headers: self
168 .headers
169 .into_iter()
170 .map(TryInto::try_into)
171 .collect::<Result<Vec<_>, Error>>()?
172 .into(),
173 body: self.body.into(),
174 })
175 }
176 }
177
178 #[derive(Debug, PartialEq, Eq)]
179 pub struct Tokenizer<'a> {
180 pub method: method::Tokenizer<'a, &'a [u8], u8>,
181 pub uri: uri::Tokenizer<'a, &'a [u8], u8>,
182 pub version: version::Tokenizer<'a, &'a [u8], u8>,
183 pub headers: Vec<header::Tokenizer<'a>>,
184 pub body: &'a [u8],
185 }
186
187 impl<'a> Tokenizer<'a> {
188 pub fn tokenize(part: &'a [u8]) -> IResult<Self> {
189 use crate::parser_utils::is_empty_or_fail_with;
190 use nom::{
191 branch::alt,
192 bytes::complete::{tag, take_until},
193 multi::many0,
194 sequence::tuple,
195 };
196
197 let (rem, (method, _, uri, _, version, _)) = tuple((
198 method::Tokenizer::tokenize,
199 tag(" "),
200 uri::Tokenizer::tokenize,
201 tag(" "),
202 version::Tokenizer::tokenize,
203 tag("\r\n"),
204 ))(part)?;
205
206 let (body, (raw_headers, _)) = alt((
207 tuple((take_until("\r\n\r\n"), tag("\r\n\r\n"))),
208 tuple((take_until("\r\n"), tag("\r\n"))),
209 ))(rem)
210 .map_err(|_: NomError<'a>| TokenizerError::from(("headers", rem)).into())?;
211 let (rem, headers) = many0(header::Tokenizer::tokenize)(raw_headers)?;
212 is_empty_or_fail_with(rem, ("headers", rem))?;
213
214 Ok((
215 &[],
216 Self {
217 method,
218 uri,
219 version,
220 headers,
221 body,
222 },
223 ))
224 }
225 }
226}