diff --git a/src/web/api/v1/contexts/torrent/handlers.rs b/src/web/api/v1/contexts/torrent/handlers.rs index 724821e1..2621ff9c 100644 --- a/src/web/api/v1/contexts/torrent/handlers.rs +++ b/src/web/api/v1/contexts/torrent/handlers.rs @@ -94,7 +94,7 @@ pub async fn download_torrent_handler( return ServiceError::InternalServerError.into_response(); }; - torrent_file_response(bytes, &format!("{}.torrent", torrent.info.name)) + torrent_file_response(bytes, &format!("{}.torrent", torrent.info.name), &torrent.info_hash()) } /// It returns a list of torrents matching the search criteria. @@ -244,7 +244,7 @@ pub async fn create_random_torrent_handler(State(_app_data): State> return ServiceError::InternalServerError.into_response(); }; - torrent_file_response(bytes, &format!("{}.torrent", torrent.info.name)) + torrent_file_response(bytes, &format!("{}.torrent", torrent.info.name), &torrent.info_hash()) } /// Extracts the [`TorrentRequest`] from the multipart form payload. diff --git a/src/web/api/v1/contexts/torrent/responses.rs b/src/web/api/v1/contexts/torrent/responses.rs index be5e50f5..33ec2a19 100644 --- a/src/web/api/v1/contexts/torrent/responses.rs +++ b/src/web/api/v1/contexts/torrent/responses.rs @@ -1,6 +1,6 @@ use axum::response::{IntoResponse, Response}; use axum::Json; -use hyper::{header, StatusCode}; +use hyper::{header, HeaderMap, StatusCode}; use serde::{Deserialize, Serialize}; use crate::models::torrent::TorrentId; @@ -23,15 +23,33 @@ pub fn new_torrent_response(torrent_id: TorrentId, info_hash: &str) -> Json, filename: &str) -> Response { - ( - StatusCode::OK, - [ - (header::CONTENT_TYPE, "application/x-bittorrent"), - (header::CONTENT_DISPOSITION, &format!("attachment; filename={filename}")), - ], - bytes, - ) - .into_response() +pub fn torrent_file_response(bytes: Vec, filename: &str, info_hash: &str) -> Response { + let mut headers = HeaderMap::new(); + headers.insert( + header::CONTENT_TYPE, + "application/x-bittorrent" + .parse() + .expect("HTTP content type header should be valid"), + ); + headers.insert( + header::CONTENT_DISPOSITION, + format!("attachment; filename={filename}") + .parse() + .expect("Torrent filename should be a valid header value for the content disposition header"), + ); + headers.insert( + "x-torrust-torrent-infohash", + info_hash + .parse() + .expect("Torrent infohash should be a valid header value for the content disposition header"), + ); + + (StatusCode::OK, headers, bytes).into_response() }