class PhotoCook::Resize::Middleware
Attributes
headers[RW]
Public Class Methods
new(app)
click to toggle source
# File lib/photo-cook/resize/middleware.rb, line 13 def initialize(app) @app = app end
Public Instance Methods
call(env)
click to toggle source
Consider we have car.png in /uploads/photos/1/car.png We want to resize it with the following params:
Width: choose automatically Height: exactly 640px Mode: fill
Middleware
will handle this URI:
/uploads/photos/1/resized/width=auto&height=640&mode=fill/car.png
# File lib/photo-cook/resize/middleware.rb, line 26 def call(env) uri = extract_uri(env) # Check if URI contains PhotoCook resize indicators return default_action(env) unless Assemble.resize_uri?(uri) # If resized photo exists but nginx or apache didn't handle this request return respond_with_file(env) if requested_file_exists?(uri) # At this point we are sure that this request is targeting to resize photo PhotoCook.notify('resize:middleware:match', uri) # Matched data: width=auto&height=640&mode=fill command = Command.extract(uri) # Assemble path of the source photo: # => /application/public/uploads/photos/1/car.png source_path = Assemble.assemble_source_path_from_resize_uri(root_path, uri) # Assemble path of the resized photo: # => /application/public/resized/uploads/photos/1/COMMAND/car.png store_path = Assemble.assemble_store_path(root_path, source_path, command.to_s) if File.file?(store_path) && File.readable?(store_path) symlink_cache_dir(source_path, store_path) respond_with_file(env) elsif File.file?(source_path) && File.readable?(source_path) # Finally resize photo # Resized photo will appear in resize directory Resize.perform(source_path, store_path, command[:width], command[:height], command[:mode]) symlink_cache_dir(source_path, store_path) respond_with_file(env) else default_action(env) end end
Protected Instance Methods
default_action(env)
click to toggle source
# File lib/photo-cook/resize/middleware.rb, line 85 def default_action(env) @app.call(env) end
extract_uri(env)
click to toggle source
# File lib/photo-cook/resize/middleware.rb, line 81 def extract_uri(env) Rack::Utils.clean_path_info(Rack::Utils.unescape(env['PATH_INFO'])) end
public_path()
click to toggle source
# File lib/photo-cook/resize/middleware.rb, line 70 def public_path PhotoCook::Resize::Assemble.assemble_public_path(root_path) end
requested_file_exists?(uri)
click to toggle source
# File lib/photo-cook/resize/middleware.rb, line 74 def requested_file_exists?(uri) # Check if file exists: # /application/public/uploads/photos/1/resized/width=auto&height=640&mode=fill/car.png path = File.join(public_path, uri) File.file?(path) && File.readable?(path) end
respond_with_file(env)
click to toggle source
# File lib/photo-cook/resize/middleware.rb, line 89 def respond_with_file(env) # http://rubylogs.com/writing-rails-middleware/ # https://viget.com/extend/refactoring-patterns-the-rails-middleware-response-handler status, headers, body = Rack::File.new(public_path).call(env) # Rack::File will set Last-Modified, Content-Type and Content-Length # We will set Cache-Control. This is default behaviour. # This is configurable in PhotoCook::Resize::Middleware.headers headers.merge!(self.class.headers) if status == 200 || status == 304 response = Rack::Response.new(body, status, headers) response.finish end
root_path()
click to toggle source
# File lib/photo-cook/resize/middleware.rb, line 66 def root_path PhotoCook.root_path end
symlink_cache_dir(source_path, store_path)
click to toggle source
# File lib/photo-cook/resize/middleware.rb, line 103 def symlink_cache_dir(source_path, store_path) PhotoCook::Utils.make_relative_symlink( File.dirname(File.dirname(store_path)), File.join(File.dirname(source_path), PhotoCook::Resize.cache_dir)) end