module DynamicImage::Controller

DynamicImage Controller

Generating images is rather expensive, so all requests must be signed with a HMAC digest in order to avoid denial of service attacks. The methods in DynamicImage::Helper handles this transparently. As a bonus, this also prevents unauthorized URL enumeration.

Public Instance Methods

download() click to toggle source
# File lib/dynamic_image/controller.rb, line 35
def download
  render_raw_image(disposition: "attachment")
end
original() click to toggle source

Renders the original image data, without any processing.

# File lib/dynamic_image/controller.rb, line 31
def original
  render_raw_image
end
requested_size() click to toggle source

Returns the requested size as a vector.

# File lib/dynamic_image/controller.rb, line 40
def requested_size
  Vector2d.parse(params[:size])
end
show() click to toggle source

Renders the image.

# File lib/dynamic_image/controller.rb, line 21
def show
  render_image(format: requested_format)
end
uncropped() click to toggle source

Same as show, but renders the image without any pre-cropping applied.

# File lib/dynamic_image/controller.rb, line 26
def uncropped
  render_image(format: requested_format, uncropped: true)
end

Private Instance Methods

cache_expiration_header() click to toggle source
# File lib/dynamic_image/controller.rb, line 46
def cache_expiration_header
  return unless response.status == 200

  response.headers["Cache-Control"] = "max-age=#{1.year}, public"
  expires_in 1.year, public: true
end
filename(format = nil) click to toggle source
# File lib/dynamic_image/controller.rb, line 57
def filename(format = nil)
  if format.is_a?(DynamicImage::Format)
    File.basename(@record.filename, ".*") + format.extension
  else
    filename(DynamicImage::Format.find(format) ||
             DynamicImage::Format.content_type(@record.content_type))
  end
end
find_record() click to toggle source
# File lib/dynamic_image/controller.rb, line 53
def find_record
  @record = model.find(params[:id])
end
process_and_send(image, options) click to toggle source
# File lib/dynamic_image/controller.rb, line 66
def process_and_send(image, options)
  processed_image = DynamicImage::ProcessedImage.new(image, options)
  send_data(processed_image.cropped_and_resized(requested_size),
            filename: filename(processed_image.format),
            content_type: processed_image.format.content_type,
            disposition: "inline")
end
render_image(options) click to toggle source
# File lib/dynamic_image/controller.rb, line 74
def render_image(options)
  return unless stale?(@record)

  respond_to do |format|
    format.html do
      render(template: "dynamic_image/images/show",
             layout: false, locals: { options: })
    end
    format.any(:gif, :jpeg, :jpg, :png, :tiff, :webp) do
      process_and_send(@record, options)
    end
  end
end
render_raw_image(disposition: "inline") click to toggle source
# File lib/dynamic_image/controller.rb, line 88
def render_raw_image(disposition: "inline")
  return unless stale?(@record)

  respond_to do |format|
    format.any(:gif, :jpeg, :jpg, :png, :tiff, :webp) do
      send_data(@record.data,
                filename:,
                content_type: @record.content_type,
                disposition:)
    end
  end
end
requested_format() click to toggle source
# File lib/dynamic_image/controller.rb, line 101
def requested_format
  params[:format]
end
verify_signed_params() click to toggle source
# File lib/dynamic_image/controller.rb, line 105
def verify_signed_params
  key = %i[action id size].map do |k|
    k == :id ? params.require(k).to_i : params.require(k)
  end.join("-")
  DynamicImage.digest_verifier.verify(key, params[:digest])
rescue ActionController::ParameterMissing => e
  raise DynamicImage::Errors::ParameterMissing, e.message
end