通过Paperclip 4连接时,在S3中设置内容类型?

时间:2022-10-05 21:07:53

I'm trying to attach CSV files to a Rails3 model using paperclip 4.1.1, but I'm having trouble getting the content-type as reported by S3 to be text/csv (instead I am getting text/plain). When I subsequently download the file from S3, the extension is getting changed to match the content-type instead of preserving the original extension (so test.csv is downloaded as test.txt).

我正在尝试使用paperclip 4.1.1将CSV文件附加到Rails3模型,但是我无法将S3报告的内容类型变为text / csv(而是我得到text / plain)。当我随后从S3下载文件时,扩展名将更改为与内容类型匹配,而不是保留原始扩展名(因此test.csv将作为test.txt下载)。

From what I can see, when you upload a file, the FileAdapter will cache the content-type on creation with whatever value was determined by the ContentTypeDetector (which calls file -b --mime filename). Unfortunately, CSV files return text/plain which makes sense, as how can you really distinguish this? Attempts to set the content-type with attachment.instance_write(:content_type, 'text/csv') only set the value in the model and do not affect what gets written to S3.

从我所看到的,当您上传文件时,FileAdapter将使用ContentTypeDetector(调用文件-b --mime文件名)确定的任何值来缓存创建时的内容类型。不幸的是,CSV文件返回text / plain是有意义的,你怎么能真正区分它呢?尝试使用attachment.instance_write(:content_type,'text / csv')设置内容类型只会在模型中设置值,而不会影响写入S3的内容。

FileAdapter's content_type initialized here: https://github.com/thoughtbot/paperclip/blob/v4.0/lib/paperclip/io_adapters/file_adapter.rb#L14

FileAdapter的content_type在这里初始化:https://github.com/thoughtbot/paperclip/blob/v4.0/lib/paperclip/io_adapters/file_adapter.rb#L14

Call which creates that io_adapter: https://github.com/thoughtbot/paperclip/blob/v4.0/lib/paperclip/attachment.rb#L98

创建io_adapter的调用:https://github.com/thoughtbot/paperclip/blob/v4.0/lib/paperclip/attachment.rb#L98

I really have a generic upload here (so I can't hard-code the content type in the S3 headers definition in has_attached_file), and I don't really want the content-type spoofing protection. Any ideas/suggestions? I would prefer not to downgrade to 3.5 because it would mean just delaying the pain, but if that's the only way, I'll entertain it...

我真的有一个通用的上传(所以我不能硬编码has_attached_file中S3头定义中的内容类型),我真的不想要内容类型的欺骗保护。有什么想法/建议吗?我宁愿不降级到3.5,因为这只会拖延痛苦,但如果这是唯一的方法,我会接受它......

1 个解决方案

#1


7  

If you are using fog then you can do something like this:

如果你使用雾,那么你可以这样做:

has_attached_file :report,
  fog_file: lambda { |attachment|
    {
      content_type: 'text/csv',
      content_disposition: "attachment; filename=#{attachment.original_filename}",
    }
  }

If you are using Amazon S3 as your storage provider, then something like this should work:

如果您使用Amazon S3作为存储提供商,那么这样的事情应该有效:

has_attached_file :report
  s3_headers: lambda { |attachment|
    { 
      'Content-Type' => 'text/csv',
      'Content-Disposition' => "attachment; filename=#{attachment.original_filename}",
    }
  }

#1


7  

If you are using fog then you can do something like this:

如果你使用雾,那么你可以这样做:

has_attached_file :report,
  fog_file: lambda { |attachment|
    {
      content_type: 'text/csv',
      content_disposition: "attachment; filename=#{attachment.original_filename}",
    }
  }

If you are using Amazon S3 as your storage provider, then something like this should work:

如果您使用Amazon S3作为存储提供商,那么这样的事情应该有效:

has_attached_file :report
  s3_headers: lambda { |attachment|
    { 
      'Content-Type' => 'text/csv',
      'Content-Disposition' => "attachment; filename=#{attachment.original_filename}",
    }
  }