feat: implements remaining http cache conditionalss (#407)

* implements remaining http conditionals

* computed etag is not optional
This commit is contained in:
Matthias Möller
2024-06-23 14:25:07 +02:00
committed by GitHub
parent f1e90686dc
commit 632f7a41bf
2 changed files with 104 additions and 13 deletions

View File

@@ -15,8 +15,8 @@ use chrono::{LocalResult, TimeZone, Utc};
use futures_util::{pin_mut, TryStreamExt};
use headers::{
AcceptRanges, AccessControlAllowCredentials, AccessControlAllowOrigin, CacheControl,
ContentLength, ContentType, ETag, HeaderMap, HeaderMapExt, IfModifiedSince, IfNoneMatch,
IfRange, LastModified, Range,
ContentLength, ContentType, ETag, HeaderMap, HeaderMapExt, IfMatch, IfModifiedSince,
IfNoneMatch, IfRange, IfUnmodifiedSince, LastModified, Range,
};
use http_body_util::{combinators::BoxBody, BodyExt, StreamBody};
use hyper::body::Frame;
@@ -796,18 +796,29 @@ impl Server {
let size = meta.len();
let mut use_range = true;
if let Some((etag, last_modified)) = extract_cache_headers(&meta) {
let cached = {
if let Some(if_none_match) = headers.typed_get::<IfNoneMatch>() {
!if_none_match.precondition_passes(&etag)
} else if let Some(if_modified_since) = headers.typed_get::<IfModifiedSince>() {
!if_modified_since.is_modified(last_modified.into())
} else {
false
if let Some(if_unmodified_since) = headers.typed_get::<IfUnmodifiedSince>() {
if !if_unmodified_since.precondition_passes(last_modified.into()) {
*res.status_mut() = StatusCode::PRECONDITION_FAILED;
return Ok(());
}
}
if let Some(if_match) = headers.typed_get::<IfMatch>() {
if !if_match.precondition_passes(&etag) {
*res.status_mut() = StatusCode::PRECONDITION_FAILED;
return Ok(());
}
}
if let Some(if_modified_since) = headers.typed_get::<IfModifiedSince>() {
if !if_modified_since.is_modified(last_modified.into()) {
*res.status_mut() = StatusCode::NOT_MODIFIED;
return Ok(());
}
}
if let Some(if_none_match) = headers.typed_get::<IfNoneMatch>() {
if !if_none_match.precondition_passes(&etag) {
*res.status_mut() = StatusCode::NOT_MODIFIED;
return Ok(());
}
};
if cached {
*res.status_mut() = StatusCode::NOT_MODIFIED;
return Ok(());
}
res.headers_mut().typed_insert(last_modified);