(literal: &[u8])
| 754 | } |
| 755 | |
| 756 | fn parse_headers(literal: &[u8]) -> BTreeMap<String, String> { |
| 757 | let mut headers: BTreeMap<String, String> = BTreeMap::new(); |
| 758 | let text = String::from_utf8_lossy(literal); |
| 759 | let mut current_key: Option<String> = None; |
| 760 | |
| 761 | for raw_line in text.lines() { |
| 762 | let line = raw_line.trim_end_matches('\r'); |
| 763 | if line.is_empty() { |
| 764 | break; |
| 765 | } |
| 766 | |
| 767 | if line.starts_with(' ') || line.starts_with('\t') { |
| 768 | if let Some(key) = current_key.as_deref() |
| 769 | && let Some(value) = headers.get_mut(key) |
| 770 | { |
| 771 | value.push(' '); |
| 772 | value.push_str(line.trim()); |
| 773 | } |
| 774 | continue; |
| 775 | } |
| 776 | |
| 777 | let Some((name, value)) = line.split_once(':') else { |
| 778 | continue; |
| 779 | }; |
| 780 | |
| 781 | let key = name.trim().to_ascii_lowercase(); |
| 782 | headers.insert(key.clone(), value.trim().to_string()); |
| 783 | current_key = Some(key); |
| 784 | } |
| 785 | |
| 786 | headers |
| 787 | } |
| 788 | |
| 789 | fn split_headers_and_body(raw: &[u8]) -> (BTreeMap<String, String>, &[u8]) { |
| 790 | if let Some(index) = find_subsequence(raw, b"\r\n\r\n") { |
no outgoing calls