【问题标题】:Carrierwave sets mime type to invalid/invalidCarrierwave 将 mime 类型设置为无效/无效
【发布时间】:2021-02-27 17:43:32
【问题描述】:

我最近从 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 作为依赖项有关?

【问题讨论】:

    标签: ruby-on-rails ruby mime-types carrierwave


    【解决方案1】:

    使用 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/

    【讨论】:

      【解决方案2】:

      看来问题找到了。

      在之前的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 之后有“无效/无效”内容类型,这似乎无法使用“MimeMagic.by_magic”获取文件类型。

      PS 我看到为通常的 css 文件返回了“纯文本”内容类型。 https://github.com/minad/mimemagic/blob/master/lib/mimemagic/tables.rb#L1506

      【讨论】:

        猜你喜欢
        • 2016-01-11
        • 1970-01-01
        • 1970-01-01
        • 2019-03-23
        • 1970-01-01
        • 2012-01-05
        • 1970-01-01
        • 1970-01-01
        • 2019-03-29
        相关资源
        最近更新 更多