class DynamicPaperclip::AttachmentStyleGenerator

Public Instance Methods

call(env) click to toggle source
# File lib/dynamic_paperclip_patch.rb, line 43
def call(env)
  request = Rack::Request.new(env)

  DynamicPaperclip::AttachmentRegistry.each_definition do |klass, name, options|
    if match = regexp_for_attachment_url(klass, (options[:url] || Attachment.default_options[:url])).match(request.path)
      id = id_from_partition(match[:id])
      attachment = klass.find(id).send(name)

      # iXmedia
      # Fix to avoid error: uninitialized constant ActionController::DataStreaming::FileBody
      # When the filename is wrong
      # Return a 404 instead
      if !attachment.exists? || attachment.original_filename != URI.unescape(match[:filename])
        return [404, {}, []]
      end

      # The definition will be escaped twice in the URL, so we need to unescape it once.
      # We should always reference dynamic style names after escaping once - that's how they reside on the FS.
      style_name = StyleNaming.dynamic_style_name_from_definition(CGI.unescape(match[:definition]), false)

      # Validate URL hash against requested style name
      if DynamicPaperclip::UrlSecurity.valid_hash?(request.params['s'], style_name)

        # Only process style if it doesn't exist,
        # otherwise we may just be fielding a request for
        # an existing style
        attachment.process_dynamic_style style_name unless attachment.exists?(style_name)

        return [
          200,
          {
            'Content-Type' => attachment.content_type,
            'Content-Transfer-Encoding' => 'binary',
            'Content-Disposition' => "inline; filename=#{File.basename(attachment.path(style_name))}"
          },
          ActionDispatch::Response::FileBody.new(attachment.path(style_name))
        ]
      else
        # Invalid hash, just 403

        return [403, {}, []]
      end
    end
  end

  @app.call env
end