Skip to content

Commit 91fb52b

Browse files
committed
Add Content-MD5 header
1 parent f01cc90 commit 91fb52b

File tree

2 files changed

+57
-0
lines changed

2 files changed

+57
-0
lines changed

src/common/content_md5.rs

+55
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
use std::convert::TryInto;
2+
use {Header, HeaderValue};
3+
4+
/// `Content-MD5` header, defined in
5+
/// [RFC1864](https://datatracker.ietf.org/doc/html/rfc1864)
6+
///
7+
/// ## ABNF
8+
///
9+
/// ```text
10+
/// Content-Length = 1*DIGIT
11+
/// ```
12+
///
13+
/// ## Example values
14+
///
15+
/// * `Q2hlY2sgSW50ZWdyaXR5IQ==`
16+
///
17+
/// # Example
18+
///
19+
/// ```
20+
/// # extern crate headers;
21+
/// use headers::ContentMd5;
22+
///
23+
/// let md5 = ContentMd5([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5]);
24+
/// ```
25+
#[derive(Clone, Copy, Debug, PartialEq)]
26+
pub struct ContentMd5(pub [u8; 16]);
27+
28+
static CONTENT_MD5: ::http::header::HeaderName =
29+
::http::header::HeaderName::from_static("content-md5");
30+
31+
impl Header for ContentMd5 {
32+
fn name() -> &'static ::http::header::HeaderName {
33+
&CONTENT_MD5
34+
}
35+
36+
fn decode<'i, I: Iterator<Item = &'i HeaderValue>>(values: &mut I) -> Result<Self, ::Error> {
37+
let value = values.next().ok_or_else(::Error::invalid)?;
38+
39+
// Ensure base64 encoded length fits the expected MD5 digest length.
40+
if value.len() < 22 || value.len() > 24 {
41+
return Err(::Error::invalid());
42+
}
43+
44+
let value = value.to_str().map_err(|_| ::Error::invalid())?;
45+
let vec = base64::decode(value).map_err(|_| ::Error::invalid())?;
46+
Ok(Self(vec.try_into().map_err(|_| ::Error::invalid())?))
47+
}
48+
49+
fn encode<E: Extend<::HeaderValue>>(&self, values: &mut E) {
50+
let encoded = base64::encode(self.0);
51+
if let Ok(value) = HeaderValue::from_str(&encoded) {
52+
values.extend(std::iter::once(value));
53+
}
54+
}
55+
}

src/common/mod.rs

+2
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ pub use self::content_encoding::ContentEncoding;
2929
//pub use self::content_language::ContentLanguage;
3030
pub use self::content_length::ContentLength;
3131
pub use self::content_location::ContentLocation;
32+
pub use self::content_md5::ContentMd5;
3233
pub use self::content_range::ContentRange;
3334
pub use self::content_type::ContentType;
3435
pub use self::cookie::Cookie;
@@ -149,6 +150,7 @@ mod content_encoding;
149150
//mod content_language;
150151
mod content_length;
151152
mod content_location;
153+
mod content_md5;
152154
mod content_range;
153155
mod content_type;
154156
mod cookie;

0 commit comments

Comments
 (0)