Configure content disposition

This commit is contained in:
2026-03-23 16:26:28 -07:00
parent 9008a248c1
commit 5da81679be
3 changed files with 33 additions and 4 deletions

View File

@@ -57,6 +57,7 @@ unimplemented = "deny"
unwrap_used = "warn" unwrap_used = "warn"
expect_used = "warn" expect_used = "warn"
type_complexity = "allow" type_complexity = "allow"
len_without_is_empty = "allow"
# #
# MARK: dependencies # MARK: dependencies

View File

@@ -18,6 +18,8 @@ pub struct FieldQuery {
source: String, source: String,
key: String, key: String,
path: String, path: String,
#[serde(default)]
download: bool,
} }
/// Extract a specific field from an item's metadata /// Extract a specific field from an item's metadata
@@ -79,21 +81,38 @@ pub async fn get_field(
time_ms = start.elapsed().as_millis() time_ms = start.elapsed().as_millis()
); );
let disposition = if params.download {
"attachment"
} else {
"inline"
};
match value { match value {
PileValue::String(s) => ( PileValue::String(s) => (
StatusCode::OK, StatusCode::OK,
[(header::CONTENT_TYPE, "text/plain")], [
(header::CONTENT_TYPE, "text/plain".to_owned()),
(header::CONTENT_DISPOSITION, disposition.to_owned()),
],
s.to_string(), s.to_string(),
) )
.into_response(), .into_response(),
PileValue::Blob { mime, bytes } => ( PileValue::Blob { mime, bytes } => (
StatusCode::OK, StatusCode::OK,
[(header::CONTENT_TYPE, mime.to_string())], [
(header::CONTENT_TYPE, mime.to_string()),
(header::CONTENT_DISPOSITION, disposition.to_owned()),
],
bytes.as_ref().clone(), bytes.as_ref().clone(),
) )
.into_response(), .into_response(),
_ => match value.to_json(&state).await { _ => match value.to_json(&state).await {
Ok(json) => (StatusCode::OK, Json(json)).into_response(), Ok(json) => (
StatusCode::OK,
[(header::CONTENT_DISPOSITION, disposition.to_owned())],
Json(json),
)
.into_response(),
Err(e) => (StatusCode::INTERNAL_SERVER_ERROR, format!("{e:?}")).into_response(), Err(e) => (StatusCode::INTERNAL_SERVER_ERROR, format!("{e:?}")).into_response(),
}, },
} }

View File

@@ -19,6 +19,8 @@ use crate::Datasets;
pub struct ItemQuery { pub struct ItemQuery {
source: String, source: String,
key: String, key: String,
#[serde(default)]
download: bool,
} }
/// Parse a `Range: bytes=...` header value. /// Parse a `Range: bytes=...` header value.
@@ -161,11 +163,18 @@ pub async fn item_get(
StatusCode::OK StatusCode::OK
}; };
let disposition = if params.download {
"attachment"
} else {
"inline"
};
let mut builder = axum::http::Response::builder() let mut builder = axum::http::Response::builder()
.status(status) .status(status)
.header(header::CONTENT_TYPE, mime) .header(header::CONTENT_TYPE, mime)
.header(header::ACCEPT_RANGES, "bytes") .header(header::ACCEPT_RANGES, "bytes")
.header(header::CONTENT_LENGTH, length); .header(header::CONTENT_LENGTH, length)
.header(header::CONTENT_DISPOSITION, disposition);
if is_range { if is_range {
builder = builder.header( builder = builder.header(