lib/refile/app.rb in refile-0.3.0 vs lib/refile/app.rb in refile-0.4.0
- old
+ new
@@ -1,99 +1,124 @@
-require "logger"
require "json"
+require "sinatra/base"
module Refile
- class App
- def initialize(logger: nil, allow_origin: nil)
- @logger = logger
- @logger ||= ::Logger.new(nil)
- @allow_origin = allow_origin
+ class App < Sinatra::Base
+ configure do
+ set :show_exceptions, false
+ set :raise_errors, false
+ set :sessions, false
+ set :logging, false
+ set :dump_errors, false
end
- # @api private
- class Proxy
- def initialize(peek, file)
- @peek = peek
- @file = file
+ before do
+ content_type ::File.extname(request.path), default: "application/octet-stream"
+ if Refile.allow_origin
+ response["Access-Control-Allow-Origin"] = Refile.allow_origin
+ response["Access-Control-Allow-Headers"] = request.env["HTTP_ACCESS_CONTROL_REQUEST_HEADERS"].to_s
+ response["Access-Control-Allow-Method"] = request.env["HTTP_ACCESS_CONTROL_REQUEST_METHOD"].to_s
end
+ end
- def close
- @file.close
- end
+ get "/:backend/:id/:filename" do
+ set_expires_header
+ stream_file(file)
+ end
- def each(&block)
- block.call(@peek)
- @file.each(&block)
- end
+ get "/:backend/:processor/:id/:file_basename.:extension" do
+ set_expires_header
+ stream_file processor.call(file, format: params[:extension])
end
- def call(env)
- @logger.info { "Refile: #{env["REQUEST_METHOD"]} #{env["PATH_INFO"]}" }
+ get "/:backend/:processor/:id/:filename" do
+ set_expires_header
+ stream_file processor.call(file)
+ end
- backend_name, *args = env["PATH_INFO"].sub(/^\//, "").split("/")
- backend = Refile.backends[backend_name]
+ get "/:backend/:processor/*/:id/:file_basename.:extension" do
+ set_expires_header
+ stream_file processor.call(file, *params[:splat].first.split("/"), format: params[:extension])
+ end
- if env["REQUEST_METHOD"] == "GET" and backend and args.length >= 2
- *process_args, id, filename = args
- format = ::File.extname(filename)[1..-1]
+ get "/:backend/:processor/*/:id/:filename" do
+ set_expires_header
+ stream_file processor.call(file, *params[:splat].first.split("/"))
+ end
- @logger.debug { "Refile: serving #{id.inspect} from #{backend_name} backend which is of type #{backend.class}" }
+ options "/:backend" do
+ ""
+ end
- file = backend.get(id)
+ post "/:backend" do
+ backend = Refile.backends[params[:backend]]
+ halt 404 unless backend && Refile.direct_upload.include?(params[:backend])
+ tempfile = request.params.fetch("file").fetch(:tempfile)
+ file = backend.upload(tempfile)
+ content_type :json
+ { id: file.id }.to_json
+ end
- unless process_args.empty?
- name = process_args.shift
- processor = Refile.processors[name]
- unless processor
- @logger.debug { "Refile: no such processor #{name.inspect}" }
- return not_found
- end
- file = if format
- processor.call(file, *process_args, format: format)
- else
- processor.call(file, *process_args)
- end
- end
+ not_found do
+ content_type :text
+ "not found"
+ end
- peek = begin
- file.read(Refile.read_chunk_size)
- rescue => e
- log_error(e)
- return not_found
- end
+ error do |error_thrown|
+ log_error("Error -> #{error_thrown}")
+ error_thrown.backtrace.each do |line|
+ log_error(line)
+ end
+ content_type :text
+ "error"
+ end
- headers = {}
- headers["Access-Control-Allow-Origin"] = @allow_origin if @allow_origin
+ private
- [200, headers, Proxy.new(peek, file)]
- elsif env["REQUEST_METHOD"] == "POST" and backend and args.empty? and Refile.direct_upload.include?(backend_name)
- @logger.debug { "Refile: uploading to #{backend_name} backend which is of type #{backend.class}" }
+ def set_expires_header
+ expires Refile.content_max_age, :public, :must_revalidate
+ end
- tempfile = Rack::Request.new(env).params.fetch("file").fetch(:tempfile)
- file = backend.upload(tempfile)
+ def logger
+ Refile.logger
+ end
- [200, { "Content-Type" => "application/json" }, [{ id: file.id }.to_json]]
- else
- not_found
+ def stream_file(file)
+ stream do |out|
+ file.each do |chunk|
+ out << chunk
+ end
end
- rescue => e
- log_error(e)
- [500, {}, ["error"]]
end
- private
+ def backend
+ backend = Refile.backends[params[:backend]]
+ unless backend
+ log_error("Could not find backend: #{params[:backend]}")
+ halt 404
+ end
+ backend
+ end
- def not_found
- [404, {}, ["not found"]]
+ def file
+ file = backend.get(params[:id])
+ unless file.exists?
+ log_error("Could not find attachment by id: #{params[:id]}")
+ halt 404
+ end
+ file
end
- def log_error(e)
- if @logger.debug?
- @logger.debug "Refile: unable to read file"
- @logger.debug "#{e.class}: #{e.message}"
- e.backtrace.each do |line|
- @logger.debug " #{line}"
- end
+ def processor
+ processor = Refile.processors[params[:processor]]
+ unless processor
+ log_error("Could not find processor: #{params[:processor]}")
+ halt 404
end
+ processor
+ end
+
+ def log_error(message)
+ logger.error "#{self.class.name}: #{message}"
end
end
end