Apache Commons Net includes FTPHTTPClient for FTP through an HTTP CONNECT proxy. Its useful feature is not merely reaching the FTP login port: it also establishes proxy tunnels for passive data connections used by listings and file transfers.

The constructor accepts the proxy endpoint and optional proxy credentials. The FTP server remains the argument to connect, and login receives the FTP account:

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();
    }
}

This transfer fragment assumes Commons Net's FTP imports, java.io.IOException, application-supplied credential variables and an output stream owned by the caller. remoteFile is the intended server-side filename. The application must also close its output stream at the appropriate point.

Set passive mode after connecting and before a data operation. FTPHTTPClient's implementation rejects data connections in active mode. In passive mode, it negotiates the data endpoint with FTP and opens another connection to the HTTP proxy, then requests a CONNECT tunnel to that endpoint.

That second tunnel explains a common boundary: proxy permission for the FTP control port is not enough. The permitted destinations and ports must include the server's passive data endpoints. A successful greeting and login prove only that the control route worked.

The implementation supplies Basic proxy authentication when both proxy username and password are present. That is distinct from the FTP USER/PASS exchange. A proxy requiring another authentication mechanism needs a compatible connector; the constructor does not make every scheme available.

Commons Net documents this class as experimental, so evaluate it against the application and proxy requirements before adopting it. It is an FTP client, not an FTPS or SFTP client. For FTPS with an available SOCKS service, FTPSClient’s socket-proxy interface is a separate client path. CONNECT provides the route and does not itself encrypt FTP credentials or file contents.

Keep errors attached to the stage that produced them: an HTTP rejection during tunnel setup, an FTP login refusal, or an FTP/data-transfer failure. Replacing the FTP password cannot resolve a proxy policy that rejects the passive data port.

Winndannde jowitiiɗe heen