エラーメッセージ
received corrupt message of type InvalidContentType
reqwest は「error sending request for url (…): client error (Connect): received corrupt message of type InvalidContentType」の末尾に、ureq は「io: received corrupt message of type InvalidContentType」としてこれを表示します。OpenSSL ベースのクライアントは、同じ状況を「wrong version number」として報告します。
rustls (via reqwest, ureq, tonic) — rustls::Error::InvalidMessage(InvalidContentType): the peer's reply is not TLS
このエラーの意味
rustls はサーバーの応答の最初のバイトを TLS レコードのコンテンツタイプとして読み取り、どの TLS レコードにもありえない値を見つけました。相手は TLS で通信していません。典型的なのは、https:// で接続したポートで「HTTP/1.1 …」と応答する HTTP サーバー、平文の gRPC サーバー、平文の HTTP を想定しているプロキシです。
発生する理由
平文の HTTP ポートに https:// で接続している
よくあるTLS を使っていないローカルの開発用サーバー、サイドカー、内部ポートです。
TLS で接続した平文のプロキシ
ときどきクライアントとは平文の HTTP でしか通信しないプロキシに対して、HTTPS_PROXY に https:// の URL を設定しています。
平文のサーバーに TLS で接続する gRPC クライアント
ときどきTLS なしで起動したサーバーに対して、https:// のエンドポイントから(または TLS の設定付きで)作成した tonic のチャネルを使っています。
修正方法
- 1.
ポートが何のプロトコルで通信しているかを確認する
平文の HTTP で応答がある場合は、http:// を使うか、サーバーの TLS ポートを使ってください。
bash curl -si http://127.0.0.1:8080/ | head -1 # plain HTTP answers -> use http:// or the TLS port - 2.
エンドポイントのスキームをサーバーに合わせる
信頼できるネットワーク上の平文の gRPC サーバーには http:// のエンドポイントを使い、それ以外の場合は TLS の設定とともに https:// を使ってください。
rust // tonic: use an http:// endpoint for plaintext servers, https:// + TLS config for TLS servers let channel = tonic::transport::Channel::from_static("http://127.0.0.1:50051").connect().await?;