Skip to content

Commit

Permalink
Add option to HTTP::StaticFileHandler initializer to disable director…
Browse files Browse the repository at this point in the history
…y listing (#4403)
  • Loading branch information
joaodiogocosta authored and bcardiff committed May 15, 2017
1 parent 0e78159 commit 6930423
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 5 deletions.
9 changes: 7 additions & 2 deletions spec/std/http/server/handlers/static_file_handler_spec.cr
@@ -1,11 +1,11 @@
require "spec"
require "http/server"

private def handle(request, fallthrough = true)
private def handle(request, fallthrough = true, directory_listing = true)
io = IO::Memory.new
response = HTTP::Server::Response.new(io)
context = HTTP::Server::Context.new(request, response)
handler = HTTP::StaticFileHandler.new "#{__DIR__}/static", fallthrough
handler = HTTP::StaticFileHandler.new "#{__DIR__}/static", fallthrough, directory_listing
handler.call context
response.close
io.rewind
Expand All @@ -27,6 +27,11 @@ describe HTTP::StaticFileHandler do
response.body.should match(/test.txt/)
end

it "should not list directory's entries when directory_listing is set to false" do
response = handle HTTP::Request.new("GET", "/"), directory_listing: false
response.status_code.should eq(404)
end

it "should not serve a not found file" do
response = handle HTTP::Request.new("GET", "/not_found_file.txt")
response.status_code.should eq(404)
Expand Down
11 changes: 8 additions & 3 deletions src/http/server/handlers/static_file_handler.cr
Expand Up @@ -14,9 +14,13 @@ class HTTP::StaticFileHandler
# If *fallthrough* is `false`, this handler does not call next handler when
# request method is neither GET or HEAD, then serves `405 Method Not Allowed`.
# Otherwise, it calls next handler.
def initialize(public_dir : String, fallthrough = true)
#
# If *directory_listing* is `false`, directory listing is disabled. This means that
# paths matching directories are ignored and next handler is called.
def initialize(public_dir : String, fallthrough = true, directory_listing = true)
@public_dir = File.expand_path public_dir
@fallthrough = !!fallthrough
@directory_listing = !!directory_listing
end

def call(context)
Expand Down Expand Up @@ -49,16 +53,17 @@ class HTTP::StaticFileHandler

file_path = File.join(@public_dir, expanded_path)
is_dir = Dir.exists? file_path
is_file = !is_dir && File.exists?(file_path)

if request_path != expanded_path || is_dir && !is_dir_path
redirect_to context, "#{expanded_path}#{is_dir && !is_dir_path ? "/" : ""}"
return
end

if Dir.exists?(file_path)
if @directory_listing && is_dir
context.response.content_type = "text/html"
directory_listing(context.response, request_path, file_path)
elsif File.exists?(file_path)
elsif is_file
context.response.content_type = mime_type(file_path)
context.response.content_length = File.size(file_path)
File.open(file_path) do |file|
Expand Down

0 comments on commit 6930423

Please sign in to comment.