# coding: utf-8 require 'sinatra' require 'securerandom' require 'json' set :storage_directory, './storage/' def is_base32?(str) table = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567=' if str.force_encoding("UTF-8").ascii_only? str.each_char { |c| return false unless table.include?(c) } return true else return false end end def path_is_base32?(str) str.split('/').each do |p| return false unless is_base32?(p) end return true end get '/' do redirect 'index.html' end # create a room post '/room' do id = SecureRandom.hex(6) Dir.mkdir(settings.storage_directory+id) content_type 'text/json' {id: id}.to_json end # mkdir post '/room/mkdir/:id' do |id| if Dir.exists?(settings.storage_directory+id) if params[:path] && path_is_base32?(params[:path]) Dir.mkdir(settings.storage_directory+id+"/"+params[:path]) return 200 end end 403 end # get room content get '/room/:id/*?' do |id,path| dir = settings.storage_directory+id dir += path_is_base32?(path) ? '/'+path : '' if Dir.exist?(dir) content_type 'text/json' Dir.glob(dir+'/*').map { |f| { is_directory: File.directory?(f), name: File.basename(f), last_updated: File.mtime(f) }}.to_json else 404 end end # upload a file post '/room/:id' do |id| if Dir.exists?(settings.storage_directory+id) unless params[:file] && (tmpfile = params[:file][:tempfile]) && (name = params[:file][:filename]) && params[:path] && path_is_base32?(params[:path]) && Dir.exists?(settings.storage_directory+id+'/'+params[:path]) 403 return end FileUtils.cp(tmpfile, settings.storage_directory+id+'/'+params[:path]+'/'+name) 200 else 404 end end # remove a room delete '/room/:id' do |id| end # get a file get '/files/:id/*?' do |id, filename| puts filename if path_is_base32?(filename) send_file File.join(settings.storage_directory+id, filename) else 404 end end # remove a file delete '/room/:id/*?' do |id, filename| if path_is_base32?(filename) FileUtils.rm_rf(settings.storage_directory+id+"/"+filename) else 404 end end