トラックバック先の AutoDiscovery
RDF に基づいて、渡されたパーマリンクに対するトラックバック Ping URL を自動検出します。
参考: トラックバック技術仕様書
トラックバック関連の gem ってないんですかね。
Timeout::Error も捕捉しています。
require 'net/http' require 'uri' Net::HTTP.version_1_2 class Trackback def self.discover(url) uri = URI(url) begin Net::HTTP.start(uri.host, uri.port) { |http| req = Net::HTTP::Get.new(uri.request_uri) req['User-Agent'] = 'TrackBack/1.0' http.request(req) { |response| return nil unless response.code == '200' content = response.body url_no_anchor = url.sub(/#.*$/, '') content.scan(%r!<rdf:RDF.*?</rdf:RDF>!m) do |rdf| perm_url = (rdf =~ /dc:identifier="([^"]+)"/m) ? $1 : nil next unless perm_url == url || perm_url == url_no_anchor if rdf =~ /trackback:ping="([^"]+)"/m return $1 elsif rdf =~ /about="([^"]+)"/m return $1 end end } } rescue Timeout::Error end nil end end
テスト。書きづらいです。FakeWeb を使っています。
describe '::discover' do def fakeweb_stub(name) path = File.expand_path("../fakeweb_stubs/#{ name }.html", File.dirname(__FILE__)) open(path) { |f| f.read } end before { FakeWeb.clean_registry } it 'は、RDF に基づいて、トラックバック先を自動検出すること' do FakeWeb.register_uri(:get, 'http://d.hatena.ne.jp/milk1000cc/20090507/1241702656', :string => fakeweb_stub(:article)) Trackback.discover('http://d.hatena.ne.jp/milk1000cc/20090507/1241702656').should == 'http://d.hatena.ne.jp/milk1000cc/20090507/1241702656/tb' Trackback.discover('http://d.hatena.ne.jp/milk1000cc/20090507/1241702656#fuga').should == 'http://d.hatena.ne.jp/milk1000cc/20090507/1241702656/tb' FakeWeb.register_uri(:get, 'http://d.hatena.ne.jp/milk1000cc/20090507/1241702657', :string => fakeweb_stub(:article2)) Trackback.discover('http://d.hatena.ne.jp/milk1000cc/20090507/1241702657').should == 'http://d.hatena.ne.jp/milk1000cc/20090507/1241702657/abt' Trackback.discover('http://d.hatena.ne.jp/milk1000cc/20090507/1241702657#fuga').should == 'http://d.hatena.ne.jp/milk1000cc/20090507/1241702657/abt' FakeWeb.register_uri(:get, 'http://d.hatena.ne.jp/milk1000cc/', :string => fakeweb_stub(:index)) Trackback.discover('http://d.hatena.ne.jp/milk1000cc/').should be_nil Trackback.discover('http://d.hatena.ne.jp/milk1000cc/#fuga').should be_nil end it 'は、HTTP ステータスコードが 200 以外ならば、nil を返すこと' do FakeWeb.register_uri(:get, 'http://example.com/404', :string => 'Not Found', :status => ['404', 'Not Found']) Trackback.discover('http://example.com/404').should be_nil end it 'は、タイムアウトしたら nil を返すこと' do Net::HTTP.stub!(:start).and_raise(Timeout::Error.new('execution expired')) Trackback.discover('http://example.com').should be_nil end end