Skip to content

Commit

Permalink
feat: [torrust#483] allow upload torrent with application/octet-stream
Browse files Browse the repository at this point in the history
HTTP header Content-Type.

Some users are having problems uploading torrents becuase the client
(browser or other clients) use the HTTP header Contetnt-Type:

`application/octet-stream`

instead of:

`application/x-bittorrent`

It seems that the reason is they don't have any application associated
to that extension. So it uses the generic binary file mime type.

The MIME type can be inferred from the file extension. If the system or application uploading the file has a specific association for .torrent files, it might set the MIME type to application/x-bittorrent. In the absence of such association, it might fall back to the generic application/octet-stream.
  • Loading branch information
josecelano committed Feb 22, 2024
1 parent f7c1aab commit 8a97b5b
Show file tree
Hide file tree
Showing 4 changed files with 22 additions and 5 deletions.
10 changes: 9 additions & 1 deletion src/web/api/client/v1/responses.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ impl BinaryResponse {

#[must_use]
pub fn is_a_bit_torrent_file(&self) -> bool {
self.is_ok() && self.is_bittorrent_content_type()
self.is_ok() && (self.is_bittorrent_content_type() || self.is_octet_stream_content_type())
}

#[must_use]
Expand All @@ -82,6 +82,14 @@ impl BinaryResponse {
false
}

#[must_use]
pub fn is_octet_stream_content_type(&self) -> bool {
if let Some(content_type) = &self.content_type {
return content_type == "application/octet-stream";
}
false
}

#[must_use]
pub fn is_ok(&self) -> bool {
self.status == 200
Expand Down
4 changes: 3 additions & 1 deletion src/web/api/server/v1/contexts/torrent/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@ pub enum Request {
#[display(fmt = "torrent tags string is not a valid JSON.")]
TagsArrayIsNotValidJson,

#[display(fmt = "upload torrent request header `content-type` should be `application/x-bittorrent`.")]
#[display(
fmt = "upload torrent request header `content-type` should be preferably `application/x-bittorrent` or `application/octet-stream`."
)]
InvalidFileType,

#[display(fmt = "cannot write uploaded torrent bytes (binary file) into memory.")]
Expand Down
4 changes: 2 additions & 2 deletions src/web/api/server/v1/contexts/torrent/handlers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -301,7 +301,7 @@ pub async fn create_random_torrent_handler(State(_app_data): State<Arc<AppData>>
///
/// - The text fields do not contain a valid UTF8 string.
/// - The torrent file data is not valid because:
/// - The content type is not `application/x-bittorrent`.
/// - The content type is not `application/x-bittorrent` or `application/octet-stream`.
/// - The multipart content is invalid.
/// - The torrent file pieces key has a length that is not a multiple of 20.
/// - The binary data cannot be decoded as a torrent file.
Expand Down Expand Up @@ -350,7 +350,7 @@ async fn build_add_torrent_request_from_payload(mut payload: Multipart) -> Resul
"torrent" => {
let content_type = field.content_type().unwrap();

if content_type != "application/x-bittorrent" {
if content_type != "application/x-bittorrent" && content_type != "application/octet-stream" {
return Err(errors::Request::InvalidFileType);
}

Expand Down
9 changes: 8 additions & 1 deletion tests/common/responses.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ impl BinaryResponse {
}
}
pub fn is_a_bit_torrent_file(&self) -> bool {
self.is_ok() && self.is_bittorrent_content_type()
self.is_ok() && (self.is_bittorrent_content_type() || self.is_octet_stream_content_type())
}

pub fn is_bittorrent_content_type(&self) -> bool {
Expand All @@ -64,6 +64,13 @@ impl BinaryResponse {
false
}

pub fn is_octet_stream_content_type(&self) -> bool {
if let Some(content_type) = &self.content_type {
return content_type == "application/octet-stream";
}
false
}

pub fn is_ok(&self) -> bool {
self.status == 200
}
Expand Down

0 comments on commit 8a97b5b

Please sign in to comment.