aboutsummaryrefslogtreecommitdiffstats
path: root/actionpack
diff options
context:
space:
mode:
Diffstat (limited to 'actionpack')
-rw-r--r--actionpack/lib/action_dispatch.rb3
-rw-r--r--actionpack/lib/action_dispatch/middleware/static.rb44
-rw-r--r--actionpack/test/dispatch/static_test.rb35
-rw-r--r--actionpack/test/fixtures/public/foo/bar.html1
-rw-r--r--actionpack/test/fixtures/public/foo/index.html1
-rw-r--r--actionpack/test/fixtures/public/index.html1
6 files changed, 84 insertions, 1 deletions
diff --git a/actionpack/lib/action_dispatch.rb b/actionpack/lib/action_dispatch.rb
index ff365dac68..38aaa6146e 100644
--- a/actionpack/lib/action_dispatch.rb
+++ b/actionpack/lib/action_dispatch.rb
@@ -34,10 +34,11 @@ module ActionDispatch
autoload :Utils, 'action_dispatch/http/utils'
autoload :Callbacks, 'action_dispatch/middleware/callbacks'
+ autoload :MiddlewareStack, 'action_dispatch/middleware/stack'
autoload :ParamsParser, 'action_dispatch/middleware/params_parser'
autoload :Rescue, 'action_dispatch/middleware/rescue'
autoload :ShowExceptions, 'action_dispatch/middleware/show_exceptions'
- autoload :MiddlewareStack, 'action_dispatch/middleware/stack'
+ autoload :Static, 'action_dispatch/middleware/static'
autoload :Assertions, 'action_dispatch/testing/assertions'
autoload :Integration, 'action_dispatch/testing/integration'
diff --git a/actionpack/lib/action_dispatch/middleware/static.rb b/actionpack/lib/action_dispatch/middleware/static.rb
new file mode 100644
index 0000000000..d7e88a54e4
--- /dev/null
+++ b/actionpack/lib/action_dispatch/middleware/static.rb
@@ -0,0 +1,44 @@
+require 'rack/utils'
+
+module ActionDispatch
+ class Static
+ FILE_METHODS = %w(GET HEAD).freeze
+
+ def initialize(app, root)
+ @app = app
+ @file_server = ::Rack::File.new(root)
+ end
+
+ def call(env)
+ path = env['PATH_INFO'].chomp('/')
+ method = env['REQUEST_METHOD']
+
+ if FILE_METHODS.include?(method)
+ if file_exist?(path)
+ return @file_server.call(env)
+ else
+ cached_path = directory_exist?(path) ? "#{path}/index" : path
+ cached_path += ::ActionController::Base.page_cache_extension
+
+ if file_exist?(cached_path)
+ env['PATH_INFO'] = cached_path
+ return @file_server.call(env)
+ end
+ end
+ end
+
+ @app.call(env)
+ end
+
+ private
+ def file_exist?(path)
+ full_path = File.join(@file_server.root, ::Rack::Utils.unescape(path))
+ File.file?(full_path) && File.readable?(full_path)
+ end
+
+ def directory_exist?(path)
+ full_path = File.join(@file_server.root, ::Rack::Utils.unescape(path))
+ File.directory?(full_path) && File.readable?(full_path)
+ end
+ end
+end
diff --git a/actionpack/test/dispatch/static_test.rb b/actionpack/test/dispatch/static_test.rb
new file mode 100644
index 0000000000..e6957bb0ea
--- /dev/null
+++ b/actionpack/test/dispatch/static_test.rb
@@ -0,0 +1,35 @@
+require 'abstract_unit'
+
+class StaticTest < ActiveSupport::TestCase
+ DummyApp = lambda { |env|
+ [200, {"Content-Type" => "text/plain"}, ["Hello, World!"]]
+ }
+ App = ActionDispatch::Static.new(DummyApp, "#{FIXTURE_LOAD_PATH}/public")
+
+ test "serves dynamic content" do
+ assert_equal "Hello, World!", get("/nofile")
+ end
+
+ test "serves static index at root" do
+ assert_equal "/index.html", get("/index.html")
+ assert_equal "/index.html", get("/index")
+ assert_equal "/index.html", get("/")
+ end
+
+ test "serves static file in directory" do
+ assert_equal "/foo/bar.html", get("/foo/bar.html")
+ assert_equal "/foo/bar.html", get("/foo/bar/")
+ assert_equal "/foo/bar.html", get("/foo/bar")
+ end
+
+ test "serves static index file in directory" do
+ assert_equal "/foo/index.html", get("/foo/index.html")
+ assert_equal "/foo/index.html", get("/foo/")
+ assert_equal "/foo/index.html", get("/foo")
+ end
+
+ private
+ def get(path)
+ Rack::MockRequest.new(App).request("GET", path).body
+ end
+end
diff --git a/actionpack/test/fixtures/public/foo/bar.html b/actionpack/test/fixtures/public/foo/bar.html
new file mode 100644
index 0000000000..9a35646205
--- /dev/null
+++ b/actionpack/test/fixtures/public/foo/bar.html
@@ -0,0 +1 @@
+/foo/bar.html \ No newline at end of file
diff --git a/actionpack/test/fixtures/public/foo/index.html b/actionpack/test/fixtures/public/foo/index.html
new file mode 100644
index 0000000000..497a2e898f
--- /dev/null
+++ b/actionpack/test/fixtures/public/foo/index.html
@@ -0,0 +1 @@
+/foo/index.html \ No newline at end of file
diff --git a/actionpack/test/fixtures/public/index.html b/actionpack/test/fixtures/public/index.html
new file mode 100644
index 0000000000..525950ba6b
--- /dev/null
+++ b/actionpack/test/fixtures/public/index.html
@@ -0,0 +1 @@
+/index.html \ No newline at end of file