Skip to content

Commit d19a17e

Browse files
committed
refactor(ext): add new CasedHeaderName struct for HeaderCaseMap
1 parent a92c250 commit d19a17e

File tree

3 files changed

+47
-23
lines changed

3 files changed

+47
-23
lines changed

src/ext/mod.rs

Lines changed: 28 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -42,10 +42,12 @@ use bytes::Bytes;
4242
feature = "ffi"
4343
))]
4444
use http::header::HeaderName;
45+
#[cfg(all(feature = "http1", feature = "ffi"))]
46+
use http::header::IntoHeaderName;
4547
#[cfg(all(any(feature = "client", feature = "server"), feature = "http1"))]
4648
use http::header::InvalidHeaderName;
4749
#[cfg(all(any(feature = "client", feature = "server"), feature = "http1"))]
48-
use http::header::{HeaderMap, IntoHeaderName, ValueIter};
50+
use http::header::{HeaderMap, ValueIter};
4951
#[cfg(feature = "ffi")]
5052
use std::collections::HashMap;
5153
#[cfg(feature = "http2")]
@@ -183,24 +185,40 @@ impl HeaderCaseMap {
183185

184186
/// Inserts a header spelling, replacing any existing ones associated with that header name.
185187
#[cfg(all(any(feature = "client", feature = "server"), feature = "http1"))]
186-
pub fn insert(&mut self, name: HeaderName, orig: Bytes) -> Result<(), InvalidHeaderName> {
187-
HeaderName::from_bytes(&orig)?;
188-
self.0.insert(name, orig);
188+
pub fn insert(&mut self, name: CasedHeaderName) -> Result<(), InvalidHeaderName> {
189+
self.0.insert(name.0, name.1);
189190
Ok(())
190191
}
191192

192193
/// Inserts a header spelling in addition to any existing ones associated with that header name.
193194
#[cfg(all(any(feature = "client", feature = "server"), feature = "http1"))]
194-
pub fn append<N>(&mut self, name: N, orig: Bytes) -> Result<(), InvalidHeaderName>
195-
where
196-
N: IntoHeaderName,
197-
{
198-
HeaderName::from_bytes(&orig)?;
199-
self.0.append(name, orig);
195+
pub fn append(&mut self, name: CasedHeaderName) -> Result<(), InvalidHeaderName> {
196+
self.0.append(name.0, name.1);
200197
Ok(())
201198
}
202199
}
203200

201+
/// A header casing representation, guaranteed to be a valid [`http::HeaderName`].
202+
#[cfg(all(any(feature = "client", feature = "server"), feature = "http1"))]
203+
#[derive(Debug)]
204+
pub struct CasedHeaderName(pub HeaderName, pub Bytes);
205+
206+
#[cfg(all(any(feature = "client", feature = "server"), feature = "http1"))]
207+
impl TryFrom<Bytes> for CasedHeaderName {
208+
type Error = InvalidHeaderName;
209+
210+
fn try_from(orig: Bytes) -> Result<Self, Self::Error> {
211+
HeaderName::from_bytes(&orig).map(|name| CasedHeaderName(name, orig))
212+
}
213+
}
214+
215+
#[cfg(all(any(feature = "client", feature = "server"), feature = "http1"))]
216+
impl From<CasedHeaderName> for HeaderName {
217+
fn from(value: CasedHeaderName) -> Self {
218+
value.0
219+
}
220+
}
221+
204222
#[cfg(feature = "ffi")]
205223
#[derive(Clone, Debug)]
206224
/// Hashmap<Headername, numheaders with that name>

src/ffi/http_types.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use super::error::hyper_code;
77
use super::task::{hyper_task_return_type, AsTaskType};
88
use super::{UserDataPointer, HYPER_ITER_CONTINUE};
99
use crate::body::Incoming as IncomingBody;
10-
use crate::ext::{HeaderCaseMap, OriginalHeaderOrder, ReasonPhrase};
10+
use crate::ext::{CasedHeaderName, HeaderCaseMap, OriginalHeaderOrder, ReasonPhrase};
1111
use crate::ffi::size_t;
1212
use crate::header::{HeaderName, HeaderValue};
1313
use crate::{HeaderMap, Method, Request, Response, Uri};
@@ -513,7 +513,7 @@ ffi_fn! {
513513
match unsafe { raw_name_value(name, name_len, value, value_len) } {
514514
Ok((name, value, orig_name)) => {
515515
headers.headers.insert(&name, value);
516-
headers.orig_casing.insert(name.clone(), orig_name.clone()).unwrap();
516+
headers.orig_casing.insert(CasedHeaderName(name.clone(), orig_name)).unwrap();
517517
headers.orig_order.insert(name);
518518
hyper_code::HYPERE_OK
519519
}
@@ -533,7 +533,7 @@ ffi_fn! {
533533
match unsafe { raw_name_value(name, name_len, value, value_len) } {
534534
Ok((name, value, orig_name)) => {
535535
headers.headers.append(&name, value);
536-
headers.orig_casing.append(&name, orig_name.clone()).unwrap();
536+
headers.orig_casing.append(CasedHeaderName(name.clone(), orig_name)).unwrap();
537537
headers.orig_order.append(name);
538538
hyper_code::HYPERE_OK
539539
}

src/proto/h1/role.rs

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -315,8 +315,10 @@ impl Http1Transaction for Server {
315315
}
316316

317317
if let Some(ref mut header_case_map) = header_case_map {
318+
use crate::ext::CasedHeaderName;
319+
318320
header_case_map
319-
.append(&name, slice.slice(header.name.0..header.name.1))
321+
.append(CasedHeaderName(name.clone(), slice.slice(header.name.0..header.name.1)))
320322
.unwrap();
321323
}
322324

@@ -1108,8 +1110,10 @@ impl Http1Transaction for Client {
11081110
}
11091111

11101112
if let Some(ref mut header_case_map) = header_case_map {
1113+
use crate::ext::CasedHeaderName;
1114+
11111115
header_case_map
1112-
.append(&name, slice.slice(header.name.0..header.name.1))
1116+
.append(CasedHeaderName(name.clone(), slice.slice(header.name.0..header.name.1)))
11131117
.unwrap();
11141118
}
11151119

@@ -1645,6 +1649,8 @@ fn extend(dst: &mut Vec<u8>, data: &[u8]) {
16451649
mod tests {
16461650
use bytes::BytesMut;
16471651

1652+
use crate::ext::CasedHeaderName;
1653+
16481654
use super::*;
16491655

16501656
#[cfg(feature = "server")]
@@ -2492,7 +2498,7 @@ mod tests {
24922498

24932499
let mut orig_headers = HeaderCaseMap::default();
24942500
orig_headers
2495-
.insert(CONTENT_LENGTH, "CONTENT-LENGTH".into())
2501+
.insert(CasedHeaderName(CONTENT_LENGTH, "CONTENT-LENGTH".into()))
24962502
.unwrap();
24972503
head.extensions.insert(orig_headers);
24982504

@@ -2531,7 +2537,7 @@ mod tests {
25312537

25322538
let mut orig_headers = HeaderCaseMap::default();
25332539
orig_headers
2534-
.insert(CONTENT_LENGTH, "CONTENT-LENGTH".into())
2540+
.insert(CasedHeaderName(CONTENT_LENGTH, "CONTENT-LENGTH".into()))
25352541
.unwrap();
25362542
head.extensions.insert(orig_headers);
25372543

@@ -2628,7 +2634,7 @@ mod tests {
26282634

26292635
let mut orig_headers = HeaderCaseMap::default();
26302636
orig_headers
2631-
.insert(CONTENT_LENGTH, "CONTENT-LENGTH".into())
2637+
.insert(CasedHeaderName(CONTENT_LENGTH, "CONTENT-LENGTH".into()))
26322638
.unwrap();
26332639
head.extensions.insert(orig_headers);
26342640

@@ -2666,7 +2672,7 @@ mod tests {
26662672

26672673
let mut orig_headers = HeaderCaseMap::default();
26682674
orig_headers
2669-
.insert(CONTENT_LENGTH, "CONTENT-LENGTH".into())
2675+
.insert(CasedHeaderName(CONTENT_LENGTH, "CONTENT-LENGTH".into()))
26702676
.unwrap();
26712677
head.extensions.insert(orig_headers);
26722678

@@ -2705,7 +2711,7 @@ mod tests {
27052711

27062712
let mut orig_headers = HeaderCaseMap::default();
27072713
orig_headers
2708-
.insert(CONTENT_LENGTH, "CONTENT-LENGTH".into())
2714+
.insert(CasedHeaderName(CONTENT_LENGTH, "CONTENT-LENGTH".into()))
27092715
.unwrap();
27102716
head.extensions.insert(orig_headers);
27112717

@@ -2912,7 +2918,7 @@ mod tests {
29122918
headers.insert(&name, "".parse().expect("parse empty"));
29132919
let mut orig_cases = HeaderCaseMap::default();
29142920
orig_cases
2915-
.insert(name, Bytes::from_static(b"X-EmptY"))
2921+
.insert(CasedHeaderName(name, Bytes::from_static(b"X-EmptY")))
29162922
.unwrap();
29172923

29182924
let mut dst = Vec::new();
@@ -2933,10 +2939,10 @@ mod tests {
29332939

29342940
let mut orig_cases = HeaderCaseMap::default();
29352941
orig_cases
2936-
.insert(name.clone(), Bytes::from_static(b"X-Empty"))
2942+
.insert(CasedHeaderName(name.clone(), Bytes::from_static(b"X-Empty")))
29372943
.unwrap();
29382944
orig_cases
2939-
.append(name, Bytes::from_static(b"X-EMPTY"))
2945+
.append(CasedHeaderName(name, Bytes::from_static(b"X-EMPTY")))
29402946
.unwrap();
29412947

29422948
let mut dst = Vec::new();

0 commit comments

Comments
 (0)