content disposition
This commit is contained in:
@@ -1113,10 +1113,13 @@ pub async fn get_document_asset(
|
||||
|
||||
let mut object_responses = Vec::with_capacity(objects.len());
|
||||
for object in objects {
|
||||
let response_disposition = presign_disposition_for_asset(&asset, &object);
|
||||
|
||||
let url = storage
|
||||
.presign_get_object(
|
||||
&object.s3_key,
|
||||
Duration::from_secs(PRESIGNED_URL_EXPIRY_SECONDS),
|
||||
response_disposition.as_deref(),
|
||||
)
|
||||
.await
|
||||
.storage_context("failed to generate asset URL")?;
|
||||
@@ -1135,6 +1138,14 @@ pub async fn get_document_asset(
|
||||
Ok(Json(to_asset_detail_response(asset, object_responses)))
|
||||
}
|
||||
|
||||
fn presign_disposition_for_asset(
|
||||
asset: &DocumentAsset,
|
||||
object: &DocumentAssetObject,
|
||||
) -> Option<String> {
|
||||
let filename = format!("{}-{}", asset.asset_type, object.ordinal);
|
||||
inline_content_disposition(&filename)
|
||||
}
|
||||
|
||||
#[utoipa::path(
|
||||
get,
|
||||
path = "/api/documents/{id}/versions",
|
||||
@@ -1271,6 +1282,7 @@ pub async fn download_with_token(
|
||||
.presign_get_object(
|
||||
&version.s3_key,
|
||||
Duration::from_secs(PRESIGNED_URL_EXPIRY_SECONDS),
|
||||
None,
|
||||
)
|
||||
.await
|
||||
.storage_context("failed to generate download URL")?;
|
||||
|
||||
@@ -320,6 +320,7 @@ async fn stream_document(
|
||||
.presign_get_object(
|
||||
&version.s3_key,
|
||||
Duration::from_secs(DOWNLOAD_URL_TTL_SECONDS),
|
||||
None,
|
||||
)
|
||||
.await
|
||||
.storage_context("failed to presign document download")?;
|
||||
|
||||
+27
-9
@@ -20,7 +20,12 @@ pub trait ObjectStorage: Send + Sync + 'static {
|
||||
content_disposition: Option<String>,
|
||||
) -> Result<()>;
|
||||
|
||||
async fn presign_get_object(&self, key: &str, expires_in: Duration) -> Result<String>;
|
||||
async fn presign_get_object(
|
||||
&self,
|
||||
key: &str,
|
||||
expires_in: Duration,
|
||||
response_content_disposition: Option<&str>,
|
||||
) -> Result<String>;
|
||||
|
||||
async fn get_object(&self, key: &str) -> Result<Vec<u8>>;
|
||||
|
||||
@@ -73,17 +78,23 @@ impl ObjectStorage for S3Storage {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn presign_get_object(&self, key: &str, expires_in: Duration) -> Result<String> {
|
||||
async fn presign_get_object(
|
||||
&self,
|
||||
key: &str,
|
||||
expires_in: Duration,
|
||||
response_content_disposition: Option<&str>,
|
||||
) -> Result<String> {
|
||||
let presign_config = PresigningConfig::builder()
|
||||
.expires_in(expires_in)
|
||||
.build()
|
||||
.context("failed to build S3 presigning config")?;
|
||||
|
||||
let presigned = self
|
||||
.client
|
||||
.get_object()
|
||||
.bucket(&self.bucket)
|
||||
.key(key)
|
||||
let mut request = self.client.get_object().bucket(&self.bucket).key(key);
|
||||
if let Some(value) = response_content_disposition {
|
||||
request = request.response_content_disposition(value);
|
||||
}
|
||||
|
||||
let presigned = request
|
||||
.presigned(presign_config)
|
||||
.await
|
||||
.context("failed to generate presigned download URL")?;
|
||||
@@ -157,9 +168,16 @@ impl TenantStorage {
|
||||
.await
|
||||
}
|
||||
|
||||
pub async fn presign_get_object(&self, key: &str, expires_in: Duration) -> Result<String> {
|
||||
pub async fn presign_get_object(
|
||||
&self,
|
||||
key: &str,
|
||||
expires_in: Duration,
|
||||
response_content_disposition: Option<&str>,
|
||||
) -> Result<String> {
|
||||
let qualified = self.qualify(key);
|
||||
self.inner.presign_get_object(&qualified, expires_in).await
|
||||
self.inner
|
||||
.presign_get_object(&qualified, expires_in, response_content_disposition)
|
||||
.await
|
||||
}
|
||||
|
||||
pub async fn get_object(&self, key: &str) -> Result<Vec<u8>> {
|
||||
|
||||
Reference in New Issue
Block a user