Advanced FTP



This is an FTP client library for Node.js. It supports FTPS over TLS, Passive Mode over IPv6, has a Promise-based API, and offers methods to operate on whole directories.
It is a fork of
basic-ftp aiming to add more features (FTPMaster with queueing and auto reconnect, non-stadard commands...) and fix some bugs.
Advisory
Prefer alternative transfer protocols like HTTPS or SFTP (SSH). FTP is a an old protocol with some reliability issues. Use this library when you have no choice and need to use FTP. Try to use FTPS (FTP over TLS) whenever possible, FTP alone does not provide any security.
Dependencies
Node 10.0 or later is the only dependency.
Installation
npm install advanced-ftp
Usage
The first example will connect to an FTP server using TLS (FTPS), get a directory listing, upload a file and download it as a copy. Note that the FTP protocol doesn't allow multiple requests running in parallel. When using the
FTPMaster class, all requests are queued and executed one after another. This is useful for complicated workflows where you want to make sure that one request is finished before the next one starts. If you don't need this, you can use the
Client class directly (as in
basic-ftp).
``
js
const ftp = require("advanced-ftp")
// ESM: import * as ftp from "advanced-ftp"
example()
async function example() {
const master = new ftp.FTPMaster({
host: "myftpserver.com",
user: "very",
password: "password",
secure: true
})
master.clients[0].client.ftp.verbose = true
master.enqueue(client => client.list()).then(console.log).catch(console.log)
await master.enqueue(client => client.uploadFrom("README.md", "README_FTP.md")).catch(console.log)
await master.enqueue(client => client.downloadTo("README_COPY.md", "README_FTP.md")).catch(console.log)
master.enqueue(client => client.close()).catch(console.log)
}
`
The next example deals with directories and their content. First, we make sure a remote path exists, creating all directories as necessary. Then, we make sure it's empty and upload the contents of a local directory.
`
js
await master.enqueue(client => client.ensureDir("my/remote/directory"))
await master.enqueue(client => client.clearWorkingDir())
await master.enqueue(client => client.uploadFromDir("my/local/directory"))
`
If you encounter a problem, it may help to log out all communication with the FTP server.
`
js
client.ftp.verbose = true
`
FTPMaster API
new FTPMaster(accessOptions: AccessOptions, [maxConnections: number = 1], [autoReconnect: boolean = true])
Create a master instance. Configure it with the AccessOptions for every client (see Client#access
for details), the maximum number of connections (Clients) to the server and whether to automatically reconnect when the connection is lost. The default is 1 connection and auto reconnect.
The clients will be connected when calling connectClients()
or automatically if autoReconnect
.
connectClients(): Promise
Reconnect all clients.
enqueue(task: (client: Client) => Promise, [priority: boolean = false]): Promise & {abort: () => void}
Adds a task to the queue. The task will be executed when a client is available. If no client is available, the task will be executed when a client is released. If priority is true, the task will be executed as soon as possible otherwise the task will be executed in the order they were added to the queue.
The returning Promise has an abort method that can be used to abort the task. The Promise will be rejected with an AbortError if the task is aborted. Aborting will remove the task from the queue if it has not been executed yet or cancel the data transfer if it is currently running.
clearQueue(): void
Clear the queue by rejecting all pending tasks.
autoReconnect = value: boolean
Set whether to automatically reconnect when the connection is lost. If true, the master will try to reconnect every client (see FTPMaster#connectClients). Default is true.
maxConnections = value: number
Set the maximum number of connections (Clients) to the server. If the number of connections is greater than the maximum, the master will close those connections, prefering the ones with no running tasks but forcing the ones with running tasks to close if necessary. New connections will be opened if FTPMaster#autoReconnect is true. Default is 1.
on(event: "error", listener: (err: Error) => void): this
Handle errors. This is currently only used for connection errors.
Client API
new Client(timeout = 30000)
Create a client instance. Configure it with a timeout in milliseconds that will be used for any connection made. Use 0 to disable timeouts, default is 30 seconds.
close()
Close the client and any open connection. The client can’t be used anymore after calling this method, you'll have to reconnect with access to continue any work. A client is also closed automatically if any timeout or connection error occurs. See the section on Error Handling below.
closed
True if the client is not connected to a server. You can reconnect with access.
access(options): Promise
Get access to an FTP server. This method will connect to a server, optionally secure the connection with TLS, login a user and apply some default settings (TYPE I, STRU F, PBSZ 0, PROT P). It returns the response of the initial connect command. This is an instance method and thus can be called multiple times during the lifecycle of a Client instance. Whenever you do, the client is reset with a new connection. This also implies that you can reopen a Client instance that has been closed due to an error when reconnecting with this method. The available options are:
- host (string) Server host, default: localhost
- port (number) Server port, default: 21
- user (string) Username, default: anonymous
- password (string) Password, default: guest
- secure (boolean | "implicit") Explicit FTPS over TLS, default: false. Use "implicit" if you need support for legacy implicit FTPS.
- secureOptions Options for TLS, same as for tls.connect() in Node.js.
---
features(): Promise