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/cookies.rb2
-rw-r--r--actionpack/lib/action_dispatch/middleware/flash.rb4
-rw-r--r--actionpack/lib/action_dispatch/middleware/request_id.rb39
-rw-r--r--actionpack/lib/action_dispatch/middleware/session/cache_store.rb50
4 files changed, 94 insertions, 1 deletions
diff --git a/actionpack/lib/action_dispatch/middleware/cookies.rb b/actionpack/lib/action_dispatch/middleware/cookies.rb
index 8c4615c0c1..a4ffd40a66 100644
--- a/actionpack/lib/action_dispatch/middleware/cookies.rb
+++ b/actionpack/lib/action_dispatch/middleware/cookies.rb
@@ -174,7 +174,7 @@ module ActionDispatch
options = { :value => value }
end
- value = @cookies[key.to_s] = value
+ @cookies[key.to_s] = value
handle_options(options)
diff --git a/actionpack/lib/action_dispatch/middleware/flash.rb b/actionpack/lib/action_dispatch/middleware/flash.rb
index 2adbce031b..e59404ef68 100644
--- a/actionpack/lib/action_dispatch/middleware/flash.rb
+++ b/actionpack/lib/action_dispatch/middleware/flash.rb
@@ -70,6 +70,10 @@ module ActionDispatch
end
end
+ # Implementation detail: please do not change the signature of the
+ # FlashHash class. Doing that will likely affect all Rails apps in
+ # production as the FlashHash currently stored in their sessions will
+ # become invalid.
class FlashHash
include Enumerable
diff --git a/actionpack/lib/action_dispatch/middleware/request_id.rb b/actionpack/lib/action_dispatch/middleware/request_id.rb
new file mode 100644
index 0000000000..bee446c8a5
--- /dev/null
+++ b/actionpack/lib/action_dispatch/middleware/request_id.rb
@@ -0,0 +1,39 @@
+require 'securerandom'
+require 'active_support/core_ext/string/access'
+require 'active_support/core_ext/object/blank'
+
+module ActionDispatch
+ # Makes a unique request id available to the action_dispatch.request_id env variable (which is then accessible through
+ # ActionDispatch::Request#uuid) and sends the same id to the client via the X-Request-Id header.
+ #
+ # The unique request id is either based off the X-Request-Id header in the request, which would typically be generated
+ # by a firewall, load balancer, or the web server, or, if this header is not available, a random uuid. If the
+ # header is accepted from the outside world, we sanitize it to a max of 255 chars and alphanumeric and dashes only.
+ #
+ # The unique request id can be used to trace a request end-to-end and would typically end up being part of log files
+ # from multiple pieces of the stack.
+ class RequestId
+ def initialize(app)
+ @app = app
+ end
+
+ def call(env)
+ env["action_dispatch.request_id"] = external_request_id(env) || internal_request_id
+ status, headers, body = @app.call(env)
+
+ headers["X-Request-Id"] = env["action_dispatch.request_id"]
+ [ status, headers, body ]
+ end
+
+ private
+ def external_request_id(env)
+ if request_id = env["HTTP_X_REQUEST_ID"].presence
+ request_id.gsub(/[^\w\-]/, "").first(255)
+ end
+ end
+
+ def internal_request_id
+ SecureRandom.hex(16)
+ end
+ end
+end
diff --git a/actionpack/lib/action_dispatch/middleware/session/cache_store.rb b/actionpack/lib/action_dispatch/middleware/session/cache_store.rb
new file mode 100644
index 0000000000..d3b6fd12fa
--- /dev/null
+++ b/actionpack/lib/action_dispatch/middleware/session/cache_store.rb
@@ -0,0 +1,50 @@
+require 'action_dispatch/middleware/session/abstract_store'
+require 'rack/session/memcache'
+
+module ActionDispatch
+ module Session
+ # Session store that uses an ActiveSupport::Cache::Store to store the sessions. This store is most useful
+ # if you don't store critical data in your sessions and you don't need them to live for extended periods
+ # of time.
+ class CacheStore < AbstractStore
+ # Create a new store. The cache to use can be passed in the <tt>:cache</tt> option. If it is
+ # not specified, <tt>Rails.cache</tt> will be used.
+ def initialize(app, options = {})
+ @cache = options[:cache] || Rails.cache
+ options[:expire_after] ||= @cache.options[:expires_in]
+ super
+ end
+
+ # Get a session from the cache.
+ def get_session(env, sid)
+ sid ||= generate_sid
+ session = @cache.read(cache_key(sid))
+ session ||= {}
+ [sid, session]
+ end
+
+ # Set a session in the cache.
+ def set_session(env, sid, session, options)
+ key = cache_key(sid)
+ if session
+ @cache.write(key, session, :expires_in => options[:expire_after])
+ else
+ @cache.delete(key)
+ end
+ sid
+ end
+
+ # Remove a session from the cache.
+ def destroy_session(env, sid, options)
+ @cache.delete(cache_key(sid))
+ generate_sid
+ end
+
+ private
+ # Turn the session id into a cache key.
+ def cache_key(sid)
+ "_session_id:#{sid}"
+ end
+ end
+ end
+end