Simple and extensible promise-based FTP server.
npm install ftpserver --save
import {FTPServer} from 'ftpserver';
const ftpServer = new FTPServer({...});
ftpServer.listen().then(() => {
// now listening for connections
});
listen()
to start the server.
close()
to stop.
You can pass an object to the constructor to set various options. Below are the options and their defaults.
var ftpServer = new FTPServer({
host: '127.0.0.1',
port: 21,
pasvStart: null,
pasvEnd: null,
timeout: 30000,
disabledCommands: [],
anonymous: false,
logLevel: 10,
greeting = null,
override: {
fs: null,
authentication: null
}
});
IP address clients use to connect to the server.
This IP will be used for passive connections, so ensure it is your remote IP.
Port clients use to connect to the server.
Sets the range for ports to use with a passive connection.
The server will have the client connect to the first available port within the range.
How long (in milliseconds) before a connection is closed if no commands are received.
String array of client commands that are forbidden.
These commands will be replied to with code 502.
Example: disabledCommands: ['RMD', 'RNFR', 'RNTO']
If true, will not authenticate connections and will act as if all connections are authenticated.
See Bunyan Levels.
If set, a greeting is sent to the connection when it first connects.
This can be a string or path to a file.
Used to override various functions or classes.
See Override Section.
The File class is used to signify a file or directory.
import fs from 'fs';
import {File} from 'FTPServer';
fs.stat(..., (stat) {
let myFile = new File('/path/to/file/or/directory').fromStat(stat);
});
You can use the fromStat
function to populate information on the file or directory
from the fs
stat
function.
You can override the default authentication function used by connections.
function myAuthFunction(username, password) {
...
}
new FTPServer({
...
override: {
authentication: myAuthFunction
}
})
Your function must return a promise that resolves if sucessful, and rejects otherwise.
ACCT:
If your connections require an account (ACCT), resolve your function with332
.
(This is not implemented yet)
You can override the default filesystem the server uses by creating a
new filesystem class.
Doing so can allow you to interact directly with the data without any
real file access.
class MyFileSystem {
constructor() {
// Current connection: this.connection
// Bunyan logger: this.connection.bunyan
}
...
}
...
new FTPServer({
...
override: {
fs: MyFileSystem
}
});
When a connection is recieved it will call new
on the overridden class.
The current connection will be available with this.connection
.
The following functions are to be implemented in your class and must
return promises (check lib/ftp/file-system.js
for examples):
list(dir) {}
Receives a path to a directory relative to the current directory.
If no argument, than the current directory is used.
Returns an array ofFile
classes (see File Section)
write(filePath, append) {}
Receives the relative path to write a new file.
Returns the stream to write data to.
read(filePath) {}
Receives the relative path to a file to read it's contents.
Returns the stream to read data from.
get(path) {}
Returns a
File
class to the path (either a file or directory).
chdir(dir) {}
Change the current directory (dir is relative).
mkdir(dir) {}
Create a directory relative to the current directory.
delete(filePath) {}
Delete a file or directory relative to the current directory.
rename(oldName, newName) {}
Rename a file or directory relative to the current directory.
Feel free to submit issues or pull requests, any assistance is welcomed!