fedibird-fe/app/models/preview_card.rb
Akihiko Odaki 40e5d2303b Validate HTTP response length while receiving (#6891)
to_s method of HTTP::Response keeps blocking while it receives the whole
content, no matter how it is big. This means it may waste time to receive
unacceptably large files. It may also consume memory and disk in the
process. This solves the inefficency by checking response length while
receiving.
2018-03-26 14:02:10 +02:00

69 lines
2.1 KiB
Ruby

# frozen_string_literal: true
# == Schema Information
#
# Table name: preview_cards
#
# id :integer not null, primary key
# url :string default(""), not null
# title :string default(""), not null
# description :string default(""), not null
# image_file_name :string
# image_content_type :string
# image_file_size :integer
# image_updated_at :datetime
# type :integer default("link"), not null
# html :text default(""), not null
# author_name :string default(""), not null
# author_url :string default(""), not null
# provider_name :string default(""), not null
# provider_url :string default(""), not null
# width :integer default(0), not null
# height :integer default(0), not null
# created_at :datetime not null
# updated_at :datetime not null
# embed_url :string default(""), not null
#
class PreviewCard < ApplicationRecord
IMAGE_MIME_TYPES = ['image/jpeg', 'image/png', 'image/gif'].freeze
LIMIT = 1.megabytes
self.inheritance_column = false
enum type: [:link, :photo, :video, :rich]
has_and_belongs_to_many :statuses
has_attached_file :image, styles: { original: { geometry: '400x400>', file_geometry_parser: FastGeometryParser } }, convert_options: { all: '-quality 80 -strip' }
include Attachmentable
validates :url, presence: true, uniqueness: true
validates_attachment_content_type :image, content_type: IMAGE_MIME_TYPES
validates_attachment_size :image, less_than: LIMIT
remotable_attachment :image, LIMIT
before_save :extract_dimensions, if: :link?
def save_with_optional_image!
save!
rescue ActiveRecord::RecordInvalid
self.image = nil
save!
end
private
def extract_dimensions
file = image.queued_for_write[:original]
return if file.nil?
width, height = FastImage.size(file.path)
return nil if width.nil?
self.width = width
self.height = height
end
end