141 lines
3.4 KiB
Ruby
141 lines
3.4 KiB
Ruby
$LOAD_PATH << File.join(File.expand_path(File.dirname(__FILE__)), 'lib')
|
|
|
|
require "json"
|
|
require "sinatra/base"
|
|
require 'sinatra/config_file'
|
|
require "sinatra/reloader"
|
|
require "remote_storage/s3"
|
|
|
|
class LiquorCabinet < Sinatra::Base
|
|
|
|
#
|
|
# Configuration
|
|
#
|
|
|
|
configure do
|
|
disable :protection, :logging
|
|
enable :dump_errors
|
|
|
|
register Sinatra::ConfigFile
|
|
set :environments, %w{development test production staging}
|
|
config_file 'config.yml.erb'
|
|
end
|
|
|
|
configure :development do
|
|
register Sinatra::Reloader
|
|
also_reload "lib/remote_storage/*.rb"
|
|
set :logging, Logger::DEBUG
|
|
end
|
|
|
|
configure :production do
|
|
# Disable logging
|
|
require "rack/common_logger"
|
|
end
|
|
|
|
configure :production, :staging do
|
|
if ENV['SENTRY_DSN']
|
|
require "raven/base"
|
|
require "raven/integrations/rack"
|
|
|
|
Raven.configure do |config|
|
|
config.dsn = ENV['SENTRY_DSN']
|
|
config.tags = { environment: settings.environment.to_s }
|
|
config.excluded_exceptions = ['Sinatra::NotFound']
|
|
end
|
|
|
|
use Raven::Rack
|
|
end
|
|
end
|
|
|
|
configure :staging do
|
|
set :logging, Logger::DEBUG
|
|
end
|
|
|
|
#
|
|
# Cabinet doors
|
|
#
|
|
|
|
before do
|
|
halt 503 if settings.maintenance rescue false
|
|
end
|
|
|
|
["/:user/*/:key", "/:user/:key", "/:user/*/", "/:user/"].each do |path|
|
|
before path do
|
|
headers 'Access-Control-Allow-Origin' => '*',
|
|
'Access-Control-Allow-Methods' => 'GET, PUT, DELETE',
|
|
'Access-Control-Allow-Headers' => 'Authorization, Content-Type, Origin, If-Match, If-None-Match, Range',
|
|
'Access-Control-Expose-Headers' => 'ETag, Content-Length, Content-Range',
|
|
'Accept-Ranges' => 'bytes'
|
|
headers['Access-Control-Allow-Origin'] = env["HTTP_ORIGIN"] if env["HTTP_ORIGIN"]
|
|
headers['Cache-Control'] = 'no-cache'
|
|
|
|
@user, @key = params[:user], params[:key]
|
|
@directory = params[:splat] && params[:splat].first || ""
|
|
|
|
token = env["HTTP_AUTHORIZATION"] ? env["HTTP_AUTHORIZATION"].split(" ")[1] : ""
|
|
|
|
no_key = @key.nil? || @key.empty?
|
|
storage.authorize_request(@user, @directory, token, no_key) unless request.options?
|
|
end
|
|
|
|
options path do
|
|
headers['Access-Control-Max-Age'] = '7200'
|
|
halt 200
|
|
end
|
|
end
|
|
|
|
["/:user/*/:key", "/:user/:key"].each do |path|
|
|
head path do
|
|
storage.get_head(@user, @directory, @key)
|
|
end
|
|
|
|
get path do
|
|
storage.get_data(@user, @directory, @key)
|
|
end
|
|
|
|
put path do
|
|
data = request.body.read
|
|
|
|
halt 422 unless env['CONTENT_TYPE']
|
|
|
|
if env['CONTENT_TYPE'] == "application/x-www-form-urlencoded"
|
|
content_type = "text/plain; charset=utf-8"
|
|
else
|
|
content_type = env['CONTENT_TYPE']
|
|
end
|
|
|
|
storage.put_data(@user, @directory, @key, data, content_type)
|
|
end
|
|
|
|
delete path do
|
|
storage.delete_data(@user, @directory, @key)
|
|
end
|
|
end
|
|
|
|
["/:user/*/", "/:user/"].each do |path|
|
|
head path do
|
|
storage.get_head_directory_listing(@user, @directory)
|
|
end
|
|
|
|
get path do
|
|
storage.get_directory_listing(@user, @directory)
|
|
end
|
|
end
|
|
|
|
private
|
|
|
|
def storage
|
|
@storage ||= begin
|
|
if settings.respond_to? :s3
|
|
RemoteStorage::S3.new(settings, self)
|
|
else
|
|
puts <<-EOF
|
|
You need to set one storage backend in your config.yml file.
|
|
Riak and Swift are currently supported. See config.yml.example.
|
|
EOF
|
|
end
|
|
end
|
|
end
|
|
|
|
end
|