Commons Net FTPHTTPClient: パッシブ FTP 向け HTTP プロキシトンネル
Commons Net の専用クライアントで、FTP の制御接続とパッシブデータ接続を HTTP プロキシ経由でトンネルします。
Apache Commons Net には、HTTP CONNECT プロキシ経由で FTP を使うための FTPHTTPClient が含まれています。その有用な点は FTP のログインポートに到達するだけではありません。一覧取得やファイル転送で使われるパッシブデータ接続のためにも、プロキシトンネルを確立します。
コンストラクタはプロキシのエンドポイントと任意のプロキシ資格情報を受け取ります。FTP サーバーは引き続き connect の引数であり、login は FTP アカウントを受け取ります。
FTPHTTPClient ftp = new FTPHTTPClient(
"proxy.example.net", 8080, proxyUser, proxyPassword
);
try {
ftp.connect("ftp.example.net", 21);
if (!FTPReply.isPositiveCompletion(ftp.getReplyCode())) {
throw new IOException(ftp.getReplyString());
}
if (!ftp.login(ftpUser, ftpPassword)) {
throw new IOException(ftp.getReplyString());
}
ftp.enterLocalPassiveMode();
if (!ftp.setFileType(FTP.BINARY_FILE_TYPE)
|| !ftp.retrieveFile(remoteFile, output)) {
throw new IOException(ftp.getReplyString());
}
ftp.logout();
} finally {
if (ftp.isConnected()) {
ftp.disconnect();
}
}
この転送の断片は、Commons Net の FTP インポート、java.io.IOException、アプリケーションが渡す資格情報の変数、呼び出し側が所有する出力ストリームを前提としています。remoteFile はサーバー側の想定ファイル名です。アプリケーションは適切な時点で自身の出力ストリームも閉じる必要があります。
パッシブモードは接続後、データ操作の前に設定します。FTPHTTPClient の実装はアクティブモードでのデータ接続を拒否します。パッシブモードでは FTP とデータエンドポイントをネゴシエートし、HTTP プロキシへの別の接続を開いて、そのエンドポイントへの CONNECT トンネルを要求します。
この 2 本目のトンネルはよくある境界を説明します。FTP 制御ポートに対するプロキシの許可だけでは足りません。許可する宛先とポートには、サーバーのパッシブデータエンドポイントも含める必要があります。挨拶とログインの成功は、制御経路が機能したことだけを示します。
実装は、プロキシのユーザー名とパスワードの両方が存在する場合に Basic プロキシ認証を提供します。これは FTP の USER/PASS 交換とは別です。別の認証方式を要求するプロキシには対応するコネクタが必要で、コンストラクタがすべての方式を利用可能にするわけではありません。
Commons Net はこのクラスを実験的として文書化しているため、採用前にアプリケーションとプロキシの要件に照らして評価してください。FTP クライアントであり、FTPS や SFTP のクライアントではありません。SOCKS サービスが利用できる場合の FTPS には、FTPSClient のソケットプロキシインターフェースが別のクライアント経路です。CONNECT は経路を提供するだけで、FTP 資格情報やファイル内容自体を暗号化するものではありません。
エラーは発生した段階に対応づけてください。トンネル設定時の HTTP 拒否、FTP ログインの拒否、FTP/データ転送の失敗です。FTP パスワードを変更しても、パッシブデータポートを拒否するプロキシポリシーは解決できません。