lib/eeny-meeny/middleware.rb in eeny-meeny-2.1.4 vs lib/eeny-meeny/middleware.rb in eeny-meeny-2.2.0
- old
+ new
@@ -22,48 +22,75 @@
def call(env)
cookies = Rack::Utils.parse_query(env[HTTP_COOKIE],';,') { |s| Rack::Utils.unescape(s) rescue s }
query_parameters = query_hash(env)
now = Time.zone.now
new_cookies = {}
+ delete_cookies = find_deprecated_cookies(cookies, now)
# Prepare for experiments.
@experiments.each do |experiment|
# Skip inactive experiments
next unless experiment.active?(now)
- # Trigger experiment through query parameters
- cookie_name = EenyMeeny::Cookie.cookie_name(experiment)
- has_experiment_trigger = EenyMeeny.config.query_parameters[:experiment] && query_parameters.key?(cookie_name)
- # skip experiments that already have a cookie
- next unless has_experiment_trigger || !cookies.key?(cookie_name)
- cookie = if has_experiment_trigger
- # Trigger experiment variation through query parameter.
- EenyMeeny::Cookie.create_for_experiment_variation(experiment, query_parameters[cookie_name].to_sym, @cookie_config)
- else
- EenyMeeny::Cookie.create_for_experiment(experiment, @cookie_config)
- end
- # Set HTTP_COOKIE header to enable experiment on first pageview
- env = add_or_replace_http_cookie(env, cookie)
- new_cookies[cookie.name] = cookie
+ env, new_cookies = prepare_experiment(env, cookies, new_cookies, query_parameters, experiment)
end
- # Prepare smoke tests (if enabled through query parameters)
- if EenyMeeny.config.query_parameters[:smoke_test]
- if query_parameters.key?('smoke_test_id') && (query_parameters['smoke_test_id'] =~ /\A[A-Za-z_]+\z/)
- # Set HTTP_COOKIE header to enable smoke test on first pageview
- cookie = EenyMeeny::Cookie.create_for_smoke_test(query_parameters['smoke_test_id'], @cookie_config)
- env = add_or_replace_http_cookie(env, cookie)
- new_cookies[cookie.name] = cookie
- end
- end
+ # Prepare smoke tests
+ env, new_cookies = prepare_smoke_test(env, new_cookies, query_parameters)
# Delegate to app
status, headers, body = @app.call(env)
response = Rack::Response.new(body, status, headers)
# Add new cookies to 'Set-Cookie' header
new_cookies.each do |key, value|
response.set_cookie(key,value.to_h)
end
+ delete_cookies.each do |key, value|
+ response.delete_cookie(key, value: value, path: @cookie_config[:path], same_site: @cookie_config[:same_site])
+ end
response.finish
end
private
+
+ def find_deprecated_cookies(cookies, now)
+ deprecated_cookies = {}
+ cookies.each do |cookie_name, value|
+ # Skip any cookie that does not have the 'eeny_meeny_' prefix
+ next unless cookie_name.to_s.start_with?(EenyMeeny::Cookie::EXPERIMENT_PREFIX)
+ # Mark cookies that does not match any existing active experiment as 'deprecated'.
+ experiment = EenyMeeny::Experiment.find_by_cookie_name(cookie_name)
+ next if experiment && experiment.active?(now)
+ deprecated_cookies[cookie_name] = value
+ end
+ deprecated_cookies
+ end
+
+ def prepare_experiment(env, cookies, new_cookies, query_parameters, experiment)
+ # Trigger experiment through query parameters
+ cookie_name = EenyMeeny::Cookie.cookie_name(experiment)
+ has_experiment_trigger = EenyMeeny.config.query_parameters[:experiment] && query_parameters.key?(cookie_name)
+ # Skip experiments that already have a cookie
+ return env, new_cookies unless has_experiment_trigger || !cookies.key?(cookie_name)
+ cookie = if has_experiment_trigger
+ # Trigger experiment variation through query parameter.
+ EenyMeeny::Cookie.create_for_experiment_variation(experiment, query_parameters[cookie_name].to_sym, @cookie_config)
+ else
+ EenyMeeny::Cookie.create_for_experiment(experiment, @cookie_config)
+ end
+ # Set HTTP_COOKIE header to enable experiment on first pageview
+ env = add_or_replace_http_cookie(env, cookie)
+ new_cookies[cookie.name] = cookie
+ return env, new_cookies
+ end
+
+ def prepare_smoke_test(env, new_cookies, query_parameters)
+ # Skip if the EenyMeeny 'smoke test' query parameters configuration is disabled.
+ return env, new_cookies unless EenyMeeny.config.query_parameters[:smoke_test]
+ # Skip if no valid 'smoke_test_id' query parameter present
+ return env, new_cookies unless query_parameters.key?('smoke_test_id') && (query_parameters['smoke_test_id'] =~ /\A[A-Za-z_]+\z/)
+ # Set HTTP_COOKIE header to enable smoke test on first pageview
+ cookie = EenyMeeny::Cookie.create_for_smoke_test(query_parameters['smoke_test_id'], @cookie_config)
+ env = add_or_replace_http_cookie(env, cookie)
+ new_cookies[cookie.name] = cookie
+ return env, new_cookies
+ end
def query_hash(env)
# Query Params are only relevant if EenyMeeny.config have them enabled.
return {} unless EenyMeeny.config.query_parameters[:experiment] || EenyMeeny.config.query_parameters[:smoke_test]
# Query Params are only relevant to HTTP GET requests.