aboutsummaryrefslogtreecommitdiffstats
path: root/railties/lib
diff options
context:
space:
mode:
Diffstat (limited to 'railties/lib')
-rw-r--r--railties/lib/commands/server.rb2
-rw-r--r--railties/lib/initializer.rb8
-rw-r--r--railties/lib/rails/rack.rb3
-rw-r--r--railties/lib/rails/rack/cascade.rb31
-rw-r--r--railties/lib/rails/rack/log_tailer.rb35
-rw-r--r--railties/lib/rails/rack/logger.rb28
-rw-r--r--railties/lib/rails/rack/metal.rb27
-rw-r--r--railties/lib/rails_generator/generators/components/metal/USAGE8
-rw-r--r--railties/lib/rails_generator/generators/components/metal/metal_generator.rb8
-rw-r--r--railties/lib/rails_generator/generators/components/metal/templates/metal.rb12
-rw-r--r--railties/lib/tasks/middleware.rake2
11 files changed, 133 insertions, 31 deletions
diff --git a/railties/lib/commands/server.rb b/railties/lib/commands/server.rb
index 7057fcc33f..43b18004c0 100644
--- a/railties/lib/commands/server.rb
+++ b/railties/lib/commands/server.rb
@@ -84,7 +84,7 @@ else
end
app = Rack::Builder.new {
- use Rails::Rack::Logger
+ use Rails::Rack::LogTailer unless options[:detach]
use Rails::Rack::Static
use Rails::Rack::Debugger if options[:debugger]
run inner_app
diff --git a/railties/lib/initializer.rb b/railties/lib/initializer.rb
index 56e8ce95ab..637fe74313 100644
--- a/railties/lib/initializer.rb
+++ b/railties/lib/initializer.rb
@@ -155,6 +155,8 @@ module Rails
initialize_framework_settings
initialize_framework_views
+ initialize_metal
+
add_support_load_paths
load_gems
@@ -533,6 +535,10 @@ Run `rake gems:install` to install the missing gems.
end
end
+ def initialize_metal
+ configuration.middleware.use Rails::Rack::Metal
+ end
+
# Initializes framework-specific settings for each of the loaded frameworks
# (Configuration#frameworks). The available settings map to the accessors
# on each of the corresponding Base classes.
@@ -915,6 +921,7 @@ Run `rake gems:install` to install the missing gems.
# Followed by the standard includes.
paths.concat %w(
app
+ app/metal
app/models
app/controllers
app/helpers
@@ -933,6 +940,7 @@ Run `rake gems:install` to install the missing gems.
def default_eager_load_paths
%w(
+ app/metal
app/models
app/controllers
app/helpers
diff --git a/railties/lib/rails/rack.rb b/railties/lib/rails/rack.rb
index 90535674e9..9705f65e52 100644
--- a/railties/lib/rails/rack.rb
+++ b/railties/lib/rails/rack.rb
@@ -1,7 +1,8 @@
module Rails
module Rack
autoload :Debugger, "rails/rack/debugger"
- autoload :Logger, "rails/rack/logger"
+ autoload :LogTailer, "rails/rack/log_tailer"
+ autoload :Metal, "rails/rack/metal"
autoload :Static, "rails/rack/static"
end
end
diff --git a/railties/lib/rails/rack/cascade.rb b/railties/lib/rails/rack/cascade.rb
new file mode 100644
index 0000000000..d5af7fc77e
--- /dev/null
+++ b/railties/lib/rails/rack/cascade.rb
@@ -0,0 +1,31 @@
+require 'active_support/ordered_hash'
+
+module Rails
+ module Rack
+ # Try a request on several apps; return the first non-404 response.
+ class Cascade
+ attr_reader :apps
+
+ def initialize(apps)
+ @apps = ActiveSupport::OrderedHash.new
+ apps.each { |app| add app }
+ end
+
+ def call(env)
+ @apps.keys.each do |app|
+ result = app.call(env)
+ return result unless result[0].to_i == 404
+ end
+ Metal::NotFoundResponse
+ end
+
+ def add(app)
+ @apps[app] = true
+ end
+
+ def include?(app)
+ @apps.include?(app)
+ end
+ end
+ end
+end
diff --git a/railties/lib/rails/rack/log_tailer.rb b/railties/lib/rails/rack/log_tailer.rb
new file mode 100644
index 0000000000..a237cee6bc
--- /dev/null
+++ b/railties/lib/rails/rack/log_tailer.rb
@@ -0,0 +1,35 @@
+module Rails
+ module Rack
+ class LogTailer
+ EnvironmentLog = "#{File.expand_path(Rails.root)}/log/#{Rails.env}.log"
+
+ def initialize(app, log = nil)
+ @app = app
+
+ path = Pathname.new(log || EnvironmentLog).cleanpath
+ @cursor = ::File.size(path)
+ @last_checked = Time.now.to_f
+
+ @file = ::File.open(path, 'r')
+ end
+
+ def call(env)
+ response = @app.call(env)
+ tail_log
+ response
+ end
+
+ def tail_log
+ @file.seek @cursor
+
+ mod = @file.mtime.to_f
+ if mod > @last_checked
+ contents = @file.read
+ @last_checked = mod
+ @cursor += contents.size
+ $stdout.print contents
+ end
+ end
+ end
+ end
+end
diff --git a/railties/lib/rails/rack/logger.rb b/railties/lib/rails/rack/logger.rb
deleted file mode 100644
index 89d02e45a9..0000000000
--- a/railties/lib/rails/rack/logger.rb
+++ /dev/null
@@ -1,28 +0,0 @@
-module Rails
- module Rack
- class Logger
- EnvironmentLog = "#{File.expand_path(Rails.root)}/log/#{Rails.env}.log"
-
- def initialize(app, log = nil)
- @app = app
- @path = Pathname.new(log || EnvironmentLog).cleanpath
- @cursor = ::File.size(@path)
- @last_checked = Time.now
- end
-
- def call(env)
- response = @app.call(env)
- ::File.open(@path, 'r') do |f|
- f.seek @cursor
- if f.mtime > @last_checked
- contents = f.read
- @last_checked = f.mtime
- @cursor += contents.length
- print contents
- end
- end
- response
- end
- end
- end
-end
diff --git a/railties/lib/rails/rack/metal.rb b/railties/lib/rails/rack/metal.rb
new file mode 100644
index 0000000000..1df31a1594
--- /dev/null
+++ b/railties/lib/rails/rack/metal.rb
@@ -0,0 +1,27 @@
+require 'rails/rack/cascade'
+
+module Rails
+ module Rack
+ module Metal
+ NotFoundResponse = [404, {}, []].freeze
+ NotFound = lambda { NotFoundResponse }
+
+ class << self
+ def new(app)
+ Cascade.new(builtins + [app])
+ end
+
+ def builtins
+ base = "#{Rails.root}/app/metal"
+ matcher = /\A#{Regexp.escape(base)}\/(.*)\.rb\Z/
+
+ Dir["#{base}/**/*.rb"].sort.map do |file|
+ file.sub!(matcher, '\1')
+ require file
+ file.classify.constantize
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/railties/lib/rails_generator/generators/components/metal/USAGE b/railties/lib/rails_generator/generators/components/metal/USAGE
new file mode 100644
index 0000000000..123ec6c03f
--- /dev/null
+++ b/railties/lib/rails_generator/generators/components/metal/USAGE
@@ -0,0 +1,8 @@
+Description:
+ Cast some metal!
+
+Examples:
+ `./script/generate metal poller`
+
+ This will create:
+ Metal: app/metal/poller.rb
diff --git a/railties/lib/rails_generator/generators/components/metal/metal_generator.rb b/railties/lib/rails_generator/generators/components/metal/metal_generator.rb
new file mode 100644
index 0000000000..64f49d929d
--- /dev/null
+++ b/railties/lib/rails_generator/generators/components/metal/metal_generator.rb
@@ -0,0 +1,8 @@
+class MetalGenerator < Rails::Generator::NamedBase
+ def manifest
+ record do |m|
+ m.directory 'app/metal'
+ m.template 'metal.rb', File.join('app/metal', "#{file_name}.rb")
+ end
+ end
+end
diff --git a/railties/lib/rails_generator/generators/components/metal/templates/metal.rb b/railties/lib/rails_generator/generators/components/metal/templates/metal.rb
new file mode 100644
index 0000000000..e94982b69a
--- /dev/null
+++ b/railties/lib/rails_generator/generators/components/metal/templates/metal.rb
@@ -0,0 +1,12 @@
+# Allow the metal piece to run in isolation
+require(File.dirname(__FILE__) + "/../../config/environment") unless defined?(Rails)
+
+class <%= class_name %>
+ def self.call(env)
+ if env["PATH_INFO"] =~ /^\/<%= file_name %>/
+ [200, {"Content-Type" => "text/html"}, ["Hello, World!"]]
+ else
+ [404, {"Content-Type" => "text/html"}, ["Not Found"]]
+ end
+ end
+end
diff --git a/railties/lib/tasks/middleware.rake b/railties/lib/tasks/middleware.rake
index e0dcf50307..05f159184e 100644
--- a/railties/lib/tasks/middleware.rake
+++ b/railties/lib/tasks/middleware.rake
@@ -1,6 +1,6 @@
desc 'Prints out your Rack middleware stack'
task :middleware => :environment do
- ActionController::Dispatcher.middleware.each do |middleware|
+ ActionController::Dispatcher.middleware.active.each do |middleware|
puts "use #{middleware.inspect}"
end
puts "run ActionController::Dispatcher.new"