概要
reqwest
など、OpenSSLに依存しているcrateを使用する際、OpenSSL起因でビルドが失敗するなら、rustls-tls
を使うことで回避できるかもしれない。
# Cargo.toml
reqwest = { version = "0.12.7", default-features = false, features = [
"rustls-tls",
] }
課題
RustでWeb開発をしていると、HTTPクライアントであるreqwest
クレートをしばしば使用する。
しかし、reqwest
はOpenSSL(クレート名だとopenssl-sys
など)に依存しており、ローカル開発環境や、採用したいDocker
イメージによっては、下記のようなエラーにより、ビルドやバイナリの実行に失敗してしまう。
error: failed to run custom build command for `openssl-sys v0.9.103`
error while loading shared libraries: libssl.so.3: cannot open shared obj
ect file: No such file or directory
解決策
Cargo.toml
に下記の通り記載する。
# Cargo.toml
reqwest = { version = "0.12.7", default-features = false, features = [
"rustls-tls",
] }
ポイントは2つ。
-
default-features = false
:reqwest
はデフォルトでnative-tls
(こいつはopenssl-sys
に依存)に依存しているようなので、明示的にdefault-features
を無効にする。 -
features
でrustls-tls
を指定:features
に指定するだけで、native-tls
の代わりにrustls-tls
に依存してくれる。rustls-tls
は純粋なRust実装なので、共有ライブラリなどは不要。
経緯
解決策の方向性は2種類思いつく。
- OpenSSLの依存関係を用意する
- OpenSSLへの依存をやめる
本記事は主に2.OpenSSLへの依存をやめる方法について記述した。
1のアプローチも至って真っ当だが、筆者は苦しんだ果、2に行き着いた。
1の苦しみ
- 必要なライブラリがどれなのかわからない
-
apt-get install libssl-dev
はまだしも、``
-
- 必要なライブラリを入れるためのツールがわからない
- 必要なライブラリを入れても、環境によってはOpenSSLのインストールに失敗する
- OpenSSLのインストールに成功しても、Dockerのマルチステージングビルドで、ビルドしたRustのバイナリ以外にどのバイナリが必要なのかわからない
-
ldd
(Macならotool
)で共有ライブラリは調べられるけど、不足していることもある
-
2の応用
Cargo.lock
をgrep
して、openssl
に依存しているcrate
があれば、rustls-tls
に変更できないか、クレートのfeatures
を調べてみる。など。
筆者は実際に、google-cloud-starge
というクレートを使っているときに、本エラーに遭遇した。
結局、google-cloud-storage
がreqwest
に依存していたので、google-cloud-storage
のfeatures
を調べて、本記事の解決策と同様にして対応し解決した。
参考