2024/04/12(金)RubyのHttpClientはそろそろ捨てるべき?
2024/04/12 18:09
GitHub - nahi/httpclient: 'httpclient' gives something like the functionality of libwww-perl (LWP) in Ruby.
を使って作成していたスクレイピング的なスクリプトが動かなくなってしまった。
↓のようなエラーを吐く。
SSL_connect returned=1 errno=0 state=error: certificate verify failed (certificate has expired) (OpenSSL::SSL::SSLError)原因は、取得先のサーバーがSSL証明書をLet's Encryptに入れ替えたため。
httpclientはルート証明書がライブラリ内に同梱されており、最終更新が2015年。
Let's Encrypt系のルート証明書は未対応である。
ルート証明書がライブラリ同梱なのは今どきではないし、更新が止まっているのも痛い。
モンキーパッチがGitHub上にあるので、そちらでとりあえず対応可能。
Connection to Lets Encrypt secured server fails · Issue #445 · nahi/httpclient · GitHub
class HTTPClient alias original_initialize initialize def initialize(*args, &block) original_initialize(*args, &block) # Force use of the default system CA certs (instead of the 6 year old bundled ones) @session_manager&.ssl_config&.set_default_paths end endhttpclientは投げ捨てて、httprbを使った方が良いかも。
GitHub - httprb/http: HTTP (The Gem! a.k.a. http.rb) - a fast Ruby HTTP client with a chainable API, streaming support, and timeouts
パパっと書き換えたけど素直でかなり簡単に修正できた。
パフォーマンスも良いらしい。
なお、rubyのhttpclientでletsencryptの証明書を保有するサイトに接続できなくなった | 元祖ワシ的日記のやり方だと、Windows環境では上手くいったのだが、debian Linuxだと上手くいかなかった。
追求していない。
2024/02/23(金)Ruby XMLRPCでdokuwikiのAPIをコールするとエラー
2024/02/23 18:52
DBを使わないので遅いが、その分設置場所の選択肢が多い。
PHPが使えるフリーサーバーがいくつかあるので、小さいチーム作業や情報公開用途であれば扱いやすいと思う。
さて、dokuwikiは標準でXML-RPCによるAPIを備えているのだが、Rubyからコールしようとしてハマった。
このサンプル通り、
xmlrpc:clients:devel:xmlrpc:clients [DokuWiki]
require 'xmlrpc/client' server = XMLRPC::Client.new("localhost", "/dokuwiki/lib/exe/xmlrpc.php", 8084) result = server.call("dokuwiki.getVersion") pp resultとしてコールしても、
XML-RPC server accepts XML requests only.が返ってきてしまう。
環境は、
・dokuwiki: Release 2024-02-06a "Kaos"
・PHP: 7.4
・Ruby: 2.7
HTTPサーバは問わない。
調査。
・RubyのXMLRPCはリクエストのContent-Typeに"text/xml;charset=UTF-8"がセットされる。
・dokuwikiのXML-RPC APIは"application/xml"か"text/xml"だけを受け付ける。これはcharsetがあるのもダメっぽい?
うーん、リクエストにcharsetはあっても良いはずなので、dokuwiki側のコードがかなり変か何かを読み飛ばしてるかもしれない。
とりあえず、RubyのXMLRPCはhttp_header_extraをセットすることでヘッダーを上書きできる。
コレを使って、以下にすれば動く。
require 'xmlrpc/client' server = XMLRPC::Client.new("localhost", "/dokuwiki/lib/exe/xmlrpc.php", 8084) server.http_header_extra = {"Content-Type" => "text/xml"} result = server.call("dokuwiki.getVersion") pp result