Ruby gem geoip and Rack::GeoIPCountry
by Samson on Feb.25, 2010, under Ruby, Technique (709 views)
wikipedia上对于geolocation的解释是这样的:
Geolocation is the identification of the real-world geographic location of an Internet-connected computer, mobile device, website visitor or other.
检测的方法貌似也有很多:
Geolocation can be performed by associating a geographic location with the Internet Protocol (IP) address, MAC address, RFID, hardware embedded article/production number, embedded software number (such as UUID, Exif/IPTC/XMP or modern steganography), invoice, Wi-Fi connection location, or device GPS coordinates, or other, perhaps self-disclosed information.
(班门弄斧一下先,呵呵呵呵)
ruby里面取到geo信息的一个相对方便的办法是使用rubygem geoip,虽然本质上还是使用maxmind的data,但是免去了编译和安装其c library的麻烦。
安装gem并下载其depend到的geoip database:
如果想要城市信息,还可以下载稍微大一点的带city info的free database:
简单的测试一下:
require 'geoip'
p GeoIP.new('GeoIP.dat').country("google.com")
p GeoIP.new('GeoLiteCity.dat').city("baidu.com")
alright, looks good:
["baidu.com", "220.181.6.81", "CN", "CHN", "China", "AS", "22", "Beijing", "", 39.9289, 116.3883]
由于geo的普遍性,把其做成可以plug&play的Rack middleware绝对是个好主意,这就是接下来要介绍的Rack::GeoIPCountry,CodeRack Contest的first place。
其原理就是调用geoip gem获得访问IP的geo信息并写入request header,这样后面的app或者middleware就能读到并处理了。
同样写个简单的middleware测试一下:
class GeoTest
def initialize(app)
@app = app
end
def call(env)
puts "Remote Address: #{env['REMOTE_ADDR']}"
puts "GeoIP Country ID: #{env['X_GEOIP_COUNTRY_ID']}"
puts "GeoIP Country Code: #{env['X_GEOIP_COUNTRY_CODE']}"
puts "GeoIP Country Code3: #{env['X_GEOIP_COUNTRY_CODE3']}"
puts "GeoIP Country: #{env['X_GEOIP_COUNTRY']}"
puts "GeoIP Continent: #{env['X_GEOIP_CONTINENT']}"
@app.call(env)
end
end
use Rack::ContentLength
use Rack::GeoIPCountry
use GeoTest
run Proc.new { |env| [200, { 'Content-Type' => 'text/html' }, 'OK'] }
rackup起来后,访问http://localhost:9292,确认console下输出了我们想要的geo信息:
GeoIP Country ID: 0
GeoIP Country Code: --
GeoIP Country Code3: --
GeoIP Country: N/A
GeoIP Continent: --
127.0.0.1 - - [25/Feb/2010 16:36:11] "GET / HTTP/1.1" 200 2 0.0016
当然上面的127.0.0.1是不会有任何信息的,local network也是不会在database里面找到对应的,只有当真正的外网ip hit到我们的server时,我们才能看到有意义的geo信息。
February 25th, 2010 on 5:24 pm
汗,我以为走错了。。。
纳爱斯~
February 25th, 2010 on 5:29 pm
成功cosplay了唉
万德福~
August 13th, 2010 on 8:58 am
the demand for embedded software these days are getting higher and higher.`:;