1use crate::{
2 common::{
3 bnfcore::*,
4 errorparse::SipParseError,
5 nom_wrappers::{from_utf8_nom, take_sws},
6 take_sws_token,
7 traits::NomParser,
8 },
9 headers::{
10 parsers::ExtensionParser,
11 traits::{HeaderValueParserFn, SipHeaderParser},
12 GenericParams, SipRFCHeader, SipUri,
13 },
14};
15use alloc::collections::{BTreeMap, VecDeque};
16use core::str;
17use nom::{bytes::complete::take_while1, character::complete, sequence::tuple};
18use unicase::Ascii;
19
20#[derive(PartialEq, Debug)]
23pub enum HeaderValueType {
24 EmptyValue, TokenValue, Digit, AbsoluteURI, QuotedValue, AuthentificationInfo, CSeq, DateString, Utf8Text, Version, AuthorizationDigest, CallID, CallInfo, NameAddr, Timestamp, RetryAfter, UserAgent, Via, Warning, ExtensionHeader, }
60
61#[derive(PartialEq, Debug, Eq, PartialOrd, Ord)]
62pub enum HeaderTagType {
63 PureValue,
64 AinfoType, AinfoValue, AbsoluteURI, AuthSchema,
69 Username,
70 Domain,
71 Realm,
72 Nonce,
73 DigestUri, Dresponse,
75 Algorithm,
76 Cnonce,
77 Opaque,
78 Stale,
79 QopValue,
80 NonceCount,
81 Number,
83 Method,
84 ID,
85 Host,
86 Port,
87 Star, DisplayName,
89 Seconds,
90 Comment,
91 Major,
92 Minor,
93 TimveVal,
94 Delay,
95
96 ProtocolName,
97 ProtocolVersion,
98 ProtocolTransport,
99
100 WarnCode,
101 WarnAgent,
102 WarnText,
103}
104
105pub type HeaderTags<'a> = BTreeMap<HeaderTagType, &'a [u8]>;
106
107#[derive(PartialEq, Debug)]
108pub struct HeaderValue<'a> {
109 pub vstr: &'a str,
110 pub vtype: HeaderValueType,
111 vtags: Option<HeaderTags<'a>>,
112 sip_uri: Option<SipUri<'a>>,
113}
114
115impl<'a> HeaderValue<'a> {
116 pub fn create_empty_value() -> HeaderValue<'a> {
117 HeaderValue {
118 vstr: "",
119 vtype: HeaderValueType::EmptyValue,
120 vtags: None,
121 sip_uri: None,
122 }
123 }
124
125 pub fn new(
126 val: &'a [u8],
127 vtype: HeaderValueType,
128 vtags: Option<HeaderTags<'a>>,
129 sip_uri: Option<SipUri<'a>>,
130 ) -> nom::IResult<&'a [u8], HeaderValue<'a>, SipParseError<'a>> {
131 let (_, vstr) = from_utf8_nom(val)?;
132
133 Ok((
134 val,
135 HeaderValue {
136 vstr: vstr,
137 vtype: vtype,
138 vtags: vtags,
139 sip_uri: sip_uri,
140 },
141 ))
142 }
143
144 pub fn tags(&self) -> Option<&HeaderTags<'a>> {
145 self.vtags.as_ref()
146 }
147
148 pub fn sip_uri(&self) -> Option<&SipUri<'a>> {
149 self.sip_uri.as_ref()
150 }
151}
152
153#[derive(PartialEq, Debug)]
154pub struct Header<'a> {
156 pub name: Ascii<&'a str>,
158 pub value: HeaderValue<'a>,
160 parameters: Option<GenericParams<'a>>,
162}
163
164impl<'a> Header<'a> {
165 pub fn new(
166 name: &'a str,
167 value: HeaderValue<'a>,
168 parameters: Option<GenericParams<'a>>,
169 ) -> Header<'a> {
170 Header {
171 name: { Ascii::new(name) },
172 value: value,
173 parameters: parameters,
174 }
175 }
176
177 pub fn params(&self) -> Option<&GenericParams<'a>> {
178 self.parameters.as_ref()
179 }
180
181 pub fn find_parser(header_name: &'a str) -> (Option<SipRFCHeader>, HeaderValueParserFn) {
182 match SipRFCHeader::from_str(&header_name) {
183 Some(rfc_header) => (Some(rfc_header), rfc_header.get_parser()),
184 None => (None, ExtensionParser::take_value),
185 }
186 }
187
188 pub fn take_name(input: &'a [u8]) -> nom::IResult<&[u8], &'a str, SipParseError> {
189 let (input_rest, (header_name, _, _, _)) = tuple((
190 take_while1(is_token_char),
191 complete::space0,
192 complete::char(':'),
193 complete::space0,
194 ))(input)?;
195 match str::from_utf8(header_name) {
196 Ok(hdr_str) => Ok((input_rest, hdr_str)),
197 Err(_) => sip_parse_error!(1, "Bad header name"),
198 }
199 }
200
201 pub fn take_value(
203 input: &'a [u8],
204 parser: HeaderValueParserFn,
205 ) -> nom::IResult<&'a [u8], (HeaderValue<'a>, Option<GenericParams<'a>>), SipParseError<'a>>
206 {
207 let (input, _) = take_sws(input)?;
209 if is_crlf(input) {
210 return Ok((input, (HeaderValue::create_empty_value(), None))); }
212
213 let (inp, value) = parser(input)?;
214 let (inp, _) = complete::space0(inp)?;
218 if inp.is_empty() {
219 return sip_parse_error!(1, "Error parse header value");
220 }
221 if inp[0] != b',' && inp[0] != b';' && inp[0] != b' ' && !is_crlf(inp) {
222 return sip_parse_error!(2, "Error parse header value");
223 }
224
225 if inp[0] == b';' {
226 let (inp, params) = Header::try_take_parameters(inp)?;
227 return Ok((inp, (value, params)));
228 }
229 Ok((inp, (value, None)))
230 }
231
232 fn try_take_parameters(
233 input: &'a [u8],
234 ) -> nom::IResult<&'a [u8], Option<GenericParams<'a>>, SipParseError<'a>> {
235 if input.is_empty() || input[0] != b';' {
236 return Ok((input, None));
237 }
238 let (input, parameters) = GenericParams::parse(input)?;
239 Ok((input, Some(parameters)))
240 }
241}
242
243impl<'a> NomParser<'a> for Header<'a> {
244 type ParseResult = (Option<SipRFCHeader>, VecDeque<Header<'a>>);
245 fn parse(input: &'a [u8]) -> nom::IResult<&[u8], Self::ParseResult, SipParseError> {
246 let mut headers = VecDeque::new();
247 let (input, header_name) = Header::take_name(input)?;
248 let (rfc_type, value_parser) = Header::find_parser(header_name);
249 let mut inp = input;
250 loop {
251 let (input, (value, params)) = Header::take_value(inp, value_parser)?;
252 headers.push_back(Header::new(header_name, value, params));
253 if input[0] == b',' {
254 let (input, _) = take_sws_token::comma(input)?;
255 inp = input;
256 continue;
257 }
258 inp = input;
259 break;
260 }
261 Ok((inp, (rfc_type, headers)))
262 }
263}