rack-geoipcity 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +3 -0
- data/README +47 -0
- data/lib/rack/geoipcity/version.rb +5 -0
- data/lib/rack/geoipcity.rb +69 -0
- data/rack-geoipcity.gemspec +22 -0
- metadata +65 -0
data/.gitignore
ADDED
data/README
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
Rack::GeoIPCity uses the geoip gem and the GeoIP database to lookup the geographical info of a request by its IP address
|
2
|
+
The database can be downloaded from:
|
3
|
+
|
4
|
+
(Lite version) http://geolite.maxmind.com/download/geoip/database/GeoLiteCity.dat.gz, instructions are here http://www.maxmind.com/app/geolitecity.
|
5
|
+
|
6
|
+
http://www.maxmind.com/app/city for full version.
|
7
|
+
|
8
|
+
*NOTE!* If you're using the country database you'll get a different struct returned, so use the GeoIPCountry gem, rack-geoipcountry. I'd make this middleware do both but:
|
9
|
+
|
10
|
+
a) It would be slower
|
11
|
+
b) there's already a country gem and
|
12
|
+
c) you can do the branching yourself if you really want, but why would you?
|
13
|
+
|
14
|
+
Usage:
|
15
|
+
======
|
16
|
+
|
17
|
+
use Rack::GeoIPCity, :db => "path/to/GeoIP.dat"
|
18
|
+
|
19
|
+
By default all requests are looked up and the X\_GEOIP\_* headers are added to the request
|
20
|
+
The headers can then be read in the application
|
21
|
+
The country name is added to the request header as X\_GEOIP\_COUNTRY, eg:
|
22
|
+
X\_GEOIP\_COUNTRY: United Kingdom
|
23
|
+
|
24
|
+
The full set of GEOIP request headers is below:
|
25
|
+
X\_GEOIP\_COUNTRY\_CODE - The ISO3166-1 two-character country code, if not found set to --
|
26
|
+
X\_GEOIP\_COUNTRY\_CODE3 - The ISO3166-2 three-character country code, if not found set to --
|
27
|
+
X\_GEOIP\_COUNTRY - The ISO3166 English-language name of the country, if not found set to an empty string
|
28
|
+
X\_GEOIP\_CONTINENT if not found set to an empty string
|
29
|
+
X\_GEOIP\_REGION\_NAME if not found set to an empty string
|
30
|
+
X\_GEOIP\_CITY\_NAME if not found set to an empty string
|
31
|
+
X\_GEOIP\_POSTAL\_CODE if not found set to an empty string
|
32
|
+
X\_GEOIP\_LATITUDE if not found won't be returned as I can't think of another good return value to signify "not found"
|
33
|
+
X\_GEOIP\_LONGITUDE if not found won't be returned as I can't think of another good return value to signify "not found"
|
34
|
+
'X\_GEOIP\_DMA\_CODE' The metropolitan code (this is for the USA, see http://code.google.com/apis/adwords/docs/appendix/metrocodes.html if you're interested), default 0 for not found.
|
35
|
+
X\_GEOIP\_AREA\_CODE if not found set to an empty string
|
36
|
+
X\_GEOIP\_TIMEZONE if not found set to an empty string
|
37
|
+
X\_GEOIP\_CONTINENT - The two-character continent code, if not found set to an empty string
|
38
|
+
|
39
|
+
|
40
|
+
You can use the included Mapping class to trigger lookup only for certain requests by specifying matching path prefix in options, eg:
|
41
|
+
use Rack::GeoIPCity::Mapping, :prefix => '/video\_tracking'
|
42
|
+
The above will lookup IP addresses only for requests matching /video\_tracking etc.
|
43
|
+
|
44
|
+
MIT License -
|
45
|
+
Originally by Karol Hosiawa ( http://twitter.com/hosiawak )
|
46
|
+
Converted to a gem by Thomas Maurer
|
47
|
+
This one by Iain Barnett
|
@@ -0,0 +1,69 @@
|
|
1
|
+
require 'geoip'
|
2
|
+
|
3
|
+
module Rack
|
4
|
+
|
5
|
+
# See the README for more docs
|
6
|
+
class GeoIPCity
|
7
|
+
def initialize(app, options = {})
|
8
|
+
options[:db] ||= 'GeoIP.dat'
|
9
|
+
@db = GeoIP.new(options[:db])
|
10
|
+
@app = app
|
11
|
+
end
|
12
|
+
|
13
|
+
DEFAULTS = {
|
14
|
+
'X_GEOIP_COUNTRY_CODE' => 0,
|
15
|
+
'X_GEOIP_COUNTRY_CODE3' => 0,
|
16
|
+
'X_GEOIP_COUNTRY' => '',
|
17
|
+
'X_GEOIP_CONTINENT' => '',
|
18
|
+
'X_GEOIP_REGION_NAME' => '',
|
19
|
+
'X_GEOIP_CITY_NAME' => '',
|
20
|
+
'X_GEOIP_POSTAL_CODE' => '' ,
|
21
|
+
'X_GEOIP_LATITUDE' => nil,
|
22
|
+
'X_GEOIP_LONGITUDE' => nil,
|
23
|
+
'X_GEOIP_DMA_CODE' => 0,
|
24
|
+
'X_GEOIP_AREA_CODE' => 0,
|
25
|
+
'X_GEOIP_TIMEZONE' => '',
|
26
|
+
}
|
27
|
+
|
28
|
+
def call(env)
|
29
|
+
res = @db.city(env['REMOTE_ADDR'])
|
30
|
+
|
31
|
+
unless res.nil? # won't bork on local or bad ip's
|
32
|
+
hash = {}
|
33
|
+
hash['X_GEOIP_COUNTRY_CODE'] = res.country_code2 unless res.country_code2.nil?
|
34
|
+
hash['X_GEOIP_COUNTRY_CODE3'] = res.country_code3 unless res.country_code3.nil?
|
35
|
+
hash['X_GEOIP_COUNTRY'] = res.country_name unless res.country_name.nil?
|
36
|
+
hash['X_GEOIP_CONTINENT'] = res.continent_code unless res.continent_code.nil?
|
37
|
+
hash['X_GEOIP_REGION_NAME'] = res.region_name unless res.region_name.nil?
|
38
|
+
hash['X_GEOIP_CITY_NAME'] = res.city_name unless res.city_name.nil?
|
39
|
+
hash['X_GEOIP_POSTAL_CODE'] = res.postal_code unless res.postal_code.nil?
|
40
|
+
hash['X_GEOIP_LATITUDE'] = res.latitude
|
41
|
+
hash['X_GEOIP_LONGITUDE'] = res.longitude
|
42
|
+
hash['X_GEOIP_DMA_CODE'] = res.dma_code unless res.dma_code.nil?
|
43
|
+
hash['X_GEOIP_AREA_CODE'] = res.area_code unless res.area_code.nil?
|
44
|
+
hash['X_GEOIP_TIMEZONE'] = res.timezone unless res.timezone.nil?
|
45
|
+
|
46
|
+
hash.delete_if{|k,v| v.nil? } # remove latitude and longitude and any other stragglers
|
47
|
+
env.merge!( DEFAULTS.merge hash )
|
48
|
+
end
|
49
|
+
|
50
|
+
@app.call(env)
|
51
|
+
end
|
52
|
+
|
53
|
+
class Mapping
|
54
|
+
def initialize(app, options = {})
|
55
|
+
@app, @prefix = app, /^#{options.delete(:prefix)}/
|
56
|
+
@geoip = GeoIPCity.new(app, options)
|
57
|
+
end
|
58
|
+
|
59
|
+
def call(env)
|
60
|
+
if env['PATH_INFO'] =~ @prefix
|
61
|
+
@geoip.call(env)
|
62
|
+
else
|
63
|
+
@app.call(env)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
69
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "rack/geoipcity/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "rack-geoipcity"
|
7
|
+
s.version = Rack::GeoIPCity::VERSION
|
8
|
+
s.platform = Gem::Platform::RUBY
|
9
|
+
s.authors = ["Karol Hosiawa", "Thomas Maurer", "Iain Barnett"]
|
10
|
+
s.email = ["iainspeed@gmail.com"]
|
11
|
+
s.homepage = "https://github.com/yb66/Rack-GeoIPCity"
|
12
|
+
s.summary = %q{Rack middleware for Geo IP city lookup}
|
13
|
+
s.description = %q{Rack::GeoIPCity uses the geoip gem and the GeoIP database to lookup the city of a request by its IP address}
|
14
|
+
s.license = 'MIT'
|
15
|
+
|
16
|
+
s.add_dependency 'geoip'
|
17
|
+
|
18
|
+
s.files = `git ls-files`.split("\n")
|
19
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
20
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
21
|
+
s.require_paths = ["lib"]
|
22
|
+
end
|
metadata
ADDED
@@ -0,0 +1,65 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rack-geoipcity
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Karol Hosiawa
|
9
|
+
- Thomas Maurer
|
10
|
+
- Iain Barnett
|
11
|
+
autorequire:
|
12
|
+
bindir: bin
|
13
|
+
cert_chain: []
|
14
|
+
date: 2011-06-24 00:00:00.000000000Z
|
15
|
+
dependencies:
|
16
|
+
- !ruby/object:Gem::Dependency
|
17
|
+
name: geoip
|
18
|
+
requirement: &2152901760 !ruby/object:Gem::Requirement
|
19
|
+
none: false
|
20
|
+
requirements:
|
21
|
+
- - ! '>='
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: '0'
|
24
|
+
type: :runtime
|
25
|
+
prerelease: false
|
26
|
+
version_requirements: *2152901760
|
27
|
+
description: Rack::GeoIPCity uses the geoip gem and the GeoIP database to lookup the
|
28
|
+
city of a request by its IP address
|
29
|
+
email:
|
30
|
+
- iainspeed@gmail.com
|
31
|
+
executables: []
|
32
|
+
extensions: []
|
33
|
+
extra_rdoc_files: []
|
34
|
+
files:
|
35
|
+
- .gitignore
|
36
|
+
- README
|
37
|
+
- lib/rack/geoipcity.rb
|
38
|
+
- lib/rack/geoipcity/version.rb
|
39
|
+
- rack-geoipcity.gemspec
|
40
|
+
homepage: https://github.com/yb66/Rack-GeoIPCity
|
41
|
+
licenses:
|
42
|
+
- MIT
|
43
|
+
post_install_message:
|
44
|
+
rdoc_options: []
|
45
|
+
require_paths:
|
46
|
+
- lib
|
47
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
48
|
+
none: false
|
49
|
+
requirements:
|
50
|
+
- - ! '>='
|
51
|
+
- !ruby/object:Gem::Version
|
52
|
+
version: '0'
|
53
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
54
|
+
none: false
|
55
|
+
requirements:
|
56
|
+
- - ! '>='
|
57
|
+
- !ruby/object:Gem::Version
|
58
|
+
version: '0'
|
59
|
+
requirements: []
|
60
|
+
rubyforge_project:
|
61
|
+
rubygems_version: 1.8.5
|
62
|
+
signing_key:
|
63
|
+
specification_version: 3
|
64
|
+
summary: Rack middleware for Geo IP city lookup
|
65
|
+
test_files: []
|