rbenv installが成功しない時は、環境変数「RUBY_BUILD_CURL_OPTS」を使ってみよう。

[Vagrant](https://www.vagrantup.com/)で作成しているローカルの開発環境で、`ruby`を入れる際、`rbenv`を使おうとしました（`Vagrant`なので、基本的に`root`で作業しています）。

`rbenv`のインストール自体は完了しましたが、`rbenv`で、いざ`ruby`をインストールしようとすると、以下のエラーが出ました。

```
[root@localhost ~]# rbenv install 2.6.6
Downloading ruby-2.6.6.tar.bz2...
-> https://cache.ruby-lang.org/pub/ruby/2.6/ruby-2.6.6.tar.bz2
error: failed to download ruby-2.6.6.tar.bz2

BUILD FAILED (CentOS Linux 7 using ruby-build 20200520-2-gf00582b)
```

## `curl`の失敗

ファイルをダウンロードできないようです。調べてみると、`rbenv`ではファイルのダウンロードに`curl`を使ってることが分かりました。

実は、この作業をしていた環境は、proxyの内部であったので、おそらくネットワーク周りが原因だろうと当たりをつけて、`curl`単体を実行して、その挙動を確認してみました。

```
[root@localhost ~]# curl https://cache.ruby-lang.org/pub/ruby/2.6/ruby-2.6.6.tar.bz2
curl: (60) Peer's Certificate issuer is not recognized.
More details here: http://curl.haxx.se/docs/sslcerts.html

curl performs SSL certificate verification by default, using a "bundle"
 of Certificate Authority (CA) public keys (CA certs). If the default
 bundle file isn't adequate, you can specify an alternate file
 using the --cacert option.
If this HTTPS server uses a certificate signed by a CA represented in
 the bundle, the certificate verification probably failed due to a
 problem with the certificate (it might be expired, or the name might
 not match the domain name in the URL).
If you'd like to turn off curl's verification of the certificate, use
 the -k (or --insecure) option.
```

## プロキシ設定

`curl`も失敗しました。どうも原因は「SSL認証が上手く行ってない」もしくは「プロキシが上手く設定できてない」の、いずれかのようです。なので、まず可能性が高いプロキシ関係の設定をしてみました。

`vi ~/.curlrc`でプロキシを設定。

```
proxy-user="{ユーザー名}:{パスワード}"
proxy = "http:/{プロキシ}:{ポート番号}/"
```

設定後、`curl`を実行してみました。エラーメッセージは少し変化しましたが、上手く行きません（ちなみに、前項と指定バージョンが違ってますが、あれこれとバージョンを切り替えて試していたためです）。

```
[root@localhost ~]# curl -v https://cache.ruby-lang.org/pub/ruby/2.7/ruby-2.7.1.tar.bz2
* Could not resolve proxy: http; 不明なエラー
* Closing connection 0
curl: (5) Could not resolve proxy: http; 不明なエラー
```
## オプションによるプロキシ指定により、`curl`単体は成功

`curl`には、直接、プロキシなどを設定できる`-x`パラメータと、ついでにファイルダウンロードで使用する`-O`、SSL接続で証明書エラーをスキップするパラメータ`-k`を実行すると、`curl`単体でのダウンロードは上手く行きました。

```
curl -k -x http://{ユーザー名}:{パスワード}@{プロキシ}:{ポート番号}/ -v -O https://cache.ruby-lang.org/pub/ruby/2.7/ruby-2.7.1.tar.bz2

...
...
...

  0 11.9M    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0{ [data not shown]
100 11.9M  100 11.9M    0     0  1314k      0  0:00:09  0:00:09 --:--:-- 1658k
```

## エイリアスを指定。`curl`は成功。しかし、`rbenv`は失敗。

やはりプロキシが原因のようだと分かりました。`rbenv`でも、このパラメータを利用するために、次に`curl`のエイリアスに、同じパラメータを設定してみました。

`vi /etc/bashrc`で、末尾に以下を設定。

```
alias curl="curl -k -x http://{ユーザー名}:{パスワード}@{プロキシ}:{ポート番号}/"
```

`source ~/.bashrc`で設定を再読み込みして、`-x`と`-k`を省略して`curl`を設定すると、curl単体では成功。

```
curl -v -O https://cache.ruby-lang.org/pub/ruby/2.4/ruby-2.4.1.tar.bz2

100 11.9M  100 11.9M    0     0  1853k      0  0:00:06  0:00:06 --:--:-- 1899k
```

しかし、`rbenv`の方は、上手く行かない。

```
[root@localhost ~]# rbenv install 2.6.6
Downloading ruby-2.6.6.tar.bz2...
-> https://cache.ruby-lang.org/pub/ruby/2.6/ruby-2.6.6.tar.bz2
error: failed to download ruby-2.6.6.tar.bz2

BUILD FAILED (CentOS Linux 7 using ruby-build 20200520-2-gf00582b)
```

## `ruby-build`の環境変数`RUBY_BUILD_CURL_OPTS`を利用し、`rbenv`も成功。

あれこれと考えてみて、[rbenv](https://github.com/rbenv/rbenv)と、[ruby-build](https://github.com/rbenv/ruby-build)のGithubページを眺めていると、`curl`のオプションを指定できる環境変数`RUBY_BUILD_CURL_OPTS`がある事に気づく。

以下のように実行すると、成功。

```
[root@localhost ~]# RUBY_BUILD_CURL_OPTS="-k -x http://{ユーザー名}:{パスワード}@{プロキシ}:{ポート番号}/" rbenv install 2.7.1
Downloading ruby-2.7.1.tar.bz2...
-> https://cache.ruby-lang.org/pub/ruby/2.7/ruby-2.7.1.tar.bz2
Installing ruby-2.7.1...

Installed ruby-2.7.1 to /root/.rbenv/versions/2.7.1

[root@localhost ~]# rbenv global 2.7.1
[root@localhost ~]# rbenv rehash
[root@localhost ~]# ruby -v
ruby 2.7.1p83 (2020-03-31 revision a0c7c23c9c) [x86_64-linux]
[root@localhost ~]#
```

成功しました。`RUBY_BUILD_CURL_OPTS`を使う方法というのが、自分が検索した限りでは見当たらなかったので、メモとして残しておきます。

他に、`RUBY_BUILD_HTTP_CLIENT`というパラメータを使うと、`aria2c`や`wget`を使うように指定できるみたいなので、`curl`そのものが使えない環境の人は、`RUBY_BUILD_HTTP_CLIENT`を使うと良いかもしれません。