lib/safe_cookies.rb in safe_cookies-0.1.6 vs lib/safe_cookies.rb in safe_cookies-0.1.7

- old
+ new

@@ -3,10 +3,11 @@ require "safe_cookies/cookie_path_fix" require "safe_cookies/helpers" require "safe_cookies/util" require "safe_cookies/version" require "rack" +require "time" # add Time#rfc2822 # Naming: # - application_cookies: cookies received from the application. The 'Set-Cookie' header is a string # - request_cookies: cookies received from the client. Rack::Request#cookies returns a Hash of { 'name' => 'value' } @@ -26,20 +27,20 @@ COOKIE_NAME_REGEX = /(?=^|\n)[^\n;,=]+/i def initialize(app) @app = app - @configuration = SafeCookies.configuration or raise "Don't know what to do without configuration" + @config = SafeCookies.configuration or raise "Don't know what to do without configuration" end def call(env) reset_instance_variables @request = Rack::Request.new(env) - ensure_no_unknown_cookies_in_request! + check_if_request_has_unknown_cookies - # calling the next middleware + # call the next middleware up the stack status, @headers, body = @app.call(env) cache_application_cookies_string enhance_application_cookies! store_application_cookie_names @@ -50,26 +51,27 @@ [ status, @headers, body ] end private + # Instance variables survive requests because the middleware is a singleton. def reset_instance_variables @request, @headers, @application_cookies_string = nil end - # Make sure we get notified if a client comes with an unregistered cookie, - # because we do not want any cookie not to be secured. - def ensure_no_unknown_cookies_in_request! + # Do something if a request has an unregistered cookie, because we do not + # want any cookie to not be secured. By default, we raise an error. + def check_if_request_has_unknown_cookies request_cookie_names = request_cookies.keys.map(&:to_s) unknown_cookie_names = request_cookie_names - known_cookie_names if unknown_cookie_names.any? handle_unknown_cookies(unknown_cookie_names) end end - # Overwrites @header['Set-Cookie'] + # Overwrites @header['Set-Cookie']! def enhance_application_cookies! if @application_cookies_string cookies = @application_cookies_string.split("\n") # On Rack 1.1, cookie values sometimes contain trailing newlines. @@ -88,12 +90,12 @@ # us. A `Rack::Response` doesn't offer a way either. @headers['Set-Cookie'] = cookies.join("\n") end end - # Store the names of cookies that are set by the application. We are already - # securing those and therefore do not need to rewrite them. + # Store the names of cookies that are set by the application. + # (We are already securing those and will not need to rewrite them.) def store_application_cookie_names if @application_cookies_string application_cookie_names = stored_application_cookie_names + @application_cookies_string.scan(COOKIE_NAME_REGEX) application_cookies_string = application_cookie_names.uniq.join(KNOWN_COOKIES_DIVIDER) @@ -105,26 +107,24 @@ # making them both secure and http-only (unless specified otherwise in # the configuration). # With the SECURED_COOKIE_NAME cookie we remember the exact time that we # rewrote the cookies. def rewrite_request_cookies - cookies_to_rewrite = request_cookies || [] + rewritable_cookies = rewritable_request_cookies # don't rewrite request cookies that the application is setting in the response if @application_cookies_string - application_cookie_names = @application_cookies_string.scan(COOKIE_NAME_REGEX) - Util.except!(cookies_to_rewrite, *application_cookie_names) + app_cookie_names = @application_cookies_string.scan(COOKIE_NAME_REGEX) + Util.except!(rewritable_cookies, *app_cookie_names) end - if cookies_to_rewrite.any? - registered_cookies_in_request.each do |cookie_name, options| - value = request_cookies[cookie_name] - + if rewritable_cookies.any? + rewritable_cookies.each do |cookie_name, value| + options = @config.registered_cookies[cookie_name] set_cookie!(cookie_name, value, options) end - formatted_now = Rack::Utils.rfc2822(Time.now.gmtime) - set_cookie!(SECURED_COOKIE_NAME, formatted_now, :expire_after => HELPER_COOKIES_LIFETIME) + set_cookie!(SECURED_COOKIE_NAME, Time.now.gmtime.rfc2822, :expire_after => HELPER_COOKIES_LIFETIME) end end # API method def handle_unknown_cookies(cookie_names)