Class: DynamicPaperclip::AttachmentStyleGenerator

Inherits:
Object
  • Object
show all
Defined in:
lib/dynamic_paperclip/attachment_style_generator.rb

Instance Method Summary collapse

Constructor Details

#initialize(app) ⇒ AttachmentStyleGenerator

Rack middleware that catches requests for dynamic attachment styles that have not yet been generated and generates them.



11
12
13
# File 'lib/dynamic_paperclip/attachment_style_generator.rb', line 11

def initialize(app)
  @app = app
end

Instance Method Details

#call(env) ⇒ Object



15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
# File 'lib/dynamic_paperclip/attachment_style_generator.rb', line 15

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)

      # 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)

        # The FileBody class has been moved to another module in Rails 5
        file_body = defined?(ActionController::DataStreaming::FileBody) ? ActionController::DataStreaming::FileBody : ActionDispatch::Response::FileBody

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

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

  @app.call env
end