You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
63 lines
1.6 KiB
63 lines
1.6 KiB
# frozen_string_literal: true |
|
|
|
module Paperclip |
|
class ResponseWithLimitAdapter < AbstractAdapter |
|
def self.register |
|
Paperclip.io_adapters.register self do |target| |
|
target.is_a?(ResponseWithLimit) |
|
end |
|
end |
|
|
|
def initialize(target, options = {}) |
|
super |
|
cache_current_values |
|
end |
|
|
|
private |
|
|
|
def cache_current_values |
|
@target.response.require_limit_not_exceeded!(@target.limit) |
|
|
|
@original_filename = truncated_filename |
|
@tempfile = copy_to_tempfile(@target) |
|
@content_type = ContentTypeDetector.new(@tempfile.path).detect |
|
@size = File.size(@tempfile) |
|
end |
|
|
|
def copy_to_tempfile(source) |
|
bytes_read = 0 |
|
|
|
source.response.body.each do |chunk| |
|
bytes_read += chunk.bytesize |
|
raise Mastodon::LengthValidationError, "Body size exceeds limit of #{source.limit}" if bytes_read > source.limit |
|
|
|
destination.write(chunk) |
|
chunk.clear |
|
end |
|
|
|
destination.rewind |
|
destination |
|
rescue |
|
destination.close(true) |
|
raise |
|
ensure |
|
source.response.connection.close |
|
end |
|
|
|
def truncated_filename |
|
filename = filename_from_content_disposition.presence || filename_from_path.presence || 'data' |
|
extension = File.extname(filename) |
|
basename = File.basename(filename, extension) |
|
[basename[...20], extension[..4]].compact_blank.join |
|
end |
|
|
|
def filename_from_content_disposition |
|
disposition = @target.response.headers['content-disposition'] |
|
disposition&.match(/filename="([^"]*)"/)&.captures&.first |
|
end |
|
|
|
def filename_from_path |
|
@target.response.uri.path.split('/').last |
|
end |
|
end |
|
end
|
|
|