Created
December 5, 2016 10:55
-
-
Save yous/40d8e18b33dfb62966c3e1e343f11a96 to your computer and use it in GitHub Desktop.
Thin + Rack file server with basic auth on Windows
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'rack' | |
require 'thin' | |
dirname = File.expand_path(File.dirname(__FILE__)) | |
fileroot = File.join(dirname, 'files') | |
module Rack | |
class UTF8Directory < Directory | |
class DirectoryBody < Directory::DirectoryBody | |
private | |
# Escape single quotes in URL for DIR_FILE | |
# https://github.com/rack/rack/pull/1131 | |
def DIR_FILE_escape url, *html | |
[url.gsub("'", '''), *html.map { |e| Utils.escape_html(e) }] | |
end | |
end | |
def list_directory(path_info, path, script_name) | |
files = [['../','Parent Directory','','','']] | |
path.force_encoding(Encoding::UTF_8) | |
url_head = (script_name.split('/') + path_info.split('/')).map do |part| | |
Rack::Utils.escape_path part | |
end | |
Dir.entries(path).sort.each do |node| | |
next if node == '.' || node == '..' | |
node.encode!(Encoding::UTF_8) | |
node = ::File.join(path, node) | |
stat = stat(node) | |
next unless stat | |
basename = ::File.basename(node) | |
ext = ::File.extname(node) | |
url = ::File.join(*url_head + [Rack::Utils.escape_path(basename)]) | |
size = stat.size | |
type = stat.directory? ? 'directory' : Mime.mime_type(ext) | |
size = stat.directory? ? '-' : filesize_format(size) | |
mtime = stat.mtime.httpdate | |
url << '/' if stat.directory? | |
basename << '/' if stat.directory? | |
files << [ url, basename, size, type, mtime ] | |
end | |
return [ 200, { CONTENT_TYPE =>'text/html; charset=utf-8'}, DirectoryBody.new(@root, path, files) ] | |
end | |
def list_path(env, path, path_info, script_name) | |
path.force_encoding(Encoding::UTF_8) | |
stat = ::File.stat(path) | |
if stat.readable? | |
return @app.call(env) if stat.file? | |
return list_directory(path_info, path, script_name) if stat.directory? | |
else | |
raise Errno::ENOENT, 'No such file or directory' | |
end | |
rescue Errno::ENOENT, Errno::ELOOP | |
return entity_not_found(path_info) | |
end | |
end | |
end | |
Thin::Server.start('0.0.0.0', 8000) do | |
use Rack::Auth::Basic, 'Protected Area' do |username, password| | |
username == 'USERNAME' && password == 'PASSWORD' | |
end | |
run Rack::UTF8Directory.new(fileroot) | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
For Puma, add
require 'puma'
and replaceThin::Server.start
block with