在Rails开发环境中,我正在尝试添加Sinatra应用程序作为中间件。 Sinatra应用程序使用geoip gem处理用户的IP地址并返回json与他们的城市。
我可以通过直接访问浏览器中的示例url或在命令行http://local.fqdn.org/geoip/locate.json?ip=24.18.211.123
中使用curl来查看返回的json。但是,当我尝试在Rails控制器中使用wget调用url时,Rails应用程序停止响应,经常崩溃我的浏览器,我的rails服务器不会使用control + C命令退出。
这里发生了什么的任何线索?为什么直接转到浏览器中的url会返回正确的响应但是我在控制器中调用会导致超时?
屈-geoip.rb
require 'sinatra'
require 'geoip'
require 'json'
# http://localhost/geoip/locate.json?ip=24.18.211.123
#
# {
# latitude: 47.684700012207
# country_name: "United States"
# area_code: 206
# city: "Seattle"
# region: "WA"
# longitude: -122.384803771973
# postal_code: "98117"
# country_code3: "USA"
# country_code: "US"
# dma_code: 819
# }
class GeoIPServer < Sinatra::Base
get '/geoip/locate.json' do
c = GeoIP.new('/var/www/mywebsite.org/current/GeoLiteCity.dat').city(params[:ip])
body c.to_h.to_json
end
end
的routes.rb
mount GeoIPServer => "/geoip"
配置/环境/ development.rb
Website::Application.configure do
require "sinatra-geoip"
config.middleware.use "GeoIPServer"
...
end
控制器
raw_geo_ip = Net::HTTP.get(URI.parse("http://#{geoip_server}/geoip/locate.json?ip=#{request.ip}"))
@geo_ip = JSON.parse(raw_geo_ip)
答案 0 :(得分:1)
我们的解决方案很难找到。我们最终在sinatra源代码调用forward
中找到了一个方法。
新sinatra-geoip.rb
class GeoIPServer < Sinatra::Base
if defined?(::Rails)
get '/properties.json' do
env["geo_ip.lookup"] = geo_ip_lookup(request.ip)
forward
end
end
def geo_ip_lookup(ip = nil)
ip = ip.nil? ? params[:ip] : ip
result = GeoIP.new('/var/www/mywebsite.org/current/GeoLiteCity.dat').city(ip)
result.to_h.to_json
end
end
基本上,我们从文件中删除了/geoip/locate.json
路由并将其转换为简单方法。我们需要在调用properties.json
时进行geoip查找,因此添加了一个带有geoip信息的新参数。然后我们将新参数设置为控制器中的@geo_ip
变量。
新属性控制器
if Rails.env.development? or Rails.env.test?
# Retrieves param set by sinatra-geoip middleware.
@geo_ip = JSON.parse(env["geo_ip.lookup"] || "{}")
else
# Production and staging code
end
相当模糊的问题和解决方案。希望它会帮助那里的人。 干杯。