1

Rails 開発環境で、Sinatra アプリをミドルウェアとして追加しようとしています。Sinatra アプリは、ユーザーの IP アドレスを処理し、都市とともに json を返すgeoip gemを使用します。

返された json を表示するには、ブラウザーでサンプル URL に直接アクセスするか、コマンド ラインで curl を使用しhttp://local.fqdn.org/geoip/locate.json?ip=24.18.211.123ます。ただし、Rails コントローラー内から wget を使用して URL を呼び出そうとすると、Rails アプリが応答を停止し、ブラウザーが頻繁にクラッシュし、Rails サーバーが control+C コマンドを使用して終了しません。

ここで何が起こっているかの手がかりはありますか?ブラウザーで URL に直接アクセスすると適切な応答が返されるのに、コントローラーで呼び出しを行うとタイムアウトになるのはなぜですか?

sinatra-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

ルート.rb

mount GeoIPServer => "/geoip"

config/environments/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)
4

1 に答える 1

1

私たちの解決策は見つけるのが困難でした。最終的に、sinatra ソース コード call でメソッドを見つけました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、ファイルからルートを削除し、単純なメソッドに変換しました。が呼び出されたときに geoip ルックアップが発生する必要がproperties.jsonあったため、新しいパラメーターが 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

むしろあいまいな問題と解決策。うまくいけば、それが誰かを助けるでしょう。乾杯。

于 2013-10-04T20:48:16.527 に答える