Net::SMTP 3.16 には事前接続済み SOCKS コンストラクタがない
Net::SMTP 3.16 は事前接続済みソケット用のコンストラクタオプションを文書化していません。プロキシ経由のトランスポート統合を選ぶときは、SMTP の挨拶、EHLO、TLS の順序をそのまま保ってください。
Net::SMTP 3.16 は SOCKS や事前接続済みソケットのコンストラクタ引数を文書化していません。継承された new_from_fd でファイル記述子を包んでも、その SMTP コンストラクタは実行されません。SOCKS 接続の成功はストリームを提供するのであり、初期化済みのメールセッションではありません。
平文 SMTP では、後からの STARTTLS 昇格を含め、サーバーが先に話します:
SOCKS: connection to smtp.example.net:587 succeeds
server: 220 smtp.example.net ready
client: EHLO client.example.net
server: 250-smtp.example.net
server: 250-STARTTLS
server: 250 AUTH ...これは模式的なものです。広告される拡張は変わります。挨拶自体が複数行にまたがることがあります。応答コードの後にハイフンが続けば応答は継続し、最終行がそれを終えます。EHLO の前に挨拶全体を消費してください。そうしないと、クライアントは EHLO の 250 を待っているのに古い 220 を読み、正常な接続で調子を外すことがあります。
暗黙的 TLS は順序が異なります。SOCKS 接続、TLS ハンドシェイク、そして TLS 内部で SMTP の挨拶です。STARTTLS は読める挨拶と EHLO から始まり、ストリームを昇格し、その後に能力を再取得します。
公開コンストラクタは通常、ソケット設定、保存された接続パラメータと挨拶情報、初期応答、そして適切な場合は HELO フォールバック付きの EHLO を扱います:
use Net::SMTP;
my $smtp = Net::SMTP->new(
'smtp.example.net',
Port => 587,
Hello => 'client.example.net',
Timeout => 30,
) or die "SMTP connection failed: $@";
$smtp->starttls()
or die "STARTTLS failed: " . $smtp->message;この公開例は STARTTLS を使い、SOCKS を設定しません。サーバー名がメールの宛先を選び、Hello がクライアントの SMTP 識別情報を与えます。暗黙的 TLS では、文書化された SSL コンストラクタオプションとサービスのポートを使ってください。
SendHello => 0 は自動 EHLO/HELO を抑止しますが、挨拶の読み取りやトランスポートの構築は抑止しません。行リーダを呼んでから hello() を呼ぶことも、初期化の文書化された代替ではありません。Net::Cmd は低レベルの応答リーダを保護されたサブクラスメソッドとして分類しています。
SOCKS が必須なら、対応する SOCKS インターフェースを持つクライアントを選ぶか、特定の Net::SMTP バージョンに対する統合を維持してください。私有フィールドをコピーするのではなく、上記の順序をその契約として使ってください。別個の TCP アダプタにも意図的な TLS 識別情報の扱いが必要です。証明書は実際のメールサービスを識別しなければならず、プロキシの資格情報は SMTP ログインとは別のままです。