Carrierwave 将 mime 类型设置为 invalid/invalid
Carrierwave sets mime type to invalid/invalid
我最近从 Carrierwave 1.3 升级到 2.1,由于无效的 MIME 类型,我有几个规范失败了。
我存储在数据库中,CSV 上传,如果 mime 类型是 text/csv
,我在模型上验证。
validates :file, presence: true, file_content_type: {
allow: [
'text/csv',
'application/vnd.ms-excel',
'application/vnd.ms-office',
'application/octet-stream',
'text/comma-separated-values'
]
}
根据规范,我创建了一个夹具
let(:file) { fixture_file_upload('files/fixture.csv', 'text/csv') }
当我调试时,
@file=
#<CarrierWave::SanitizedFile:0x00007f8c731791f0
@content=nil,
@content_type="invalid/invalid",
@file="/Users/tiagovieira/code/work/tpc/public/uploads/csv_file_upload/file/1/1605532759-308056149220914-0040-7268/fixture.csv",
@original_filename="fixture.csv">,
@filename="fixture.csv",
@identifier="fixture.csv",
这是否与 carrierwave 停止使用 mime-types
gem 作为依赖项有关?
使用Rack::Test::UploadedFile
为安装的模型分配一个 Rack::Test::UploadedFile 对象
假设您的模型是:
class User < ApplicationRecord
mount_uploader :file, FileUploader
end
要测试上传器,您可以使用类似的东西:
user.file = Rack::Test::UploadedFile.new(File.open('test_file.csv'), "text/csv")
user.save
Carrierwave 的 content_type_whitelist 或 extension_whitelist
的白名单
class FileUploader < CarrierWave::Uploader::Base
private
def extension_whitelist
%w(csv xlsx xls)
end
def content_type_whitelist
[
'text/csv',
'application/vnd.ms-excel',
'application/vnd.ms-office',
'application/octet-stream',
'text/comma-separated-values'
]
end
end
同时检查:
https://til.codes/testing-carrierwave-file-uploads-with-rspec-and-factorygirl/
看来问题找到了。
在之前的carrierwave版本中“CarrierWave::SanitizedFile”content_type是通过扩展计算的
https://github.com/carrierwaveuploader/carrierwave/blob/1.x-stable/lib/carrierwave/sanitized_file.rb
def content_type
return @content_type if @content_type
if @file.respond_to?(:content_type) and @file.content_type
@content_type = @file.content_type.to_s.chomp
elsif path
@content_type = ::MIME::Types.type_for(path).first.to_s
end
end
而且现在有更复杂的方式。它使用算法根据此文件包含的数据来识别文件类型。
https://github.com/carrierwaveuploader/carrierwave/blob/master/lib/carrierwave/sanitized_file.rb
def content_type
@content_type ||=
existing_content_type ||
mime_magic_content_type ||
mini_mime_content_type
end
我在 mime_magic_content_type
之后有“invalid/invalid”内容类型,似乎无法使用“MimeMagic.by_magic”获取文件类型。
PS 我看到通常的 css 文件返回“plain/text”content_type。
https://github.com/minad/mimemagic/blob/master/lib/mimemagic/tables.rb#L1506
我最近从 Carrierwave 1.3 升级到 2.1,由于无效的 MIME 类型,我有几个规范失败了。
我存储在数据库中,CSV 上传,如果 mime 类型是 text/csv
,我在模型上验证。
validates :file, presence: true, file_content_type: {
allow: [
'text/csv',
'application/vnd.ms-excel',
'application/vnd.ms-office',
'application/octet-stream',
'text/comma-separated-values'
]
}
根据规范,我创建了一个夹具
let(:file) { fixture_file_upload('files/fixture.csv', 'text/csv') }
当我调试时,
@file=
#<CarrierWave::SanitizedFile:0x00007f8c731791f0
@content=nil,
@content_type="invalid/invalid",
@file="/Users/tiagovieira/code/work/tpc/public/uploads/csv_file_upload/file/1/1605532759-308056149220914-0040-7268/fixture.csv",
@original_filename="fixture.csv">,
@filename="fixture.csv",
@identifier="fixture.csv",
这是否与 carrierwave 停止使用 mime-types
gem 作为依赖项有关?
使用Rack::Test::UploadedFile
为安装的模型分配一个 Rack::Test::UploadedFile 对象 假设您的模型是:
class User < ApplicationRecord
mount_uploader :file, FileUploader
end
要测试上传器,您可以使用类似的东西:
user.file = Rack::Test::UploadedFile.new(File.open('test_file.csv'), "text/csv")
user.save
Carrierwave 的 content_type_whitelist 或 extension_whitelist
的白名单class FileUploader < CarrierWave::Uploader::Base
private
def extension_whitelist
%w(csv xlsx xls)
end
def content_type_whitelist
[
'text/csv',
'application/vnd.ms-excel',
'application/vnd.ms-office',
'application/octet-stream',
'text/comma-separated-values'
]
end
end
同时检查: https://til.codes/testing-carrierwave-file-uploads-with-rspec-and-factorygirl/
看来问题找到了。
在之前的carrierwave版本中“CarrierWave::SanitizedFile”content_type是通过扩展计算的 https://github.com/carrierwaveuploader/carrierwave/blob/1.x-stable/lib/carrierwave/sanitized_file.rb
def content_type
return @content_type if @content_type
if @file.respond_to?(:content_type) and @file.content_type
@content_type = @file.content_type.to_s.chomp
elsif path
@content_type = ::MIME::Types.type_for(path).first.to_s
end
end
而且现在有更复杂的方式。它使用算法根据此文件包含的数据来识别文件类型。
https://github.com/carrierwaveuploader/carrierwave/blob/master/lib/carrierwave/sanitized_file.rb
def content_type
@content_type ||=
existing_content_type ||
mime_magic_content_type ||
mini_mime_content_type
end
我在 mime_magic_content_type
之后有“invalid/invalid”内容类型,似乎无法使用“MimeMagic.by_magic”获取文件类型。
PS 我看到通常的 css 文件返回“plain/text”content_type。 https://github.com/minad/mimemagic/blob/master/lib/mimemagic/tables.rb#L1506