1use std::borrow::Cow;
12use std::ops::Range;
13
14use bytes::Bytes;
15
16use crate::error::{AddressEditError, HeaderError, WarningEditError};
17use crate::headers::address::{AddressValueSpan, value_spans};
18use crate::headers::grammar::is_token_char;
19use crate::headers::warning::{WarningValueSpan, value_spans as warning_value_spans};
20use crate::name::HeaderName;
21use crate::uri::Uri;
22
23#[derive(Debug, Clone, PartialEq, Eq, Hash)]
30pub enum Method {
31 Invite,
33 Ack,
35 Bye,
37 Cancel,
39 Register,
41 Options,
43 Info,
45 Prack,
47 Update,
49 Subscribe,
51 Notify,
53 Refer,
55 Message,
57 Publish,
59 Other(Bytes),
61}
62
63impl Method {
64 #[must_use]
66 pub fn parse(raw: &Bytes) -> Self {
67 match raw.as_ref() {
68 b"INVITE" => Self::Invite,
69 b"ACK" => Self::Ack,
70 b"BYE" => Self::Bye,
71 b"CANCEL" => Self::Cancel,
72 b"REGISTER" => Self::Register,
73 b"OPTIONS" => Self::Options,
74 b"INFO" => Self::Info,
75 b"PRACK" => Self::Prack,
76 b"UPDATE" => Self::Update,
77 b"SUBSCRIBE" => Self::Subscribe,
78 b"NOTIFY" => Self::Notify,
79 b"REFER" => Self::Refer,
80 b"MESSAGE" => Self::Message,
81 b"PUBLISH" => Self::Publish,
82 _ => Self::Other(raw.clone()),
83 }
84 }
85
86 #[must_use]
88 pub fn as_bytes(&self) -> &[u8] {
89 match self {
90 Self::Invite => b"INVITE",
91 Self::Ack => b"ACK",
92 Self::Bye => b"BYE",
93 Self::Cancel => b"CANCEL",
94 Self::Register => b"REGISTER",
95 Self::Options => b"OPTIONS",
96 Self::Info => b"INFO",
97 Self::Prack => b"PRACK",
98 Self::Update => b"UPDATE",
99 Self::Subscribe => b"SUBSCRIBE",
100 Self::Notify => b"NOTIFY",
101 Self::Refer => b"REFER",
102 Self::Message => b"MESSAGE",
103 Self::Publish => b"PUBLISH",
104 Self::Other(raw) => raw,
105 }
106 }
107}
108
109impl std::fmt::Display for Method {
110 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
111 write!(f, "{}", String::from_utf8_lossy(self.as_bytes()))
112 }
113}
114
115#[derive(Debug, Clone, PartialEq, Eq)]
117pub enum Version {
118 Sip20,
120 Other(Bytes),
123}
124
125impl Version {
126 #[must_use]
127 pub(crate) fn parse(raw: &Bytes) -> Self {
128 if raw.eq_ignore_ascii_case(b"SIP/2.0") {
131 Self::Sip20
132 } else {
133 Self::Other(raw.clone())
134 }
135 }
136
137 #[must_use]
139 pub fn as_bytes(&self) -> &[u8] {
140 match self {
141 Self::Sip20 => b"SIP/2.0",
142 Self::Other(raw) => raw,
143 }
144 }
145
146 #[must_use]
148 pub fn is_supported(&self) -> bool {
149 matches!(self, Self::Sip20)
150 }
151}
152
153#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
155pub struct StatusCode(u16);
156
157impl StatusCode {
158 #[must_use]
160 pub fn new(code: u16) -> Option<Self> {
161 (100..=699).contains(&code).then_some(Self(code))
162 }
163
164 #[must_use]
166 pub fn code(self) -> u16 {
167 self.0
168 }
169
170 #[must_use]
172 pub fn class(self) -> u16 {
173 self.0 / 100
174 }
175
176 #[must_use]
178 pub fn is_provisional(self) -> bool {
179 self.class() == 1
180 }
181
182 #[must_use]
184 pub fn is_final(self) -> bool {
185 !self.is_provisional()
186 }
187
188 #[must_use]
190 pub fn is_success(self) -> bool {
191 self.class() == 2
192 }
193}
194
195impl std::fmt::Display for StatusCode {
196 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
197 write!(f, "{}", self.0)
198 }
199}
200
201#[derive(Debug, Clone)]
203pub struct Header {
204 name: HeaderName,
205 repr: HeaderRepr,
206}
207
208#[derive(Debug, Clone)]
209enum HeaderRepr {
210 Wire { line: Bytes, value_offset: usize },
214 Built { value: Bytes },
216}
217
218#[derive(Debug)]
219struct AddressLayout {
220 spans: Vec<AddressValueSpan>,
221 source_map: Vec<Range<usize>>,
222 raw_len: usize,
223}
224
225#[derive(Debug)]
226struct WarningLayout {
227 spans: Vec<WarningValueSpan>,
228 source_map: Vec<Range<usize>>,
229 raw_len: usize,
230}
231
232impl Header {
233 #[must_use]
239 pub(crate) fn new_unchecked(name: HeaderName, value: impl Into<Bytes>) -> Self {
240 Self {
241 name,
242 repr: HeaderRepr::Built {
243 value: value.into(),
244 },
245 }
246 }
247
248 pub(crate) fn from_wire(name: HeaderName, line: Bytes, value_offset: usize) -> Self {
249 Self {
250 name,
251 repr: HeaderRepr::Wire { line, value_offset },
252 }
253 }
254
255 #[must_use]
257 pub fn name(&self) -> &HeaderName {
258 &self.name
259 }
260
261 #[must_use]
263 pub fn raw_value(&self) -> &[u8] {
264 match &self.repr {
265 HeaderRepr::Wire { line, value_offset } => line.get(*value_offset..).unwrap_or(&[]),
266 HeaderRepr::Built { value } => value,
267 }
268 }
269
270 #[must_use]
275 pub fn value(&self) -> Cow<'_, [u8]> {
276 let raw = self.raw_value();
277 if raw.iter().any(|&b| b == b'\r' || b == b'\n') {
278 let mut out = Vec::with_capacity(raw.len());
279 let mut i = 0;
280 while let Some(&b) = raw.get(i) {
281 if b == b'\r' && raw.get(i + 1) == Some(&b'\n') {
282 let mut j = i + 2;
284 while matches!(raw.get(j), Some(b' ' | b'\t')) {
285 j += 1;
286 }
287 out.push(b' ');
288 i = j;
289 } else {
290 out.push(b);
291 i += 1;
292 }
293 }
294 Cow::Owned(trim(&out).to_vec())
295 } else {
296 Cow::Borrowed(trim(raw))
297 }
298 }
299
300 pub fn address_value_count(&self) -> Result<usize, AddressEditError> {
305 self.address_layout().map(|layout| layout.spans.len())
306 }
307
308 pub fn replace_address_uri(
314 &mut self,
315 value_index: usize,
316 uri: &Uri,
317 ) -> Result<(), AddressEditError> {
318 let encoded = validate_replacement_uri(uri)?;
319 let layout = self.address_layout()?;
320 let span = layout
321 .spans
322 .get(value_index)
323 .ok_or(AddressEditError::IndexOutOfRange { index: value_index })?;
324 let raw_span =
325 project_range(&layout, &span.uri).ok_or_else(|| malformed_address(self.name()))?;
326 let rewritten = self
327 .with_value_span_replaced(&raw_span, &encoded)
328 .ok_or_else(|| malformed_address(self.name()))?;
329 let candidate = rewritten.address_layout()?;
330 if candidate.spans.len() != layout.spans.len() {
331 return Err(malformed_address(self.name()));
332 }
333 let candidate_span = candidate
334 .spans
335 .get(value_index)
336 .ok_or_else(|| malformed_address(self.name()))?;
337 let candidate_raw_span = project_range(&candidate, &candidate_span.uri)
338 .ok_or_else(|| malformed_address(self.name()))?;
339 if rewritten.raw_value().get(candidate_raw_span) != Some(encoded.as_ref()) {
340 return Err(malformed_address(self.name()));
341 }
342 *self = rewritten;
343 Ok(())
344 }
345
346 pub fn replace_address_presentation(
352 &mut self,
353 value_index: usize,
354 display_name: Option<&str>,
355 uri: &Uri,
356 ) -> Result<(), AddressEditError> {
357 let encoded = encode_address_presentation(display_name, uri)?;
358 let layout = self.address_layout()?;
359 let span = layout
360 .spans
361 .get(value_index)
362 .ok_or(AddressEditError::IndexOutOfRange { index: value_index })?;
363 let raw_span = project_range(&layout, &span.presentation)
364 .ok_or_else(|| malformed_address(self.name()))?;
365 let rewritten = self
366 .with_value_span_replaced(&raw_span, &encoded)
367 .ok_or_else(|| malformed_address(self.name()))?;
368 let candidate = rewritten.address_layout()?;
369 if candidate.spans.len() != layout.spans.len() {
370 return Err(malformed_address(self.name()));
371 }
372 let candidate_span = candidate
373 .spans
374 .get(value_index)
375 .ok_or_else(|| malformed_address(self.name()))?;
376 let candidate_raw_span = project_range(&candidate, &candidate_span.presentation)
377 .ok_or_else(|| malformed_address(self.name()))?;
378 if rewritten.raw_value().get(candidate_raw_span) != Some(encoded.as_ref()) {
379 return Err(malformed_address(self.name()));
380 }
381 *self = rewritten;
382 Ok(())
383 }
384
385 pub fn warning_value_count(&self) -> Result<usize, WarningEditError> {
390 self.warning_layout().map(|layout| layout.spans.len())
391 }
392
393 pub fn replace_warning_agent_with_pseudonym(
398 &mut self,
399 value_index: usize,
400 pseudonym: &[u8],
401 ) -> Result<(), WarningEditError> {
402 validate_warning_pseudonym(pseudonym)?;
403 let layout = self.warning_layout()?;
404 let span = layout
405 .spans
406 .get(value_index)
407 .ok_or(WarningEditError::IndexOutOfRange { index: value_index })?;
408 let raw_span = project_source_range(&layout.source_map, layout.raw_len, &span.agent)
409 .ok_or_else(malformed_warning)?;
410 let rewritten = self
411 .with_value_span_replaced(&raw_span, pseudonym)
412 .ok_or_else(malformed_warning)?;
413 let candidate = rewritten.warning_layout()?;
414 if candidate.spans.len() != layout.spans.len() {
415 return Err(malformed_warning());
416 }
417 let candidate_span = candidate
418 .spans
419 .get(value_index)
420 .ok_or_else(malformed_warning)?;
421 let candidate_raw_span = project_source_range(
422 &candidate.source_map,
423 candidate.raw_len,
424 &candidate_span.agent,
425 )
426 .ok_or_else(malformed_warning)?;
427 if rewritten.raw_value().get(candidate_raw_span) != Some(pseudonym) {
428 return Err(malformed_warning());
429 }
430 *self = rewritten;
431 Ok(())
432 }
433
434 pub fn without_address_value(
440 &self,
441 value_index: usize,
442 ) -> Result<Option<Self>, AddressEditError> {
443 let layout = self.address_layout()?;
444 let selected = layout
445 .spans
446 .get(value_index)
447 .ok_or(AddressEditError::IndexOutOfRange { index: value_index })?;
448 if layout.spans.len() == 1 {
449 return Ok(None);
450 }
451
452 let unfolded = if let Some(next) = layout.spans.get(value_index.saturating_add(1)) {
453 selected.item.start..next.item.start
454 } else {
455 let previous = value_index
456 .checked_sub(1)
457 .and_then(|index| layout.spans.get(index))
458 .ok_or_else(|| malformed_address(self.name()))?;
459 previous.part.end..selected.item.end
460 };
461 let raw_span =
462 project_range(&layout, &unfolded).ok_or_else(|| malformed_address(self.name()))?;
463 self.with_value_span_replaced(&raw_span, &[])
464 .map(Some)
465 .ok_or_else(|| malformed_address(self.name()))
466 }
467
468 fn address_layout(&self) -> Result<AddressLayout, AddressEditError> {
469 let (header, list) = address_grammar(self.name())?;
470 let raw = self.raw_value();
471 let (unfolded, source_map) = unfold_with_source_map(raw);
472 let spans = value_spans(&unfolded, header, list).map_err(AddressEditError::Malformed)?;
473 Ok(AddressLayout {
474 spans,
475 source_map,
476 raw_len: raw.len(),
477 })
478 }
479
480 fn warning_layout(&self) -> Result<WarningLayout, WarningEditError> {
481 if self.name() != &HeaderName::Warning {
482 return Err(malformed_warning());
483 }
484 let raw = self.raw_value();
485 let (unfolded, source_map) = unfold_with_source_map(raw);
486 let spans = warning_value_spans(&unfolded).map_err(WarningEditError::Malformed)?;
487 Ok(WarningLayout {
488 spans,
489 source_map,
490 raw_len: raw.len(),
491 })
492 }
493
494 fn with_value_span_replaced(&self, span: &Range<usize>, replacement: &[u8]) -> Option<Self> {
495 let repr = match &self.repr {
496 HeaderRepr::Wire { line, value_offset } => {
497 let start = value_offset.checked_add(span.start)?;
498 let end = value_offset.checked_add(span.end)?;
499 HeaderRepr::Wire {
500 line: replace_byte_span(line, &(start..end), replacement)?,
501 value_offset: *value_offset,
502 }
503 }
504 HeaderRepr::Built { value } => HeaderRepr::Built {
505 value: replace_byte_span(value, span, replacement)?,
506 },
507 };
508 Some(Self {
509 name: self.name.clone(),
510 repr,
511 })
512 }
513
514 pub fn write_to(&self, out: &mut Vec<u8>) {
516 match &self.repr {
517 HeaderRepr::Wire { line, .. } => out.extend_from_slice(line),
518 HeaderRepr::Built { value } => {
519 out.extend_from_slice(self.name.canonical());
520 out.extend_from_slice(b": ");
521 out.extend_from_slice(value);
522 }
523 }
524 }
525}
526
527fn trim(mut b: &[u8]) -> &[u8] {
528 while let Some((first, rest)) = b.split_first() {
529 if matches!(first, b' ' | b'\t') {
530 b = rest;
531 } else {
532 break;
533 }
534 }
535 while let Some((last, rest)) = b.split_last() {
536 if matches!(last, b' ' | b'\t') {
537 b = rest;
538 } else {
539 break;
540 }
541 }
542 b
543}
544
545#[derive(Debug, Clone, Default)]
550pub struct Headers {
551 entries: Vec<Header>,
552}
553
554impl Headers {
555 #[must_use]
557 pub fn new() -> Self {
558 Self::default()
559 }
560
561 #[must_use]
563 pub fn len(&self) -> usize {
564 self.entries.len()
565 }
566
567 #[must_use]
569 pub fn is_empty(&self) -> bool {
570 self.entries.is_empty()
571 }
572
573 pub fn push(&mut self, header: Header) {
575 self.entries.push(header);
576 }
577
578 pub fn push_front(&mut self, header: Header) {
580 self.entries.insert(0, header);
581 }
582
583 pub fn iter(&self) -> impl Iterator<Item = &Header> {
585 self.entries.iter()
586 }
587
588 #[must_use]
590 pub fn get(&self, name: &HeaderName) -> Option<&Header> {
591 self.entries.iter().find(|h| h.name() == name)
592 }
593
594 pub fn get_all<'a>(&'a self, name: &'a HeaderName) -> impl Iterator<Item = &'a Header> {
596 self.entries.iter().filter(move |h| h.name() == name)
597 }
598
599 #[must_use]
601 pub fn count(&self, name: &HeaderName) -> usize {
602 self.entries.iter().filter(|h| h.name() == name).count()
603 }
604
605 pub fn remove_all(&mut self, name: &HeaderName) -> usize {
607 let before = self.entries.len();
608 self.entries.retain(|h| h.name() != name);
609 before - self.entries.len()
610 }
611
612 pub fn remove_first(&mut self, name: &HeaderName) -> Option<Header> {
620 let index = self.entries.iter().position(|h| h.name() == name)?;
621 Some(self.entries.remove(index))
622 }
623
624 pub fn insert(&mut self, index: usize, header: Header) {
631 let index = index.min(self.entries.len());
632 self.entries.insert(index, header);
633 }
634
635 pub fn retain(&mut self, f: impl FnMut(&Header) -> bool) {
641 self.entries.retain(f);
642 }
643
644 pub fn replace_address_uri(
649 &mut self,
650 name: &HeaderName,
651 value_index: usize,
652 uri: &Uri,
653 ) -> Result<(), AddressEditError> {
654 address_grammar(name)?;
655 validate_replacement_uri(uri)?;
656 let rows = self.address_rows(name)?;
657 let (entry_index, row_index) = locate_address_value(&rows, value_index)?;
658 let header = self
659 .entries
660 .get_mut(entry_index)
661 .ok_or(AddressEditError::IndexOutOfRange { index: value_index })?;
662 header.replace_address_uri(row_index, uri)
663 }
664
665 pub fn replace_address_presentation(
670 &mut self,
671 name: &HeaderName,
672 value_index: usize,
673 display_name: Option<&str>,
674 uri: &Uri,
675 ) -> Result<(), AddressEditError> {
676 address_grammar(name)?;
677 encode_address_presentation(display_name, uri)?;
678 let rows = self.address_rows(name)?;
679 let (entry_index, row_index) = locate_address_value(&rows, value_index)?;
680 let header = self
681 .entries
682 .get_mut(entry_index)
683 .ok_or(AddressEditError::IndexOutOfRange { index: value_index })?;
684 header.replace_address_presentation(row_index, display_name, uri)
685 }
686
687 pub fn replace_warning_agent_with_pseudonym(
692 &mut self,
693 value_index: usize,
694 pseudonym: &[u8],
695 ) -> Result<(), WarningEditError> {
696 validate_warning_pseudonym(pseudonym)?;
697 let rows = self.warning_rows()?;
698 let (entry_index, row_index) = locate_flattened_value(&rows, value_index)
699 .map_err(|()| WarningEditError::IndexOutOfRange { index: value_index })?;
700 let header = self
701 .entries
702 .get_mut(entry_index)
703 .ok_or(WarningEditError::IndexOutOfRange { index: value_index })?;
704 header.replace_warning_agent_with_pseudonym(row_index, pseudonym)
705 }
706
707 pub fn remove_address_value(
712 &mut self,
713 name: &HeaderName,
714 value_index: usize,
715 ) -> Result<(), AddressEditError> {
716 address_grammar(name)?;
717 let rows = self.address_rows(name)?;
718 let (entry_index, row_index) = locate_address_value(&rows, value_index)?;
719 let replacement = self
720 .entries
721 .get(entry_index)
722 .ok_or(AddressEditError::IndexOutOfRange { index: value_index })?
723 .without_address_value(row_index)?;
724 if let Some(header) = replacement {
725 let slot = self
726 .entries
727 .get_mut(entry_index)
728 .ok_or(AddressEditError::IndexOutOfRange { index: value_index })?;
729 *slot = header;
730 } else {
731 self.entries.remove(entry_index);
732 }
733 Ok(())
734 }
735
736 fn address_rows(&self, name: &HeaderName) -> Result<Vec<(usize, usize)>, AddressEditError> {
737 self.entries
738 .iter()
739 .enumerate()
740 .filter(|(_, header)| header.name() == name)
741 .map(|(index, header)| header.address_value_count().map(|count| (index, count)))
742 .collect()
743 }
744
745 fn warning_rows(&self) -> Result<Vec<(usize, usize)>, WarningEditError> {
746 self.entries
747 .iter()
748 .enumerate()
749 .filter(|(_, header)| header.name() == &HeaderName::Warning)
750 .map(|(index, header)| header.warning_value_count().map(|count| (index, count)))
751 .collect()
752 }
753
754 #[must_use]
756 pub fn value(&self, name: &HeaderName) -> Option<Cow<'_, [u8]>> {
757 self.get(name).map(Header::value)
758 }
759
760 pub fn write_to(&self, out: &mut Vec<u8>) {
762 for h in &self.entries {
763 h.write_to(out);
764 out.extend_from_slice(b"\r\n");
765 }
766 }
767}
768
769fn address_grammar(name: &HeaderName) -> Result<(&'static str, bool), AddressEditError> {
770 match name {
771 HeaderName::From => Ok(("From", false)),
772 HeaderName::To => Ok(("To", false)),
773 HeaderName::Contact => Ok(("Contact", true)),
774 HeaderName::Route => Ok(("Route", true)),
775 HeaderName::RecordRoute => Ok(("Record-Route", true)),
776 HeaderName::Path => Ok(("Path", true)),
777 HeaderName::ServiceRoute => Ok(("Service-Route", true)),
778 HeaderName::PAssertedIdentity => Ok(("P-Asserted-Identity", true)),
779 HeaderName::PPreferredIdentity => Ok(("P-Preferred-Identity", true)),
780 _ => Err(AddressEditError::UnsupportedHeader),
781 }
782}
783
784fn malformed_address(name: &HeaderName) -> AddressEditError {
785 let header = address_grammar(name).map_or("address", |(header, _)| header);
786 AddressEditError::Malformed(HeaderError::Syntax { header })
787}
788
789fn malformed_warning() -> WarningEditError {
790 WarningEditError::Malformed(HeaderError::Syntax { header: "Warning" })
791}
792
793fn validate_warning_pseudonym(pseudonym: &[u8]) -> Result<(), WarningEditError> {
794 if pseudonym.is_empty() || !pseudonym.iter().copied().all(is_token_char) {
795 return Err(WarningEditError::InvalidPseudonym);
796 }
797 Ok(())
798}
799
800fn validate_replacement_uri(uri: &Uri) -> Result<Bytes, AddressEditError> {
801 let encoded = uri.to_bytes();
802 Uri::parse(encoded.clone()).map_err(AddressEditError::InvalidUri)?;
803 Ok(encoded)
804}
805
806fn encode_address_presentation(
807 display_name: Option<&str>,
808 uri: &Uri,
809) -> Result<Bytes, AddressEditError> {
810 let uri = validate_replacement_uri(uri)?;
811 let mut encoded = Vec::new();
812 if let Some(display_name) = display_name {
813 if display_name
814 .as_bytes()
815 .iter()
816 .any(|byte| *byte < 0x20 || *byte == 0x7f)
817 {
818 return Err(AddressEditError::InvalidDisplayName);
819 }
820 encoded.push(b'"');
821 for byte in display_name.as_bytes() {
822 if matches!(byte, b'"' | b'\\') {
823 encoded.push(b'\\');
824 }
825 encoded.push(*byte);
826 }
827 encoded.extend_from_slice(b"\" ");
828 }
829 encoded.push(b'<');
830 encoded.extend_from_slice(&uri);
831 encoded.push(b'>');
832 Ok(Bytes::from(encoded))
833}
834
835fn locate_address_value(
836 rows: &[(usize, usize)],
837 value_index: usize,
838) -> Result<(usize, usize), AddressEditError> {
839 locate_flattened_value(rows, value_index)
840 .map_err(|()| AddressEditError::IndexOutOfRange { index: value_index })
841}
842
843fn locate_flattened_value(
844 rows: &[(usize, usize)],
845 value_index: usize,
846) -> Result<(usize, usize), ()> {
847 let mut first = 0usize;
848 for &(entry_index, count) in rows {
849 let end = first.checked_add(count).ok_or(())?;
850 if value_index < end {
851 return Ok((entry_index, value_index - first));
852 }
853 first = end;
854 }
855 Err(())
856}
857
858fn unfold_with_source_map(raw: &[u8]) -> (Vec<u8>, Vec<Range<usize>>) {
859 let mut unfolded = Vec::with_capacity(raw.len());
860 let mut source_map = Vec::with_capacity(raw.len());
861 let mut i = 0usize;
862 while let Some(&byte) = raw.get(i) {
863 if byte == b'\r'
864 && raw.get(i + 1) == Some(&b'\n')
865 && matches!(raw.get(i + 2), Some(b' ' | b'\t'))
866 {
867 let mut end = i + 2;
868 while matches!(raw.get(end), Some(b' ' | b'\t')) {
869 end += 1;
870 }
871 unfolded.push(b' ');
872 source_map.push(i..end);
873 i = end;
874 } else {
875 unfolded.push(byte);
876 source_map.push(i..i + 1);
877 i += 1;
878 }
879 }
880 (unfolded, source_map)
881}
882
883fn project_range(layout: &AddressLayout, span: &Range<usize>) -> Option<Range<usize>> {
884 project_source_range(&layout.source_map, layout.raw_len, span)
885}
886
887fn project_source_range(
888 source_map: &[Range<usize>],
889 raw_len: usize,
890 span: &Range<usize>,
891) -> Option<Range<usize>> {
892 if span.start > span.end || span.end > source_map.len() {
893 return None;
894 }
895 let start = source_boundary(source_map, raw_len, span.start)?;
896 let end = source_boundary(source_map, raw_len, span.end)?;
897 (start <= end).then_some(start..end)
898}
899
900fn source_boundary(source_map: &[Range<usize>], raw_len: usize, position: usize) -> Option<usize> {
901 if position == source_map.len() {
902 Some(raw_len)
903 } else {
904 source_map.get(position).map(|source| source.start)
905 }
906}
907
908#[derive(Debug, Clone)]
910pub struct Request {
911 pub method: Method,
913 pub uri: Uri,
918 pub version: Version,
920 pub headers: Headers,
922 body: Bytes,
923 raw_start_line: Option<Bytes>,
924 raw_uri_span: Option<Range<usize>>,
925}
926
927#[derive(Debug, Clone)]
929pub struct Response {
930 pub version: Version,
932 pub status: StatusCode,
934 pub reason: Bytes,
936 pub headers: Headers,
938 body: Bytes,
939 raw_start_line: Option<Bytes>,
940}
941
942#[derive(Debug, Clone)]
944pub enum Message {
945 Request(Request),
947 Response(Response),
949}
950
951impl Request {
952 pub(crate) fn from_wire(
953 method: Method,
954 uri: Uri,
955 version: Version,
956 raw_start_line: Bytes,
957 raw_uri_span: Range<usize>,
958 headers: Headers,
959 body: Bytes,
960 ) -> Self {
961 Self {
962 method,
963 uri,
964 version,
965 headers,
966 body,
967 raw_start_line: Some(raw_start_line),
968 raw_uri_span: Some(raw_uri_span),
969 }
970 }
971
972 pub fn set_uri(&mut self, uri: Uri) -> Result<(), crate::error::UriError> {
980 let encoded = uri.to_bytes();
981 Uri::parse(encoded.clone())?;
982
983 let rewritten = match (&self.raw_start_line, &self.raw_uri_span) {
984 (Some(raw), Some(span)) => Some(
985 replace_byte_span(raw, span, &encoded)
986 .ok_or(crate::error::UriError::RetainedSpan)?,
987 ),
988 (None, None) => None,
989 _ => return Err(crate::error::UriError::RetainedSpan),
990 };
991
992 if let Some(raw) = rewritten {
993 let start = self
994 .raw_uri_span
995 .as_ref()
996 .map(|span| span.start)
997 .ok_or(crate::error::UriError::RetainedSpan)?;
998 let end = start
999 .checked_add(encoded.len())
1000 .ok_or(crate::error::UriError::RetainedSpan)?;
1001 self.raw_start_line = Some(raw);
1002 self.raw_uri_span = Some(start..end);
1003 } else {
1004 self.raw_start_line = None;
1005 self.raw_uri_span = None;
1006 }
1007 self.uri = uri;
1008 Ok(())
1009 }
1010
1011 #[must_use]
1013 pub fn new(method: Method, uri: Uri) -> Self {
1014 Self {
1015 method,
1016 uri,
1017 version: Version::Sip20,
1018 headers: Headers::new(),
1019 body: Bytes::new(),
1020 raw_start_line: None,
1021 raw_uri_span: None,
1022 }
1023 }
1024
1025 #[must_use]
1027 pub fn body(&self) -> &Bytes {
1028 &self.body
1029 }
1030
1031 pub fn set_body(&mut self, body: Bytes) {
1033 self.body = body;
1034 }
1035
1036 pub fn write_to(&self, out: &mut Vec<u8>) {
1038 if let Some(raw) = &self.raw_start_line {
1039 out.extend_from_slice(raw);
1040 } else {
1041 out.extend_from_slice(self.method.as_bytes());
1042 out.push(b' ');
1043 self.uri.write_to(out);
1044 out.push(b' ');
1045 out.extend_from_slice(self.version.as_bytes());
1046 }
1047 out.extend_from_slice(b"\r\n");
1048 self.headers.write_to(out);
1049 out.extend_from_slice(b"\r\n");
1050 out.extend_from_slice(&self.body);
1051 }
1052}
1053
1054fn replace_byte_span(source: &Bytes, span: &Range<usize>, replacement: &[u8]) -> Option<Bytes> {
1055 let prefix = source.get(..span.start)?;
1056 let suffix = source.get(span.end..)?;
1057 let capacity = prefix
1058 .len()
1059 .checked_add(replacement.len())?
1060 .checked_add(suffix.len())?;
1061 let mut out = Vec::with_capacity(capacity);
1062 out.extend_from_slice(prefix);
1063 out.extend_from_slice(replacement);
1064 out.extend_from_slice(suffix);
1065 Some(Bytes::from(out))
1066}
1067
1068impl Response {
1069 pub(crate) fn from_wire(
1070 version: Version,
1071 status: StatusCode,
1072 reason: Bytes,
1073 raw_start_line: Bytes,
1074 headers: Headers,
1075 body: Bytes,
1076 ) -> Self {
1077 Self {
1078 version,
1079 status,
1080 reason,
1081 headers,
1082 body,
1083 raw_start_line: Some(raw_start_line),
1084 }
1085 }
1086
1087 #[must_use]
1089 pub fn new(status: StatusCode, reason: impl Into<Bytes>) -> Self {
1090 Self {
1091 version: Version::Sip20,
1092 status,
1093 reason: reason.into(),
1094 headers: Headers::new(),
1095 body: Bytes::new(),
1096 raw_start_line: None,
1097 }
1098 }
1099
1100 #[must_use]
1102 pub fn body(&self) -> &Bytes {
1103 &self.body
1104 }
1105
1106 pub fn set_body(&mut self, body: Bytes) {
1108 self.body = body;
1109 }
1110
1111 pub fn write_to(&self, out: &mut Vec<u8>) {
1113 if let Some(raw) = &self.raw_start_line {
1114 out.extend_from_slice(raw);
1115 } else {
1116 out.extend_from_slice(self.version.as_bytes());
1117 out.push(b' ');
1118 out.extend_from_slice(self.status.to_string().as_bytes());
1119 out.push(b' ');
1120 out.extend_from_slice(&self.reason);
1121 }
1122 out.extend_from_slice(b"\r\n");
1123 self.headers.write_to(out);
1124 out.extend_from_slice(b"\r\n");
1125 out.extend_from_slice(&self.body);
1126 }
1127}
1128
1129impl Message {
1130 #[must_use]
1132 pub fn headers(&self) -> &Headers {
1133 match self {
1134 Self::Request(r) => &r.headers,
1135 Self::Response(r) => &r.headers,
1136 }
1137 }
1138
1139 pub fn headers_mut(&mut self) -> &mut Headers {
1141 match self {
1142 Self::Request(r) => &mut r.headers,
1143 Self::Response(r) => &mut r.headers,
1144 }
1145 }
1146
1147 #[must_use]
1149 pub fn body(&self) -> &Bytes {
1150 match self {
1151 Self::Request(r) => r.body(),
1152 Self::Response(r) => r.body(),
1153 }
1154 }
1155
1156 #[must_use]
1158 pub fn as_request(&self) -> Option<&Request> {
1159 match self {
1160 Self::Request(r) => Some(r),
1161 Self::Response(_) => None,
1162 }
1163 }
1164
1165 #[must_use]
1167 pub fn as_response(&self) -> Option<&Response> {
1168 match self {
1169 Self::Response(r) => Some(r),
1170 Self::Request(_) => None,
1171 }
1172 }
1173
1174 pub fn write_to(&self, out: &mut Vec<u8>) {
1176 match self {
1177 Self::Request(r) => r.write_to(out),
1178 Self::Response(r) => r.write_to(out),
1179 }
1180 }
1181
1182 #[must_use]
1186 pub fn to_bytes(&self) -> Bytes {
1187 let mut out = Vec::new();
1188 self.write_to(&mut out);
1189 Bytes::from(out)
1190 }
1191}
1192
1193pub trait TypedHeader: Sized {
1195 const NAME: HeaderName;
1197
1198 const VALIDATE_LIST: bool = false;
1203
1204 fn decode(value: &[u8]) -> Result<Self, HeaderError>;
1206
1207 fn decode_list(value: &[u8]) -> Result<Vec<Self>, HeaderError> {
1213 Self::decode(value).map(|one| vec![one])
1214 }
1215
1216 fn validate_list(_values: &[&Self]) -> Result<(), HeaderError> {
1223 Ok(())
1224 }
1225}
1226
1227struct TypedAll<'a, H: TypedHeader> {
1228 entries: std::slice::Iter<'a, Header>,
1229 row: std::vec::IntoIter<H>,
1230 validated: Option<std::vec::IntoIter<Result<H, HeaderError>>>,
1231}
1232
1233impl<'a, H: TypedHeader> TypedAll<'a, H> {
1234 fn new(headers: &'a Headers) -> Self {
1235 let validated = H::VALIDATE_LIST.then(|| {
1236 let mut decoded: Vec<Result<H, HeaderError>> = headers
1237 .entries
1238 .iter()
1239 .filter(|header| header.name() == &H::NAME)
1240 .flat_map(|header| match H::decode_list(&header.value()) {
1241 Ok(values) => values.into_iter().map(Ok).collect::<Vec<_>>(),
1242 Err(error) => vec![Err(error)],
1243 })
1244 .collect();
1245
1246 let decode_error = decoded.iter().find_map(|result| match result {
1251 Ok(_) => None,
1252 Err(error) => Some(error.clone()),
1253 });
1254 if let Some(error) = decode_error {
1255 decoded = vec![Err(error)];
1256 } else if !decoded.is_empty() {
1257 let values: Vec<&H> = decoded
1258 .iter()
1259 .filter_map(|result| result.as_ref().ok())
1260 .collect();
1261 if let Err(error) = H::validate_list(&values) {
1262 decoded = vec![Err(error)];
1263 }
1264 }
1265 decoded.into_iter()
1266 });
1267
1268 Self {
1269 entries: headers.entries.iter(),
1270 row: Vec::new().into_iter(),
1271 validated,
1272 }
1273 }
1274}
1275
1276impl<H: TypedHeader> Iterator for TypedAll<'_, H> {
1277 type Item = Result<H, HeaderError>;
1278
1279 fn next(&mut self) -> Option<Self::Item> {
1280 if let Some(validated) = &mut self.validated {
1281 return validated.next();
1282 }
1283
1284 loop {
1285 if let Some(value) = self.row.next() {
1286 return Some(Ok(value));
1287 }
1288 let header = self.entries.find(|header| header.name() == &H::NAME)?;
1289 match H::decode_list(&header.value()) {
1290 Ok(values) => self.row = values.into_iter(),
1291 Err(error) => return Some(Err(error)),
1292 }
1293 }
1294 }
1295}
1296
1297impl Headers {
1298 #[must_use]
1304 pub fn typed<H: TypedHeader>(&self) -> Option<Result<H, HeaderError>> {
1305 self.get(&H::NAME).map(|h| H::decode(&h.value()))
1306 }
1307
1308 pub fn typed_all<'a, H: TypedHeader + 'a>(
1312 &'a self,
1313 ) -> impl Iterator<Item = Result<H, HeaderError>> + 'a {
1314 TypedAll::new(self)
1315 }
1316}
1317
1318#[cfg(test)]
1319#[allow(
1320 clippy::unwrap_used,
1321 clippy::expect_used,
1322 clippy::panic,
1323 clippy::indexing_slicing
1324)]
1325mod tests {
1326 use super::*;
1327
1328 #[test]
1329 fn unfolding_collapses_continuations_to_a_single_space() {
1330 let line = Bytes::from_static(b"Subject: one\r\n two\r\n\tthree");
1331 let h = Header::from_wire(HeaderName::Subject, line, 9);
1332 assert_eq!(h.value().as_ref(), b"one two three");
1333 assert_eq!(h.raw_value(), b"one\r\n two\r\n\tthree");
1335 }
1336
1337 #[test]
1338 fn unfolded_value_borrows_when_there_is_no_folding() {
1339 let line = Bytes::from_static(b"Subject: plain");
1340 let h = Header::from_wire(HeaderName::Subject, line, 9);
1341 assert!(matches!(h.value(), Cow::Borrowed(_)));
1342 }
1343
1344 #[test]
1345 fn status_code_range_is_enforced() {
1346 assert!(StatusCode::new(99).is_none());
1347 assert!(StatusCode::new(700).is_none());
1348 assert_eq!(StatusCode::new(200).map(StatusCode::code), Some(200));
1349 assert!(StatusCode::new(180).unwrap().is_provisional());
1350 assert!(StatusCode::new(200).unwrap().is_success());
1351 assert!(StatusCode::new(486).unwrap().is_final());
1352 }
1353
1354 #[test]
1355 fn methods_compare_case_sensitively() {
1356 assert_ne!(
1359 Method::parse(&Bytes::from_static(b"Invite")),
1360 Method::Invite
1361 );
1362 assert_eq!(
1363 Method::parse(&Bytes::from_static(b"INVITE")),
1364 Method::Invite
1365 );
1366 }
1367
1368 #[test]
1374 fn remove_first_takes_only_the_topmost_via() {
1375 let mut headers = Headers::new();
1376 for value in [&b"first"[..], b"second", b"third"] {
1377 headers.push(Header::new_unchecked(
1378 HeaderName::Via,
1379 Bytes::copy_from_slice(value),
1380 ));
1381 }
1382 headers.insert(
1385 1,
1386 Header::new_unchecked(HeaderName::Route, Bytes::from_static(b"r")),
1387 );
1388
1389 let taken = headers.remove_first(&HeaderName::Via).expect("a Via");
1390 assert_eq!(taken.value().as_ref(), b"first");
1391 assert_eq!(
1392 headers
1393 .get_all(&HeaderName::Via)
1394 .map(|h| h.value().to_vec())
1395 .collect::<Vec<_>>(),
1396 vec![b"second".to_vec(), b"third".to_vec()],
1397 "the remaining Vias keep their order"
1398 );
1399 assert_eq!(
1400 headers.iter().map(|h| h.name().clone()).collect::<Vec<_>>(),
1401 vec![HeaderName::Route, HeaderName::Via, HeaderName::Via],
1402 "and every other header stays where it was"
1403 );
1404 }
1405
1406 #[test]
1407 fn remove_first_on_a_name_that_is_absent_yields_nothing_and_changes_nothing() {
1408 let mut headers = Headers::new();
1409 headers.push(Header::new_unchecked(
1410 HeaderName::Via,
1411 Bytes::from_static(b"v"),
1412 ));
1413 assert!(headers.remove_first(&HeaderName::Route).is_none());
1414 assert_eq!(headers.len(), 1);
1415 }
1416
1417 #[test]
1421 fn inserting_past_the_end_appends_rather_than_panicking() {
1422 let mut headers = Headers::new();
1423 headers.push(Header::new_unchecked(
1424 HeaderName::Via,
1425 Bytes::from_static(b"v"),
1426 ));
1427 headers.insert(
1428 9999,
1429 Header::new_unchecked(HeaderName::Route, Bytes::from_static(b"r")),
1430 );
1431 assert_eq!(headers.len(), 2);
1432 assert_eq!(
1433 headers.iter().last().map(|h| h.name().clone()),
1434 Some(HeaderName::Route)
1435 );
1436 }
1437
1438 #[test]
1439 fn insert_places_a_header_at_an_absolute_position() {
1440 let mut headers = Headers::new();
1441 for name in [HeaderName::Via, HeaderName::To, HeaderName::From] {
1442 headers.push(Header::new_unchecked(name, Bytes::from_static(b"x")));
1443 }
1444 headers.insert(
1445 1,
1446 Header::new_unchecked(HeaderName::RecordRoute, Bytes::from_static(b"rr")),
1447 );
1448 assert_eq!(
1449 headers.iter().map(|h| h.name().clone()).collect::<Vec<_>>(),
1450 vec![
1451 HeaderName::Via,
1452 HeaderName::RecordRoute,
1453 HeaderName::To,
1454 HeaderName::From
1455 ]
1456 );
1457 headers.insert(
1459 0,
1460 Header::new_unchecked(HeaderName::Via, Bytes::from_static(b"newest")),
1461 );
1462 assert_eq!(headers.value(&HeaderName::Via).unwrap().as_ref(), b"newest");
1463 }
1464
1465 #[test]
1467 fn retain_filters_in_place_and_keeps_order() {
1468 let mut headers = Headers::new();
1469 for (name, value) in [
1470 (HeaderName::Via, &b"keep"[..]),
1471 (HeaderName::Route, b"drop"),
1472 (HeaderName::Via, b"drop"),
1473 (HeaderName::To, b"keep"),
1474 ] {
1475 headers.push(Header::new_unchecked(name, Bytes::copy_from_slice(value)));
1476 }
1477 headers.retain(|header| header.value().as_ref() == b"keep");
1478 assert_eq!(
1479 headers.iter().map(|h| h.name().clone()).collect::<Vec<_>>(),
1480 vec![HeaderName::Via, HeaderName::To]
1481 );
1482 }
1483
1484 #[test]
1485 fn header_order_is_preserved_including_duplicates() {
1486 let mut headers = Headers::new();
1487 headers.push(Header::new_unchecked(
1488 HeaderName::Via,
1489 Bytes::from_static(b"first"),
1490 ));
1491 headers.push(Header::new_unchecked(
1492 HeaderName::Route,
1493 Bytes::from_static(b"r"),
1494 ));
1495 headers.push(Header::new_unchecked(
1496 HeaderName::Via,
1497 Bytes::from_static(b"second"),
1498 ));
1499
1500 let vias: Vec<_> = headers
1501 .get_all(&HeaderName::Via)
1502 .map(|h| h.value().to_vec())
1503 .collect();
1504 assert_eq!(vias, vec![b"first".to_vec(), b"second".to_vec()]);
1505 assert_eq!(headers.count(&HeaderName::Via), 2);
1506
1507 headers.push_front(Header::new_unchecked(
1509 HeaderName::Via,
1510 Bytes::from_static(b"newest"),
1511 ));
1512 assert_eq!(headers.value(&HeaderName::Via).unwrap().as_ref(), b"newest");
1513 }
1514
1515 #[test]
1518 fn typed_all_yields_each_element_of_a_comma_separated_row() {
1519 use crate::headers::Contact;
1520
1521 let mut headers = Headers::new();
1522 headers.push(Header::new_unchecked(
1523 HeaderName::Contact,
1524 Bytes::from_static(b"<sip:a@b.com>, <sip:c@d.com>"),
1525 ));
1526 headers.push(Header::new_unchecked(
1527 HeaderName::Contact,
1528 Bytes::from_static(b"<sip:e@f.org>"),
1529 ));
1530
1531 let contacts: Vec<Contact> = headers
1532 .typed_all::<Contact>()
1533 .collect::<Result<_, _>>()
1534 .unwrap();
1535 let uris: Vec<_> = contacts.iter().map(|c| c.uri.to_bytes()).collect();
1536 assert_eq!(
1537 uris,
1538 vec![
1539 Bytes::from_static(b"sip:a@b.com"),
1540 Bytes::from_static(b"sip:c@d.com"),
1541 Bytes::from_static(b"sip:e@f.org"),
1542 ]
1543 );
1544 }
1545
1546 #[test]
1547 fn typed_all_keeps_unconstrained_headers_lazy() {
1548 use std::sync::atomic::{AtomicUsize, Ordering};
1549
1550 static DECODES: AtomicUsize = AtomicUsize::new(0);
1551
1552 struct CountingSubject;
1553
1554 impl TypedHeader for CountingSubject {
1555 const NAME: HeaderName = HeaderName::Subject;
1556
1557 fn decode(_value: &[u8]) -> Result<Self, HeaderError> {
1558 DECODES.fetch_add(1, Ordering::SeqCst);
1559 Ok(Self)
1560 }
1561 }
1562
1563 DECODES.store(0, Ordering::SeqCst);
1564 let mut headers = Headers::new();
1565 headers.push(Header::new_unchecked(
1566 HeaderName::Subject,
1567 Bytes::from_static(b"first"),
1568 ));
1569 headers.push(Header::new_unchecked(
1570 HeaderName::Subject,
1571 Bytes::from_static(b"second"),
1572 ));
1573
1574 let mut values = headers.typed_all::<CountingSubject>();
1575 assert_eq!(DECODES.load(Ordering::SeqCst), 0);
1576 assert!(values.next().is_some_and(|value| value.is_ok()));
1577 assert_eq!(DECODES.load(Ordering::SeqCst), 1);
1578 drop(values);
1579 assert_eq!(DECODES.load(Ordering::SeqCst), 1);
1580 }
1581
1582 #[test]
1583 fn built_headers_serialize_canonically() {
1584 let mut headers = Headers::new();
1585 headers.push(Header::new_unchecked(
1586 HeaderName::MaxForwards,
1587 Bytes::from_static(b"70"),
1588 ));
1589 let mut out = Vec::new();
1590 headers.write_to(&mut out);
1591 assert_eq!(out, b"Max-Forwards: 70\r\n");
1592 }
1593
1594 #[test]
1595 fn wire_headers_serialize_verbatim() {
1596 let line = Bytes::from_static(b"MaX-fOrWaRdS : 0068");
1598 let h = Header::from_wire(HeaderName::MaxForwards, line.clone(), 17);
1599 let mut out = Vec::new();
1600 h.write_to(&mut out);
1601 assert_eq!(out, line);
1602 assert_eq!(h.value().as_ref(), b"0068");
1603 }
1604}