aboutsummaryrefslogtreecommitdiffstats
path: root/actionpack/lib/action_dispatch/middleware
diff options
context:
space:
mode:
Diffstat (limited to 'actionpack/lib/action_dispatch/middleware')
-rw-r--r--actionpack/lib/action_dispatch/middleware/callbacks.rb2
-rw-r--r--actionpack/lib/action_dispatch/middleware/params_parser.rb1
-rw-r--r--actionpack/lib/action_dispatch/middleware/remote_ip.rb51
-rw-r--r--actionpack/lib/action_dispatch/middleware/session/cookie_store.rb13
-rw-r--r--actionpack/lib/action_dispatch/middleware/stack.rb8
5 files changed, 63 insertions, 12 deletions
diff --git a/actionpack/lib/action_dispatch/middleware/callbacks.rb b/actionpack/lib/action_dispatch/middleware/callbacks.rb
index 7cf75ffe63..d07841218a 100644
--- a/actionpack/lib/action_dispatch/middleware/callbacks.rb
+++ b/actionpack/lib/action_dispatch/middleware/callbacks.rb
@@ -37,7 +37,7 @@ module ActionDispatch
def initialize(app, prepare_each_request = false)
@app, @prepare_each_request = app, prepare_each_request
- run_callbacks(:prepare) unless @prepare_each_request
+ run_callbacks(:prepare)
end
def call(env)
diff --git a/actionpack/lib/action_dispatch/middleware/params_parser.rb b/actionpack/lib/action_dispatch/middleware/params_parser.rb
index 522982e202..f4c4324fb0 100644
--- a/actionpack/lib/action_dispatch/middleware/params_parser.rb
+++ b/actionpack/lib/action_dispatch/middleware/params_parser.rb
@@ -1,4 +1,3 @@
-require 'active_support/json'
require 'action_dispatch/http/request'
module ActionDispatch
diff --git a/actionpack/lib/action_dispatch/middleware/remote_ip.rb b/actionpack/lib/action_dispatch/middleware/remote_ip.rb
new file mode 100644
index 0000000000..c7d710b98e
--- /dev/null
+++ b/actionpack/lib/action_dispatch/middleware/remote_ip.rb
@@ -0,0 +1,51 @@
+module ActionDispatch
+ class RemoteIp
+ class IpSpoofAttackError < StandardError ; end
+
+ class RemoteIpGetter
+ def initialize(env, check_ip_spoofing, trusted_proxies)
+ @env = env
+ @check_ip_spoofing = check_ip_spoofing
+ @trusted_proxies = trusted_proxies
+ end
+
+ def remote_addrs
+ @remote_addrs ||= begin
+ list = @env['REMOTE_ADDR'] ? @env['REMOTE_ADDR'].split(/[,\s]+/) : []
+ list.reject { |addr| addr =~ @trusted_proxies }
+ end
+ end
+
+ def to_s
+ return remote_addrs.first if remote_addrs.any?
+
+ forwarded_ips = @env['HTTP_X_FORWARDED_FOR'] ? @env['HTTP_X_FORWARDED_FOR'].strip.split(/[,\s]+/) : []
+
+ if client_ip = @env['HTTP_CLIENT_IP']
+ if @check_ip_spoofing && !forwarded_ips.include?(client_ip)
+ # We don't know which came from the proxy, and which from the user
+ raise IpSpoofAttackError, "IP spoofing attack?!" \
+ "HTTP_CLIENT_IP=#{@env['HTTP_CLIENT_IP'].inspect}" \
+ "HTTP_X_FORWARDED_FOR=#{@env['HTTP_X_FORWARDED_FOR'].inspect}"
+ end
+ return client_ip
+ end
+
+ return forwarded_ips.reject { |ip| ip =~ @trusted_proxies }.last || @env["REMOTE_ADDR"]
+ end
+ end
+
+ def initialize(app, check_ip_spoofing = true, trusted_proxies = nil)
+ @app = app
+ @check_ip_spoofing = check_ip_spoofing
+ regex = '(^127\.0\.0\.1$|^(10|172\.(1[6-9]|2[0-9]|30|31)|192\.168)\.)'
+ regex << "|(#{trusted_proxies})" if trusted_proxies
+ @trusted_proxies = Regexp.new(regex, "i")
+ end
+
+ def call(env)
+ env["action_dispatch.remote_ip"] = RemoteIpGetter.new(env, @check_ip_spoofing, @trusted_proxies)
+ @app.call(env)
+ end
+ end
+end \ No newline at end of file
diff --git a/actionpack/lib/action_dispatch/middleware/session/cookie_store.rb b/actionpack/lib/action_dispatch/middleware/session/cookie_store.rb
index 04a101dbb2..22da82479e 100644
--- a/actionpack/lib/action_dispatch/middleware/session/cookie_store.rb
+++ b/actionpack/lib/action_dispatch/middleware/session/cookie_store.rb
@@ -1,5 +1,4 @@
require 'active_support/core_ext/hash/keys'
-require 'rack/request'
module ActionDispatch
module Session
@@ -177,9 +176,8 @@ module ActionDispatch
if key.blank?
raise ArgumentError, 'A key is required to write a ' +
'cookie containing the session data. Use ' +
- 'config.action_controller.session = { :key => ' +
- '"_myapp_session", :secret => "some secret phrase" } in ' +
- 'config/application.rb'
+ 'config.action_controller.session_store :cookie_store, { :key => ' +
+ '"_myapp_session" } in config/application.rb'
end
end
@@ -193,10 +191,9 @@ module ActionDispatch
if secret.blank?
raise ArgumentError, "A secret is required to generate an " +
"integrity hash for cookie session data. Use " +
- "config.action_controller.session = { :key => " +
- "\"_myapp_session\", :secret => \"some secret phrase of at " +
- "least #{SECRET_MIN_LENGTH} characters\" } " +
- "in config/environment.rb"
+ "config.cookie_secret = \"some secret phrase of at " +
+ "least #{SECRET_MIN_LENGTH} characters\"" +
+ "in config/application.rb"
end
if secret.length < SECRET_MIN_LENGTH
diff --git a/actionpack/lib/action_dispatch/middleware/stack.rb b/actionpack/lib/action_dispatch/middleware/stack.rb
index 18a2922fa7..5c5362ce4a 100644
--- a/actionpack/lib/action_dispatch/middleware/stack.rb
+++ b/actionpack/lib/action_dispatch/middleware/stack.rb
@@ -58,7 +58,7 @@ module ActionDispatch
if lazy_compare?(@klass) && lazy_compare?(middleware)
normalize(@klass) == normalize(middleware)
else
- klass == ActiveSupport::Inflector.constantize(middleware.to_s)
+ klass.name == middleware.to_s
end
end
end
@@ -122,7 +122,11 @@ module ActionDispatch
find_all { |middleware| middleware.active? }
end
- def build(app)
+ def build(app = nil, &blk)
+ app ||= blk
+
+ raise "MiddlewareStack#build requires an app" unless app
+
active.reverse.inject(app) { |a, e| e.build(a) }
end
end