Class: GeoRedirect::Middleware
- Inherits:
-
Object
- Object
- GeoRedirect::Middleware
- Defined in:
- lib/geo_redirect/middleware.rb
Instance Attribute Summary collapse
-
#config ⇒ Object
Returns the value of attribute config.
-
#db ⇒ Object
Returns the value of attribute db.
Instance Method Summary collapse
- #call(env) ⇒ Object
- #force_redirect?(url) ⇒ Boolean
- #forget_host(request, host) ⇒ Object
- #handle_force(request, url) ⇒ Object
- #handle_geoip(request) ⇒ Object
- #handle_session(request) ⇒ Object
- #host_by_country(country) ⇒ Object
- #host_by_hostname(hostname) ⇒ Object
- #hostname_by_host(host) ⇒ Object
-
#initialize(app, options = {}) ⇒ Middleware
constructor
A new instance of Middleware.
- #path_blacklisted?(url) ⇒ Boolean
- #path_not_whitelisted?(url) ⇒ Boolean
- #query_includes_skip_geo?(url) ⇒ Boolean
- #redirect_request(request, host = nil, same_host = false) ⇒ Object
- #remember_host(request, host) ⇒ Object
- #session_exists?(request) ⇒ Boolean
- #skip_redirect?(request, url) ⇒ Boolean
- #skipped_by_block?(request) ⇒ Boolean
Constructor Details
#initialize(app, options = {}) ⇒ Middleware
Returns a new instance of Middleware.
8 9 10 11 12 13 14 15 16 17 18 19 20 |
# File 'lib/geo_redirect/middleware.rb', line 8 def initialize(app, = {}) @app = app @options = @logger = init_logger([:logfile]) @db = init_db([:db] || DEFAULT_DB_PATH) @config = init_config([:config] || DEFAULT_CONFIG_PATH) @include_paths = Array([:include]) @exclude_paths = Array([:exclude]) log 'Initialized middleware' end |
Instance Attribute Details
#config ⇒ Object
Returns the value of attribute config.
6 7 8 |
# File 'lib/geo_redirect/middleware.rb', line 6 def config @config end |
#db ⇒ Object
Returns the value of attribute db.
6 7 8 |
# File 'lib/geo_redirect/middleware.rb', line 6 def db @db end |
Instance Method Details
#call(env) ⇒ Object
22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
# File 'lib/geo_redirect/middleware.rb', line 22 def call(env) request = Rack::Request.new(env) url = URI.parse(request.url) if skip_redirect?(request, url) if @options[:remember_when_skipping] remember_host(request, request_host(url)) end @app.call(env) elsif force_redirect?(url) handle_force(request, url) elsif session_exists?(request) handle_session(request) else handle_geoip(request) end end |
#force_redirect?(url) ⇒ Boolean
62 63 64 |
# File 'lib/geo_redirect/middleware.rb', line 62 def force_redirect?(url) Rack::Utils.parse_query(url.query).key? 'redirect' end |
#forget_host(request, host) ⇒ Object
146 147 148 149 |
# File 'lib/geo_redirect/middleware.rb', line 146 def forget_host(request, host) log "Forgetting: #{host}" remember_host(request, nil) end |
#handle_force(request, url) ⇒ Object
90 91 92 93 94 |
# File 'lib/geo_redirect/middleware.rb', line 90 def handle_force(request, url) log 'Handling force flag' remember_host(request, request_host(url)) redirect_request(request, url.host, true) end |
#handle_geoip(request) ⇒ Object
96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 |
# File 'lib/geo_redirect/middleware.rb', line 96 def handle_geoip(request) country = country_from_request(request) rescue nil request.session['geo_redirect.country'] = country log "GeoIP match: country code #{country.inspect}" if country.nil? @app.call(request.env) else host = host_by_country(country) # desired host log "GeoIP host match: #{host}" remember_host(request, host) redirect_request(request, host) end end |
#handle_session(request) ⇒ Object
55 56 57 58 59 60 |
# File 'lib/geo_redirect/middleware.rb', line 55 def handle_session(request) host = request.session['geo_redirect'] host = host.is_a?(Symbol) ? host : host.to_sym if host log "Handling session var: #{host}" redirect_request(request, host) end |
#host_by_country(country) ⇒ Object
127 128 129 130 |
# File 'lib/geo_redirect/middleware.rb', line 127 def host_by_country(country) hosts = @config.select { |_k, v| Array(v[:countries]).include?(country) } hosts.keys.first || :default end |
#host_by_hostname(hostname) ⇒ Object
132 133 134 135 |
# File 'lib/geo_redirect/middleware.rb', line 132 def host_by_hostname(hostname) hosts = @config.select { |_k, v| v[:host] == hostname } hosts.keys.first || :default end |
#hostname_by_host(host) ⇒ Object
137 138 139 |
# File 'lib/geo_redirect/middleware.rb', line 137 def hostname_by_host(host) host.is_a?(Symbol) ? @config[host][:host] : host end |
#path_blacklisted?(url) ⇒ Boolean
82 83 84 |
# File 'lib/geo_redirect/middleware.rb', line 82 def path_blacklisted?(url) @exclude_paths.any? { |exclude| url.path == exclude } end |
#path_not_whitelisted?(url) ⇒ Boolean
77 78 79 80 |
# File 'lib/geo_redirect/middleware.rb', line 77 def path_not_whitelisted?(url) !@include_paths.empty? && @include_paths.none? { |include| url.path == include } end |
#query_includes_skip_geo?(url) ⇒ Boolean
73 74 75 |
# File 'lib/geo_redirect/middleware.rb', line 73 def query_includes_skip_geo?(url) Rack::Utils.parse_query(url.query).key? 'skip_geo' end |
#redirect_request(request, host = nil, same_host = false) ⇒ Object
112 113 114 115 116 117 118 119 120 121 122 123 124 125 |
# File 'lib/geo_redirect/middleware.rb', line 112 def redirect_request(request, host = nil, same_host = false) hostname = hostname_by_host(host) if should_redirect?(request, hostname, same_host) url = redirect_url(request, hostname) log "Redirecting to #{url}" [301, { 'Location' => url.to_s, 'Content-Type' => 'text/plain' }, ['Moved Permanently\n']] else @app.call(request.env) end end |
#remember_host(request, host) ⇒ Object
141 142 143 144 |
# File 'lib/geo_redirect/middleware.rb', line 141 def remember_host(request, host) log "Remembering: #{host}" request.session['geo_redirect'] = host end |
#session_exists?(request) ⇒ Boolean
43 44 45 46 47 48 49 50 51 52 53 |
# File 'lib/geo_redirect/middleware.rb', line 43 def session_exists?(request) host = request.session['geo_redirect'] host = host.to_sym if host && host.respond_to?(:to_sym) if host && @config[host].nil? # Invalid var, remove it log 'Invalid session var, forgetting' forget_host(request, host) host = nil end !host.nil? end |
#skip_redirect?(request, url) ⇒ Boolean
66 67 68 69 70 71 |
# File 'lib/geo_redirect/middleware.rb', line 66 def skip_redirect?(request, url) query_includes_skip_geo?(url) || path_not_whitelisted?(url) || path_blacklisted?(url) || skipped_by_block?(request) end |
#skipped_by_block?(request) ⇒ Boolean
86 87 88 |
# File 'lib/geo_redirect/middleware.rb', line 86 def skipped_by_block?(request) @options[:skip_if] && @options[:skip_if].call(request) end |