From 9f312ca1e14d05e5d5942915774fb809f3fca67a Mon Sep 17 00:00:00 2001 From: sychic <47618543+Sychic@users.noreply.github.com> Date: Sat, 20 Jun 2026 23:27:10 -0400 Subject: [PATCH 1/2] fix(maven): return requested file extension closes #2428, #2663 why was this hard coded lol --- apps/labrinth/src/routes/maven.rs | 24 +++++++----------------- 1 file changed, 7 insertions(+), 17 deletions(-) diff --git a/apps/labrinth/src/routes/maven.rs b/apps/labrinth/src/routes/maven.rs index b9bc10d779..cf0525a55f 100644 --- a/apps/labrinth/src/routes/maven.rs +++ b/apps/labrinth/src/routes/maven.rs @@ -250,29 +250,19 @@ fn find_file<'a>( return Some(selected_file); } - // Minecraft mods are not going to be both a mod and a modpack, so this minecraft-specific handling is fine - // As there can be multiple project types, returns the first allowable match - let mut fileexts = vec![]; - for project_type in &version.project_types { - match project_type.as_str() { - "mod" => fileexts.push("jar"), - "modpack" => fileexts.push("mrpack"), - _ => (), - } - } - - for fileext in fileexts { - if file.eq_ignore_ascii_case(&format!( - "{}-{}.{}", - &project_id, &vcoords, fileext - )) { + if let Some((file_name, desired_file_ext)) = file.rsplit_once('.') { + if file_name + .eq_ignore_ascii_case(&format!("{}-{}", &project_id, &vcoords)) + { return version .files .iter() + .filter(|x| x.filename.ends_with(desired_file_ext)) .find(|x| x.primary) .or_else(|| version.files.iter().last()); } - } + }; + None } From 2adcdfe8ba5e1abe733239d29a693e29f8879ecc Mon Sep 17 00:00:00 2001 From: sychic <47618543+Sychic@users.noreply.github.com> Date: Sun, 21 Jun 2026 01:20:37 -0400 Subject: [PATCH 2/2] fix(maven): handle other file types properly --- apps/labrinth/src/routes/maven.rs | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/apps/labrinth/src/routes/maven.rs b/apps/labrinth/src/routes/maven.rs index cf0525a55f..41757641cc 100644 --- a/apps/labrinth/src/routes/maven.rs +++ b/apps/labrinth/src/routes/maven.rs @@ -9,6 +9,7 @@ use crate::database::models::version_item::{ use crate::database::redis::RedisPool; use crate::models::ids::{ProjectId, VersionId}; use crate::models::pats::Scopes; +use crate::models::projects::FileType; use crate::queue::session::AuthQueue; use crate::routes::ApiError; use crate::{auth::get_user_from_headers, database}; @@ -251,15 +252,27 @@ fn find_file<'a>( } if let Some((file_name, desired_file_ext)) = file.rsplit_once('.') { - if file_name - .eq_ignore_ascii_case(&format!("{}-{}", &project_id, &vcoords)) - { - return version - .files - .iter() - .filter(|x| x.filename.ends_with(desired_file_ext)) + let formatted_name = format!("{}-{}", &project_id, &vcoords); + let mut filtered_files = version + .files + .iter() + .filter(|x| x.filename.ends_with(desired_file_ext)); + + if file_name.eq_ignore_ascii_case(&formatted_name) { + return filtered_files .find(|x| x.primary) - .or_else(|| version.files.iter().last()); + .or_else(|| filtered_files.next_back()); + } else if file_name.len() > formatted_name.len() + && file_name.as_bytes()[..formatted_name.len()] + .eq_ignore_ascii_case(formatted_name.as_bytes()) + { + let desired_file_type = FileType::from_string(&format!( + "{}-{}", + &file_name[formatted_name.len()..].trim_start_matches('-'), + desired_file_ext + )); + return filtered_files + .find(|x| x.file_type == Some(desired_file_type)); } };