diff --git a/backend/ftp/ftp.go b/backend/ftp/ftp.go index f9401ac64..ab90c1e95 100644 --- a/backend/ftp/ftp.go +++ b/backend/ftp/ftp.go @@ -241,23 +241,6 @@ func (dl *debugLog) Write(p []byte) (n int, err error) { return len(p), nil } -type dialCtx struct { - f *Fs - ctx context.Context -} - -// dial a new connection with fshttp dialer -func (d *dialCtx) dial(network, address string) (net.Conn, error) { - conn, err := fshttp.NewDialer(d.ctx).Dial(network, address) - if err != nil { - return nil, err - } - if d.f.tlsConf != nil { - conn = tls.Client(conn, d.f.tlsConf) - } - return conn, err -} - // shouldRetry returns a boolean as to whether this err deserve to be // retried. It returns the err as a convenience func shouldRetry(ctx context.Context, err error) (bool, error) { @@ -277,9 +260,22 @@ func shouldRetry(ctx context.Context, err error) (bool, error) { // Open a new connection to the FTP server. func (f *Fs) ftpConnection(ctx context.Context) (c *ftp.ServerConn, err error) { fs.Debugf(f, "Connecting to FTP server") - dCtx := dialCtx{f, ctx} - ftpConfig := []ftp.DialOption{ftp.DialWithDialFunc(dCtx.dial)} - if f.opt.ExplicitTLS { + + // Make ftp library dial with fshttp dialer optionally using TLS + dial := func(network, address string) (conn net.Conn, err error) { + conn, err = fshttp.NewDialer(ctx).Dial(network, address) + if f.tlsConf != nil && err == nil { + conn = tls.Client(conn, f.tlsConf) + } + return + } + ftpConfig := []ftp.DialOption{ftp.DialWithDialFunc(dial)} + + if f.opt.TLS { + // Our dialer takes care of TLS but ftp library also needs tlsConf + // as a trigger for sending PSBZ and PROT options to server. + ftpConfig = append(ftpConfig, ftp.DialWithTLS(f.tlsConf)) + } else if f.opt.ExplicitTLS { ftpConfig = append(ftpConfig, ftp.DialWithExplicitTLS(f.tlsConf)) // Initial connection needs to be cleartext for explicit TLS conn, err := fshttp.NewDialer(ctx).Dial("tcp", f.dialAddr)