例えば、独自の仕組みで DNS キャッシュをする社内ライブラリがあった場合に、すべての名前解決を ruby 標準のものから、そのライブラリ経由に置き換えたい。
Ruby には標準で resolv-replace.rb というものがあって、これを使うと libc の resolver を Ruby で実装している Resolv クラスに置き換えることができる。
というわけで、これを参考に、すきな Resolver にすげかえられる gem を作った。 名前になやんだけれど、resolver_replace ぐらいにしておいた。名前かぶっとる\(^o^)/
使い方はこんなかんじで、ここでは例として、ruby 標準にある Resolv::DNS を使うようにすげかえている。
require 'resolv' # Resolve::DNS
require 'resolver_replace' # ResolverReplace
resolver = Resolv::DNS.new(:nameserver => ['210.251.121.21'],
:search => ['ruby-lang.org'],
:ndots => 1)
ResolverReplace.register!(
getaddress: Proc.new {|host| resolver.getaddress(host) },
getaddresses: Proc.new {|host| resolver.getaddresses(host) },
error_class: Resolv::ResolvError,
)
これで net/http
など大体はOK。
「大体」と言っているのは、mysql2 などの ruby ライブラリを使わずに C 拡張で実装しているような gem には効かないため。 そこでそういう gem のために plugin 機構を用意した。今のところ mysql2 だけ用意していて、以下のようにして適用できる。
ResolverReplace.load_plugin('mysql2')
まとめ
Resolver をすげかえるには、https://github.com/sonots/resolver_replace を利用できる。
後記: 今だと(?)標準機能の Resolve::DefaultResolver.replace_resolvers で置き換えられそう