Skip to content

Commit

Permalink
feat(core): Add cache-control to Metadata (#2136)
Browse files Browse the repository at this point in the history
* feat(core): Add `cache-control` to Matadata

Signed-off-by: suyanhanx <suyanhanx@gmail.com>

* make fmt happy

Signed-off-by: suyanhanx <suyanhanx@gmail.com>

* use header constant

Signed-off-by: suyanhanx <suyanhanx@gmail.com>

* fix unit test

Signed-off-by: suyanhanx <suyanhanx@gmail.com>

---------

Signed-off-by: suyanhanx <suyanhanx@gmail.com>
  • Loading branch information
suyanhanx authored Apr 26, 2023
1 parent f9cdce3 commit d3be656
Show file tree
Hide file tree
Showing 3 changed files with 89 additions and 27 deletions.
4 changes: 2 additions & 2 deletions core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,8 +89,8 @@ mod tests {
#[test]
fn assert_size() {
assert_eq!(24, size_of::<Operator>());
assert_eq!(216, size_of::<Entry>());
assert_eq!(192, size_of::<Metadata>());
assert_eq!(240, size_of::<Entry>());
assert_eq!(216, size_of::<Metadata>());
assert_eq!(1, size_of::<EntryMode>());
assert_eq!(24, size_of::<Scheme>());
}
Expand Down
25 changes: 25 additions & 0 deletions core/src/raw/http_util/header.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ use base64::Engine;
use chrono::DateTime;
use chrono::Utc;
use http::header::HeaderName;
use http::header::CACHE_CONTROL;
use http::header::CONTENT_DISPOSITION;
use http::header::CONTENT_LENGTH;
use http::header::CONTENT_RANGE;
Expand Down Expand Up @@ -56,6 +57,26 @@ pub fn parse_location(headers: &HeaderMap) -> Result<Option<&str>> {
}
}

/// Parse cache control from header map.
///
/// # Note
///
/// The returned value is the raw string of `cache-control` header,
/// maybe `no-cache`, `max-age=3600`, etc.
pub fn parse_cache_control(headers: &HeaderMap) -> Result<Option<&str>> {
match headers.get(CACHE_CONTROL) {
None => Ok(None),
Some(v) => Ok(Some(v.to_str().map_err(|e| {
Error::new(
ErrorKind::Unexpected,
"header value has to be valid utf-8 string",
)
.with_operation("http_util::parse_cache_control")
.set_source(e)
})?)),
}
}

/// Parse content length from header map.
pub fn parse_content_length(headers: &HeaderMap) -> Result<Option<u64>> {
match headers.get(CONTENT_LENGTH) {
Expand Down Expand Up @@ -193,6 +214,10 @@ pub fn parse_into_metadata(path: &str, headers: &HeaderMap) -> Result<Metadata>
};
let mut m = Metadata::new(mode);

if let Some(v) = parse_cache_control(headers)? {
m.set_cache_control(v);
}

if let Some(v) = parse_content_length(headers)? {
m.set_content_length(v);
}
Expand Down
87 changes: 62 additions & 25 deletions core/src/types/metadata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ pub struct Metadata {

mode: EntryMode,

cache_control: Option<String>,
content_disposition: Option<String>,
content_length: Option<u64>,
content_md5: Option<String>,
Expand All @@ -49,16 +50,18 @@ impl Metadata {
/// Create a new metadata
pub fn new(mode: EntryMode) -> Self {
// Mode is required to be set for metadata.
let mut bit = Metakey::Mode.into();
let mut bit: FlagSet<Metakey> = Metakey::Mode.into();
// If mode is dir, we should always mark it as complete.
if mode.is_dir() {
bit |= Metakey::Complete
}

Self {
bit,

mode,

cache_control: None,
content_length: None,
content_md5: None,
content_type: None,
Expand Down Expand Up @@ -101,19 +104,51 @@ impl Metadata {
}

/// Set mode for entry.
pub fn set_mode(&mut self, mode: EntryMode) -> &mut Self {
self.mode = mode;
pub fn set_mode(&mut self, v: EntryMode) -> &mut Self {
self.mode = v;
self.bit |= Metakey::Mode;
self
}

/// Set mode for entry.
pub fn with_mode(mut self, mode: EntryMode) -> Self {
self.mode = mode;
pub fn with_mode(mut self, v: EntryMode) -> Self {
self.mode = v;
self.bit |= Metakey::Mode;
self
}

/// Cache control of this entry.
/// Cache-Control is defined by [RFC 7234](https://httpwg.org/specs/rfc7234.html#header.cache-control)
/// Refer to [MDN Cache-Control](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control) for more information.
pub fn cache_control(&self) -> Option<&str> {
debug_assert!(
self.bit.contains(Metakey::CacheControl) || self.bit.contains(Metakey::Complete),
"visiting not set metadata: cache_control, maybe a bug"
);

self.cache_control.as_deref()
}

/// Set cache control of this entry.
///
/// Cache-Control is defined by [RFC 7234](https://httpwg.org/specs/rfc7234.html#header.cache-control)
/// Refer to [MDN Cache-Control](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control) for more information.
pub fn set_cache_control(&mut self, v: &str) -> &mut Self {
self.cache_control = Some(v.to_string());
self.bit |= Metakey::CacheControl;
self
}

/// Set cache control of this entry.
///
/// Cache-Control is defined by [RFC 7234](https://httpwg.org/specs/rfc7234.html#header.cache-control)
/// Refer to [MDN Cache-Control](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control) for more information.
pub fn with_cache_control(mut self, v: String) -> Self {
self.cache_control = Some(v);
self.bit |= Metakey::CacheControl;
self
}

/// Content length of this entry.
///
/// `Content-Length` is defined by [RFC 7230](https://httpwg.org/specs/rfc7230.html#header.content-length)
Expand All @@ -133,15 +168,15 @@ impl Metadata {
}

/// Set content length of this entry.
pub fn set_content_length(&mut self, content_length: u64) -> &mut Self {
self.content_length = Some(content_length);
pub fn set_content_length(&mut self, v: u64) -> &mut Self {
self.content_length = Some(v);
self.bit |= Metakey::ContentLength;
self
}

/// Set content length of this entry.
pub fn with_content_length(mut self, content_length: u64) -> Self {
self.content_length = Some(content_length);
pub fn with_content_length(mut self, v: u64) -> Self {
self.content_length = Some(v);
self.bit |= Metakey::ContentLength;
self
}
Expand All @@ -165,8 +200,8 @@ impl Metadata {
///
/// Content MD5 is defined by [RFC 2616](http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html).
/// And removed by [RFC 7231](https://www.rfc-editor.org/rfc/rfc7231).
pub fn set_content_md5(&mut self, content_md5: &str) -> &mut Self {
self.content_md5 = Some(content_md5.to_string());
pub fn set_content_md5(&mut self, v: &str) -> &mut Self {
self.content_md5 = Some(v.to_string());
self.bit |= Metakey::ContentMd5;
self
}
Expand All @@ -175,8 +210,8 @@ impl Metadata {
///
/// Content MD5 is defined by [RFC 2616](http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html).
/// And removed by [RFC 7231](https://www.rfc-editor.org/rfc/rfc7231).
pub fn with_content_md5(mut self, content_md5: String) -> Self {
self.content_md5 = Some(content_md5);
pub fn with_content_md5(mut self, v: String) -> Self {
self.content_md5 = Some(v);
self.bit |= Metakey::ContentMd5;
self
}
Expand Down Expand Up @@ -260,8 +295,8 @@ impl Metadata {
///
/// `Last-Modified` is defined by [RFC 7232](https://httpwg.org/specs/rfc7232.html#header.last-modified)
/// Refer to [MDN Last-Modified](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Last-Modified) for more information.
pub fn set_last_modified(&mut self, last_modified: DateTime<Utc>) -> &mut Self {
self.last_modified = Some(last_modified);
pub fn set_last_modified(&mut self, v: DateTime<Utc>) -> &mut Self {
self.last_modified = Some(v);
self.bit |= Metakey::LastModified;
self
}
Expand All @@ -270,8 +305,8 @@ impl Metadata {
///
/// `Last-Modified` is defined by [RFC 7232](https://httpwg.org/specs/rfc7232.html#header.last-modified)
/// Refer to [MDN Last-Modified](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Last-Modified) for more information.
pub fn with_last_modified(mut self, last_modified: DateTime<Utc>) -> Self {
self.last_modified = Some(last_modified);
pub fn with_last_modified(mut self, v: DateTime<Utc>) -> Self {
self.last_modified = Some(v);
self.bit |= Metakey::LastModified;
self
}
Expand Down Expand Up @@ -307,8 +342,8 @@ impl Metadata {
/// - `W/"0815"`
///
/// `"` is part of etag, don't trim it before setting.
pub fn set_etag(&mut self, etag: &str) -> &mut Self {
self.etag = Some(etag.to_string());
pub fn set_etag(&mut self, v: &str) -> &mut Self {
self.etag = Some(v.to_string());
self.bit |= Metakey::Etag;
self
}
Expand All @@ -324,8 +359,8 @@ impl Metadata {
/// - `W/"0815"`
///
/// `"` is part of etag, don't trim it before setting.
pub fn with_etag(mut self, etag: String) -> Self {
self.etag = Some(etag);
pub fn with_etag(mut self, v: String) -> Self {
self.etag = Some(v);
self.bit |= Metakey::Etag;
self
}
Expand Down Expand Up @@ -361,8 +396,8 @@ impl Metadata {
/// - "inline"
/// - "attachment"
/// - "attachment; filename=\"filename.jpg\""
pub fn with_content_disposition(mut self, content_disposition: String) -> Self {
self.content_disposition = Some(content_disposition);
pub fn with_content_disposition(mut self, v: String) -> Self {
self.content_disposition = Some(v);
self.bit |= Metakey::ContentDisposition;
self
}
Expand All @@ -378,8 +413,8 @@ impl Metadata {
/// - "inline"
/// - "attachment"
/// - "attachment; filename=\"filename.jpg\""
pub fn set_content_disposition(&mut self, content_disposition: &str) -> &mut Self {
self.content_disposition = Some(content_disposition.to_string());
pub fn set_content_disposition(&mut self, v: &str) -> &mut Self {
self.content_disposition = Some(v.to_string());
self.bit |= Metakey::ContentDisposition;
self
}
Expand All @@ -406,6 +441,8 @@ flags! {

/// Key for mode.
Mode,
/// Key for cache control.
CacheControl,
/// Key for content disposition.
ContentDisposition,
/// Key for content length.
Expand Down

0 comments on commit d3be656

Please sign in to comment.