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