Created
March 15, 2015 02:58
-
-
Save cnk/4453c6e81837e8d38b7e to your computer and use it in GitHub Desktop.
Work around for files getting uploaded as application/octet-stream
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class ApplicationController < ActionController::Base | |
# omitted stuff | |
private | |
# Used to correct content type for files uploaded with bulkupload or from PicMonkey | |
def correct_content_type_for_octet_stream(filedata) | |
return nil if filedata.blank? | |
# see what the unix file command thinks this is | |
if filedata.content_type == 'application/octet-stream' | |
filedata.content_type = type_from_file_command(filedata.path) | |
end | |
# 'file' thinks new Office docs are zip files, so we may need to correct what we just did above | |
if filedata.content_type =~ /application\/(x-)?zip/ | |
filedata.content_type = type_from_file_extension(filedata.original_filename) | |
end | |
filedata | |
end | |
def type_from_file_command(file) | |
Paperclip::FileCommandContentTypeDetector.new(file).detect | |
end | |
def type_from_file_extension(filename) | |
Paperclip::ContentTypeDetector.new(filename).send(:possible_types).first | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class DocumentsController < ApplicationController | |
before_action :set_document, only: [:edit, :update, :destroy] | |
# .... omitted | |
# POST /documents | |
def create | |
@document = Document.new(document_params) | |
@document.file = correct_content_type_for_octet_stream(params[:document][:file]) | |
if @document.save | |
redirect_to document_category_path(id: @document.document_category_id), notice: 'Document was successfully created.' | |
else | |
render :new | |
end | |
end | |
# PUT /documents/1 | |
def update | |
@document.file = correct_content_type_for_octet_stream(params[:document][:file]) unless params[:document][:file].blank? | |
if @document.update_attributes(document_params) | |
redirect_to document_path(@document), notice: 'Document was successfully updated.' | |
else | |
render :edit | |
end | |
end | |
private | |
# Use callbacks to share common setup or constraints between actions. | |
def set_document | |
@document = Document.find(params[:id]) | |
end | |
# Only allow a trusted parameter "white list" through. | |
def document_params | |
params.require(:document).permit(:document_category_id, :campus_only, :login_only) | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Document < ActiveRecord::Base | |
belongs_to :category, :class_name => 'DocumentCategory', :foreign_key => 'document_category_id' | |
# Store documents in S3 - one bucket for all CMS instances - subfolders for each site | |
has_attached_file :file, | |
:storage => :s3, | |
:s3_credentials => "#{Rails.root}/config/amazon_s3.yml", | |
:s3_permissions => "authenticated-read", | |
:path => "#{SiteConfig.hostname}/:class/:id_partition/:filename", | |
:filename_cleaner => PaperclipModifications::FilenameCleaner.new | |
validates_attachment :file, :presence => true, :size => { :less_than => 100.megabytes }, | |
:content_type => { :content_type => [/\Aimage\/.*\Z/, /\Aapplication\/.*\Z/, /\Atext\/.*\Z/]} | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Allow type mismatch for Office documents - our version of `file` calls all of them zip files | |
if Object::RUBY_PLATFORM =~ /darwin/ | |
Paperclip.options[:content_type_mappings] = { | |
:docx => "application/zip", | |
:xlsx => "application/zip", | |
:pptx => "application/zip", | |
:pages => "application/zip", | |
:numbers => "application/zip", | |
:key => "application/zip" | |
} | |
else | |
Paperclip.options[:content_type_mappings] = { | |
:docx => "application/x-zip", | |
:xlsx => "application/x-zip", | |
:pptx => "application/x-zip", | |
:pages => "application/x-zip", | |
:numbers => "application/x-zip", | |
:key => "application/x-zip" | |
} | |
end | |
module Paperclip | |
class MediaTypeSpoofDetector | |
# Make spoof detection stricter - original only compared type so all 'application' types matched all others | |
def media_type_mismatch? | |
! supplied_file_content_types.include?(calculated_content_type) | |
end | |
end | |
end | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment