微妙にハマったので、書いておきます。.NET Core CLI のdotnet restore
コマンドをプロキシ環境下のLinux*1で使う場合、環境変数http_proxy
は小文字で設定する必要があります。ちなみにこれはcurlコマンドでも同じです。ちなみにhttps_proxyもしくはHTTPS_PROXYはどちらでも動くのですが、少し挙動が異なるので最後に補足します。
man curl からの抜粋
The environment variables can be specified in lower case or upper case. The lower case version has precedence. http_proxy is an exception as it is only available in lower case.
せっかくなのでコードを追ってみましょう。dotnet restore
はNuGet.Coreを参照してつかっています。環境変数http_proxy
のキーはここで定義されています。
NuGet.Client/ConfigurationContants.cs at 3.4.5 · NuGet/NuGet.Client · GitHub
そして、ここで環境変数を取得していますが、この時大文字小文字は区別していません。
NuGet.Client/ProxyCache.cs at 3.4.5 · NuGet/NuGet.Client · GitHub
つまり、大文字でHTTP_PROXY
をセットしてもLinux*2では無視されてしまうのです。また、この後のコードを見るとわかるようにURLのチェックをしているので、不正なURLを指定すると警告なしで無視され、プロキシなしでアクセスを試みます。ちなみに認証付きプロキシの場合は、http://user:passowrd@host/http://<username>:<password>@proxy.com
の形式で指定すれば動くらしいのですが、手元に認証つきプロキシの環境をすぐに用意できていないので、検証していないです。
また、NuGetのAPIエンドポイントはhttps なのにhttp_proxyなのか?というのもありますが、これもコードを見ると、http_proxyが指定してあればNuGet.Clientがその値を読み取ってそのプロキシサーバーをNuGetの通信ではhttpsでも使うように設定しています。
さて、https_proxy でNuGetのリポジトリを検索してもなにもヒットしません。この環境変数を読み取ることはしていないようです。しかし、https_proxyもしくはHTTPS_PROXYに値をセットするとdotnet restore
のときに使われます。しかもhttp_proxy
とは違って不正なURLの場合も使われて、その結果URLにアクセスできない場合はエラーになります。これはなぜ起きるかというと、NuGet.Core がHTTP通信に使っている System.Net.HttpがUnixプラットフォームではcurl
ライブラリに処理を委譲しているからのようです。
corefx/src/System.Net.Http/src/System/Net/Http/Unix at master · dotnet/corefx · GitHub
さきほどの curl のmanの続きにhttps_proxyもあって、これは大文字小文字を区別しないので、どちらを設定しても使われる挙動になっていました。
なんというかわかりづらい挙動で、はまると抜け出すのが面倒な気がするのでどこかに書いてあると便利な気がするんですが、どこがいいんだろうと悩んでいるところです。
追記: よく見たら、NuGet.configのドキュメントに大文字環境変数で動くと書いていたのでPRを出しました。