Proxies and custom sockets

FTP proxy servers 

FTP proxy servers differs according to sequence of FTP commands used to pass connection and authentication data to the proxy:

Proxy Type FTP commands internally used by the proxy
FtpUser USER serverUser@proxyUser@serverHost[:serverPort]
PASS serverPassword@proxyPassword
FtpOpen USER proxyUser PASS proxyPassword
OPEN serverHost[:serverPort]
USER serverUser PASS serverPassword
FtpSite USER proxyUser PASS proxyPassword
SITE serverHost[:serverPort]
USER serverUser PASS serverPassword
FtpDoubleLogin USER ProxyUser@FtpHost PASS ProxyPassword
USER FtpUser PASS FtpPassword

To connect through an FTP proxy server, set Ftp.Proxy properties before calling the Connect method. Use ProxyType property to specify the proxy type from the above table:

// create FTP client instance
var ftp = new Rebex.Net.Ftp();

// use FTP OPEN proxy
ftp.Proxy.ProxyType = FtpProxyType.FtpOpen;
ftp.Proxy.Host = proxyHost;
ftp.Proxy.Port = proxyPort;
ftp.Proxy.UserName = proxyUserName;
ftp.Proxy.Password = proxyPassword;

// connect to the server
ftp.Connect(hostname);
' create FTP client instance
Dim ftp = New Rebex.Net.Ftp()

' use FTP OPEN proxy
ftp.Proxy.ProxyType = FtpProxyType.FtpOpen
ftp.Proxy.Host = proxyHost
ftp.Proxy.Port = proxyPort
ftp.Proxy.UserName = proxyUserName
ftp.Proxy.Password = proxyPassword

' connect to the server
ftp.Connect(hostname)

SOCKS4/SOCKS5 proxy servers 

To connect through SOCKET4, SOCKET4a or SOCKS5 proxy servers, set Ftp.Proxy properties before calling the Connect method. Use ProxyType property to specify the proxy type:

// create FTP client instance
var ftp = new Rebex.Net.Ftp();

// use SOCKS5 proxy
ftp.Proxy.ProxyType = FtpProxyType.Socks5;
ftp.Proxy.Host = proxyHost;
ftp.Proxy.Port = proxyPort;
ftp.Proxy.UserName = proxyUserName;

// connect to the server
ftp.Connect(hostname);
' create FTP client instance
Dim ftp = New Rebex.Net.Ftp()

' use SOCKS5 proxy
ftp.Proxy.ProxyType = FtpProxyType.Socks5
ftp.Proxy.Host = proxyHost
ftp.Proxy.Port = proxyPort
ftp.Proxy.UserName = proxyUserName

' connect to the server
ftp.Connect(hostname)

HTTP CONNECT proxy servers 

To connect through a HTTP proxy server, set Ftp.Proxy properties before calling the Connect method. Make sure the proxy server supports HTTP CONNECT method, and set the ProxyType property to HttpConnect:

// create FTP client instance
var ftp = new Rebex.Net.Ftp();

// use HTTP CONNECT proxy
ftp.Proxy.ProxyType = FtpProxyType.HttpConnect;
ftp.Proxy.Host = proxyHost;
ftp.Proxy.Port = proxyPort;
ftp.Proxy.UserName = proxyUserName;
ftp.Proxy.Password = proxyPassword;

// connect to the server
ftp.Connect(hostname);
' create FTP client instance
Dim ftp = New Rebex.Net.Ftp()

' use HTTP CONNECT proxy
ftp.Proxy.ProxyType = FtpProxyType.HttpConnect
ftp.Proxy.Host = proxyHost
ftp.Proxy.Port = proxyPort
ftp.Proxy.UserName = proxyUserName
ftp.Proxy.Password = proxyPassword

' connect to the server
ftp.Connect(hostname)

Proxies with single sign-on 

Some HTTP CONNECT proxies support NTLM authentication with single sign-on. To take advantage of this feature, set the AuthenticationMethod property to ProxyAuthentication.Ntlm.

// create FTP client instance
var ftp = new Rebex.Net.Ftp();

// use HTTP CONNECT proxy
ftp.Proxy.ProxyType = FtpProxyType.HttpConnect;
ftp.Proxy.Host = proxyHost;
ftp.Proxy.Port = proxyPort;

// use single sign-on
ftp.Proxy.AuthenticationMethod = FtpProxyAuthentication.Ntlm;

// connect to the server
ftp.Connect(hostname);
' create FTP client instance
Dim ftp = New Rebex.Net.Ftp()

' use HTTP CONNECT proxy
ftp.Proxy.ProxyType = FtpProxyType.HttpConnect
ftp.Proxy.Host = proxyHost
ftp.Proxy.Port = proxyPort

' use single sign-on
ftp.Proxy.AuthenticationMethod = FtpProxyAuthentication.Ntlm

' connect to the server
ftp.Connect(hostname)

SSH server as proxy 

It's possible to tunnel FTP sessions through an SSH server, essentially using it as a proxy server. You can utilize the SshSession class from the Rebex.Networking shared library, also available as part of Rebex FTP/SSL component.

// establish the shared SSH connection
var session = new Rebex.Net.SshSession();
session.Connect(sshHostname);
session.Authenticate(sshUsername, sshPassword);

// use SSH session as proxy to establish an FTP connection
var ftp = new Rebex.Net.Ftp();
ftp.SetSocketFactory(session.ToSocketFactory());
ftp.Connect(hostname);
ftp.Login(username, password);
// use 'ftp' object for FTP transfers
' establish the shared SSH connection
Dim session = New Rebex.Net.SshSession()
session.Connect(sshHostname)
session.Authenticate(sshUsername, sshPassword)

' use SSH session as proxy to establish an FTP connection
Dim ftp = New Rebex.Net.Ftp()
ftp.SetSocketFactory(session.ToSocketFactory())
ftp.Connect(hostname)
ftp.Login(username, password)
' use 'ftp' object for FTP transfers

Custom transport layer - ISocket 

Rebex components make it possible to implement a custom transport layer, giving you full control over the network communication. All you need to do is implement a custom ISocketFactory and ISocket interfaces and instruct the Ftp object to use them.

// create FTP client instance
var ftp = new Rebex.Net.Ftp();

// initialize factory
SimpleSocketFactory factory = new SimpleSocketFactory();
factory.SocketConnecting += factory_SocketConnecting;

// use the factory
ftp.SetSocketFactory(factory);

// connect to the server
ftp.Connect(hostname);
' create FTP client instance
Dim ftp = New Rebex.Net.Ftp()

' initialize factory
Dim factory = New SimpleSocketFactory()
AddHandler factory.SocketConnecting, AddressOf factory_SocketConnecting

' use the factory
ftp.SetSocketFactory(factory)

' connect to the server
ftp.Connect(hostname)

Custom transport layer (ISocket/ISocketFactory) implementation

/// <summary>
/// Exposes SocketConnected event which is raised
/// when a socket successfully connects to a remote end.
/// </summary>
public class SimpleSocketFactory : ISocketFactory
{
    /// <summary>
    /// Occurs when a socket successfully connects to a remote end.
    /// </summary>
    public event EventHandler SocketConnecting;

    // creates custom ISocket implementation
    ISocket ISocketFactory.CreateSocket()
    {
        return new SimpleSocket(this);
    }

    // raises event
    private void OnSocketConnecting()
    {
        EventHandler h = SocketConnecting;
        if (h != null)
            h(this, EventArgs.Empty);
    }

    // simple ISocket implementation
    // (core functionality is taken from ProxySocket)
    private class SimpleSocket : ProxySocket, ISocket
    {
        // creator object
        private readonly SimpleSocketFactory _factory;

        public SimpleSocket(SimpleSocketFactory factory)
        {
            _factory = factory;
        }

        // connects to a server and raises SocketConnected event
        void ISocket.Connect(string serverName, int serverPort)
        {
            _factory.OnSocketConnecting();
            base.Connect(serverName, serverPort);
        }

        // connects to a server and raises SocketConnected event
        void ISocket.Connect(EndPoint endpoint)
        {
            _factory.OnSocketConnecting();
            base.Connect(endpoint);
        }
    }
}
''' <summary>
''' Exposes SocketConnected event which is raised
''' when a socket successfully connects to a remote end.
''' </summary>
Public Class SimpleSocketFactory
    Implements ISocketFactory

    ''' <summary>
    ''' Occurs when a socket successfully connects to a remote end.
    ''' </summary>
    Public Event SocketConnecting As EventHandler

    ' creates custom ISocket implementation
    Function CreateSocket() As ISocket Implements ISocketFactory.CreateSocket
        Return New SimpleSocket(Me)
    End Function

    ' raises event
    Private Sub OnSocketConnecting()
        RaiseEvent SocketConnecting(Me, EventArgs.Empty)
    End Sub

    ' simple ISocket implementation
    ' (core functionality is taken from ProxySocket)
    Private Class SimpleSocket
        Inherits ProxySocket
        Implements ISocket

        ' creator object
        Dim _factory As SimpleSocketFactory

        Public Sub New(ByVal factory As SimpleSocketFactory)
            _factory = factory
        End Sub

        ' connects to a server and raises SocketConnected event
        Overloads Sub Connect(ByVal serverName As String, ByVal serverPort As Integer) Implements ISocket.Connect
            _factory.OnSocketConnecting()
            MyBase.Connect(serverName, serverPort)
        End Sub

        ' connects to a server and raises SocketConnected event
        Overloads Sub Connect(ByVal endpoint As EndPoint) Implements ISocket.Connect
            _factory.OnSocketConnecting()
            MyBase.Connect(endpoint)
        End Sub

    End Class

End Class

Please note that custom communication layer and proxy support are mutually exclusive - it's not possible to use both at the same time.