Python の SOCKS 読み取りループで EOF を処理する
閉じた接続を決して来ないタイムアウトとして扱うのではなく、SOCKS の正確読み取りループで EOF を明示的に処理します。
あるループは SOCKS 応答の八バイトを求めています。三バイトは受信済みです。次の読み取りは b'' を返し、ループはそれを追加し、長さを確認し、永遠に再試行します。
これは EOF 処理のバグであり、より長いタイムアウトを必要とする遅いプロキシではありません。通常のストリームソケットの受信では、空のバイト文字列は相手が切断したことを意味します。残りの五バイトがその接続に届くことはありません。
正確読み取りヘルパーには三つの異なる結果が必要です。空でないチャンクを蓄積すること、必要な長さに達する前に EOF で失敗すること、タイムアウトやその他のソケットエラーを伝播することです。これらのケースを一つの汎用的な再試行ループにまとめてはいけません。
操作の前にソケットの意図したタイムアウトを設定し、プロキシプロトコルが指定するフィールド長を読み取ります。一回の受信で返るのは応答の一部だけです。逆に、大きな固定バッファを要求しても、すべての SOCKS アドレスがその長さになるわけではありません。
古い MSG_WAITALL のスニペットを依存関係のソースに貼り付けて、EOF、シグナル、プラットフォームの動作をカバーすると仮定して修正しないでください。保守されている実装のサポートされた修正を選ぶか、パーサーが自分のコードである場合はヘルパーの契約を意図的に実装してください。
認証情報のペイロードをログに記録せずに、期待したバイト数と受信したバイト数を保持します。「八応答バイトのうち三バイトの後に EOF」は、「プロキシがまた固まった」よりも壊れたやり取りをはるかによく説明します。