- 更新日: 2014年2月17日
- Ruby
はてなブックマークAPIを Ruby の XMLRPC::Client で利用する時にはまった箇所
はてブ API を、Ruby の XMLRPC::Client で利用した時に、はまった箇所が2箇所あったので備忘録。
はてなブックマーク件数取得API – Hatena Developer Center を利用して はてなブックマーク総数カウンター | EasyRamble を作ったのですが、 サンプルプログラムの Perl コードを参考にして Ruby で書いた。jQuery を利用した Ajax リクエストで、Javascript のコードは WordPress の投稿記事内に直接書きました。
最初に書いた Ruby コード(簡略版)
1 2 3 4 5 6 7 8 9 10 11 12 |
EndPoint = "http://b.hatena.ne.jp/xmlrpc" server = XMLRPC::Client.new2(EndPoint) begin count = server.call('bookmark.getTotalCount', url) puts count rescue XMLRPC::FaultException => e puts "Error:" puts e.faultCode puts e.faultString end |
簡略化してますけど以上の様なコードを最初書いたところ、以降のエラーに遭遇しました。
Wrong content-type エラー
まず遭遇したのが、以下の content-type が間違ってますよ、のエラー。
1 2 3 |
/****/xmlrpc/client.rb:498:in `do_rpc': Wrong content-type (received 'application/xml' but expected 'text/xml') (RuntimeError) |
xmlrpc/client.rb:498 を確認すると…
1 2 3 4 5 6 7 8 9 10 |
# assume text/xml on instances where Content-Type header is not set ct_expected = resp["Content-Type"] || 'text/xml' ct = parse_content_type(ct_expected).first if ct != "text/xml" if ct == "text/html" raise "Wrong content-type (received '#{ct}' but expected 'text/xml'): \n#{data}" else raise "Wrong content-type (received '#{ct}' but expected 'text/xml')" end end |
Ruby のライブラリ XMLRPC::Client(xmlrpc/client)は、content-type として text/xml のみを受け取る前提になっているようです。はてブAPIを叩いて実際に受け取っているのは、application/xml。
parse_content_type メソッドは以下。xmlrpc/utils.rb の163行目〜。
1 2 3 4 5 6 7 8 9 |
module XMLRPC ... module ParseContentType def parse_content_type(str) a, *b = str.split(";") return a.strip.downcase, *b end end end |
モンキーパッチで、以下のように content-type を無理やり書き換えて text/xml を返すようにしてやる。
1 2 3 4 5 6 7 8 |
# monkey patching module XMLRPC::ParseContentType def parse_content_type(str) a, *b = str.split(";") a = "text/xml" if a == "application/xml" return a.strip.downcase, *b end end |
このコードを追加して、Wrong content-type エラーは回避出来ました。
Wrong size エラー
次に遭遇したのが、Wrong size エラー。
1 2 3 |
/*****/xmlrpc/client.rb:506:in `do_rpc': Wrong size. Was 136, should be 117 (RuntimeError) |
xmlrpc/client.rb:506 は以下。
1 2 3 4 5 6 |
expected = resp["Content-Length"] || "<unknown>" if data.nil? or data.bytesize == 0 raise "Wrong size. Was #{data.bytesize}, should be #{expected}" elsif expected != "<unknown>" and expected.to_i != data.bytesize and resp["Transfer-Encoding"].nil? raise "Wrong size. Was #{data.bytesize}, should be #{expected}" end |
今度は、Content-Length のサイズが期待されたもの値と違いますよ、という内容のエラーです。これは、XMLRPC が依存する Net::HTTP がデフォルトで HTTP 圧縮を行っているためらしい。ということで、HTTP 圧縮を行わないように header 情報を追加します。
1 2 |
server = XMLRPC::Client.new2(EndPoint) server.http_header_extra = {'accept-encoding' => 'identity'} |
以上で Wrong size エラーも回避できました。
- – 参考リンク –
- class XMLRPC::Client
- はてなブックマーク件数取得APIのXML-RPCをRubyで使う – maru source
- Ruby 2.0 で XMLRPC を使うと発生するエラー(Wrong size)とその解決法|Ruby と iPhone と UI と
- Ruby の関連記事
- Gemの作り方(Ruby Gem)
- ローカル開発中のgemをGemfileに書いてインストール
- 熊本地震の余震が夜に多いのは本当か?Rubyプログラムで検証してみた
- El Capitanでgemのnative extensionビルド失敗に対応
- Rubyで親クラスから子クラスの定数を参照
- MacabをRubyで使う
- rbenv/ruby-buildでRuby最新バージョンをインストール
- Rubyでクラスインスタンス変数にインスタンスメソッドからアクセス
- 距離1kmあたりの緯度・経度の度数を計算(日本・北緯35度)
- Google Maps Geocoding APIで住所から緯度・経度を取得するRubyコード
Leave Your Message!