I am working on a application that connects to an SFTP server and downloads files using Apache Commons VFS, it works just fine, with the exception that the system needs to allow the user to specify a proxy, as needed.
Now, I know Apache Commons VFS is built on top of Jsch and I know Jsch contains the classes: com.jcraft.jsch.ProxyHTTP, com.jcraft.jsch.ProxySOCKS4 and com.jcraft.jsch.ProxySOCKS5.
The code below is an extract of VFS class org.apache.commons.vfs2.provider.sftp.SftpClientFactory:
public static Session createConnection(
...
final SftpFileSystemConfigBuilder.ProxyType proxyType = builder.getProxyType(fileSystemOptions);
...
final String proxyUser = builder.getProxyUser(fileSystemOptions);
final String proxyPassword = builder.getProxyPassword(fileSystemOptions);
Proxy proxy = null;
if (SftpFileSystemConfigBuilder.PROXY_HTTP.equals(proxyType)) {
proxy = createProxyHTTP(proxyHost, proxyPort);
((ProxyHTTP)proxy).setUserPasswd(proxyUser, proxyPassword);
} else if (SftpFileSystemConfigBuilder.PROXY_SOCKS5.equals(proxyType)) {
proxy = createProxySOCKS5(proxyHost, proxyPort);
((ProxySOCKS5)proxy).setUserPasswd(proxyUser, proxyPassword);
} else if (SftpFileSystemConfigBuilder.PROXY_STREAM.equals(proxyType)) {
proxy = createStreamProxy(proxyHost, proxyPort, fileSystemOptions, builder);
}
...
As you can you see, there's no "if" statement to instantiate ProxySOCKS4! I have duplicated the SftpClientFactory class, set my version to load before the original class on the classpath and changed the code as follow:
public static Session createConnection(
...
final SftpFileSystemConfigBuilder.ProxyType proxyType = builder.getProxyType(fileSystemOptions);
...
final String proxyUser = builder.getProxyUser(fileSystemOptions);
final String proxyPassword = builder.getProxyPassword(fileSystemOptions);
Proxy proxy = null;
if (SftpFileSystemConfigBuilder.PROXY_HTTP.equals(proxyType)) {
proxy = createProxyHTTP(proxyHost, proxyPort);
((ProxyHTTP)proxy).setUserPasswd(proxyUser, proxyPassword);
/// change start (I also created the PROXY_SOCKS4 constant)
} else if (SftpFileSystemConfigBuilder.PROXY_SOCKS4.equals(proxyType)) {
proxy = createProxySOCKS4(proxyHost, proxyPort);
((ProxySOCKS4)proxy).setUserPasswd(proxyUser, proxyPassword);
/// change end
} else if (SftpFileSystemConfigBuilder.PROXY_SOCKS5.equals(proxyType)) {
proxy = createProxySOCKS5(proxyHost, proxyPort);
((ProxySOCKS5)proxy).setUserPasswd(proxyUser, proxyPassword);
} else if (SftpFileSystemConfigBuilder.PROXY_STREAM.equals(proxyType)) {
proxy = createStreamProxy(proxyHost, proxyPort, fileSystemOptions, builder);
}
...
.. and guess what, when I set my application to use a Socks 4 Proxy it works alright with the change above. It is important to say that setting the application to work with Socks 5 does not work if the proxy server is a Socks 4 type, and that's true not only for my application with VFS, but also any other client I tested, like Fillezila or WinSCP.
So, the main question is:
Why does VFS predicts the usage of ProxyHTTP, ProxySOCKS5 but completely ignores the JSch ProxySOCKS4 class? Am I missing some SFTP or Proxy concept here or should I consider VFS bugged? That's the first time I work with VFS.
Please consider the question in bold as the main question not to make it too broad.