diff --git a/lib/marcel/mime_type.rb b/lib/marcel/mime_type.rb index 6d7c15e..23da698 100644 --- a/lib/marcel/mime_type.rb +++ b/lib/marcel/mime_type.rb @@ -60,7 +60,12 @@ def for_extension(extension) end def for_declared_type(declared_type) - parse_media_type(declared_type) + type = parse_media_type(declared_type) + + # application/octet-stream is treated as an undeclared/missing type, + # allowing the type to be inferred from the filename. If there's no + # filename extension, then the type falls back to binary anyway. + type unless type == BINARY end def with_io(pathname_or_io, &block) diff --git a/test/declared_type_test.rb b/test/declared_type_test.rb index d5de3d0..d1feeac 100644 --- a/test/declared_type_test.rb +++ b/test/declared_type_test.rb @@ -2,11 +2,16 @@ require 'rack' class Marcel::MimeType::DeclaredTypeTest < Marcel::TestCase - test "returns declared type as last resort" do - assert_equal "text/html", Marcel::MimeType.for(name: "unrecognisable", declared_type: "text/html") + test "prefers declared type over filename extension" do + assert_equal "text/html", Marcel::MimeType.for(name: "file.txt", declared_type: "text/html") end - test "returns application/octet-stream if declared type empty or unrecognised" do + test "prefers filename extension over binary type" do + assert_equal "text/plain", Marcel::MimeType.for(name: "file.txt", declared_type: "application/octet-stream") + end + + test "defaults to binary if declared type is unrecognized" do + assert_equal "application/octet-stream", Marcel::MimeType.for(declared_type: nil) assert_equal "application/octet-stream", Marcel::MimeType.for(declared_type: "") assert_equal "application/octet-stream", Marcel::MimeType.for(declared_type: "unrecognised") end