问题
In rails 4.0.2, I am using paperclip gem to upload files. But it is not supporting .doc file. Below the file upload field, it is showing an error message as "has an extension that does not match its contents"
In model, the validation for checking the content type is given below :
validates_attachment_content_type :document, :content_type => ['application/txt', 'text/plain',
'application/pdf', 'application/msword',
'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
'application/vnd.oasis.opendocument.text',
'application/x-vnd.oasis.opendocument.text',
'application/rtf', 'application/x-rtf', 'text/rtf',
'text/richtext', 'application/doc', 'application/docx', 'application/x-soffice', 'application/octet-stream']
Gems which is used right now
rails (4.0.2, 4.0.0, 3.2.13, 3.2.8, 3.0.4, 3.0.3)
paperclip (3.5.2, 2.3.11, 2.3.8)
How can I solve this issue?
回答1:
add this to an initializer to disable spoofing protection:
require 'paperclip/media_type_spoof_detector'
module Paperclip
class MediaTypeSpoofDetector
def spoofed?
false
end
end
end
For centOS
module Paperclip
class MediaTypeSpoofDetector
def type_from_file_command
begin
Paperclip.run("file", "-b --mime :file", :file => @file.path)
rescue Cocaine::CommandLineError
""
end
end
end
end
from https://github.com/thoughtbot/paperclip/issues/1429
回答2:
It's a bad idea to skip spoofing checking. Because Paperclip adds it for security reason. See this article for details: http://robots.thoughtbot.com/prevent-spoofing-with-paperclip
The spoof validation checks if file's extension matches it's mime type. For example a txt
file's mime type is text/plain
, when you upload it to Paperclip everything goes fine. But if you modify the extension to jpg
then upload it, the validation fails because jpg
file's mime type should be image/jpeg
.
Note that this validation is for security checking so there's not a normal way to skip it. Even when you use do_not_validate_attachment_file_type
it's not skipped. But for some files Paperclip can't recognize file -> mime type mapping correctly.
In this case the right way is adding content type mapping to Paperclip configuration. Like this:
# Add it to initializer
Paperclip.options[:content_type_mappings] = {
pem: 'text/plain'
}
In this way it works without breaking spoofing validation. If you don't know what mime type a file is, you can use file
command:
file -b --mime-type some_file.pdf # -> application/pdf
回答3:
The error in the server log means that your OS file
command cannot get you the MIME type for a .doc file. This happens for me with ubuntu 12.04.
To get around this, I slightly altered MediaTypeSpoofDetector
to use mimetype
if file --mime
didn't work.
module Paperclip
class MediaTypeSpoofDetector
private
def type_from_file_command
# -- original code removed --
# begin
# Paperclip.run("file", "-b --mime-type :file", :file => @file.path)
# rescue Cocaine::CommandLineError
# ""
# end
# -- new code follows --
file_type = ''
begin
file_type = Paperclip.run('file', '-b --mime-type :file', file: @file.path)
rescue Cocaine::CommandLineError
file_type = ''
end
if file_type == ''
begin
file_type = Paperclip.run('mimetype', '-b :file', file: @file.path)
rescue Cocaine::CommandLineError
file_type = ''
end
end
file_type
end
end
end
回答4:
You can authorize all content types using do_not_validate_attachment_file_type :file
You can enable spoofing using has_attached_file :file,
class Upload
#validate_media_type == false means "authorize spoofing"
has_attached_file :file, validate_media_type: false
#authorize all content types
do_not_validate_attachment_file_type :file_if_content_type_missing
end
回答5:
Try putting do_not_validate_attachment_file_type :document
validation in model.
来源:https://stackoverflow.com/questions/22527092/paperclip-is-not-supporting-doc-file