Skip to content
Clone
a06673b
51 lines 1.6 KB Rust
use axum::body::Bytes;
use axum::extract::{Path, Query, State};
use axum::http::header;
use axum::http::{HeaderValue, StatusCode};
use axum::response::{IntoResponse, Response};
use jwt::extractor::AuthUser;
use uuid::Uuid;
use crate::error::RepoResult;
use crate::features::RepoService;
use crate::features::archive::ArchiveFormatQuery;
#[utoipa::path(
get,
path = "/repo/{channel_id}/{repo_id}/archive/{archive_format}/{ref_name}",
tag = "repo",
params(ArchiveFormatQuery),
responses((status = 200, description = "Download an archive")),
security(("bearer_auth" = []))
)]
pub(crate) async fn handler(
State(svc): State<RepoService>,
AuthUser { claims }: AuthUser,
Path((_, repo_id, archive_format, ref_name)): Path<(Uuid, Uuid, String, String)>,
Query(q): Query<ArchiveFormatQuery>,
) -> RepoResult<Response> {
let bytes = svc
.get_archive(claims.sub, repo_id, &archive_format, &ref_name, q)
.await?;
let mime = match archive_format.as_str() {
"zipball" => "application/zip",
"tarball" | "bundle" => "application/x-tar",
_ => "application/octet-stream",
};
let resp = (
StatusCode::OK,
[
(header::CONTENT_TYPE, HeaderValue::from_static(mime)),
(
header::CONTENT_DISPOSITION,
HeaderValue::from_str(&format!(
"attachment; filename=\"{ref_name}.{archive_format}\""
))
.unwrap_or(HeaderValue::from_static("attachment")),
),
],
Bytes::from(bytes),
)
.into_response();
Ok(resp)
}