basic-ftp
Advanced tools
Comparing version 2.9.2 to 2.10.0
# Changelog | ||
## 2.10.0 | ||
- Added: Resolve simple NAT issues with PASV. | ||
- Added: Log socket encryption right before login. | ||
- Fixed: Remove obsolete socket connection error listener. | ||
## 2.9.2 | ||
@@ -4,0 +10,0 @@ |
@@ -123,2 +123,3 @@ "use strict"; | ||
login(user = "anonymous", password = "guest") { | ||
this.ftp.log(`Login security: ${describeTLS(this.ftp.socket)}`); | ||
return this.ftp.handle("USER " + user, (res, task) => { | ||
@@ -519,6 +520,14 @@ if (positiveCompletion(res.code)) { // User logged in proceed OR Command superfluous | ||
} | ||
// If the host in the PASV response has a local address while the control connection hasn't, | ||
// we assume a NAT issue and use the IP of the control connection as the target for the data connection. | ||
// We can't always perform this replacement because it's possible (although unlikely) that the FTP server | ||
// indeed uses a different host for data connections. | ||
if (ipIsPrivateAddress(target.host) && !ipIsPrivateAddress(ftp.socket.remoteAddress)) { | ||
target.host = ftp.socket.remoteAddress; | ||
} | ||
const handleConnErr = function(err) { | ||
task.reject("Can't open data connection in passive mode: " + err.message); | ||
}; | ||
let socket = new Socket(); | ||
socket.once("error", err => { | ||
task.reject("Can't open data connection in passive mode: " + err.message); | ||
}); | ||
socket.on("error", handleConnErr); | ||
socket.connect(target.port, target.host, () => { | ||
@@ -544,2 +553,4 @@ if (ftp.hasTLS) { | ||
} | ||
// Let the FTPContext listen to errors from now on, remove local handler. | ||
socket.removeListener("error", handleConnErr); | ||
ftp.dataSocket = socket; | ||
@@ -575,2 +586,15 @@ task.resolve(res); | ||
/** | ||
* Returns true if an IP is a private address according to https://tools.ietf.org/html/rfc1918#section-3 | ||
* | ||
* @param {string} ip The IP as a string, e.g. "192.168.0.1" | ||
* @returns {boolean} true if the ip is local. | ||
*/ | ||
function ipIsPrivateAddress(ip = "") { | ||
const octets = ip.split(".").map(o => parseInt(o, 10)); | ||
return octets[0] === 10 // 10.0.0.0 - 10.255.255.255 | ||
|| (octets[0] === 172 && octets[1] >= 16 && octets[1] <= 31) // 172.16.0.0 - 172.31.255.255 | ||
|| (octets[0] === 192 && octets[1] === 168); // 192.168.0.0 - 192.168.255.255 | ||
} | ||
/** | ||
* Upload stream data as a file. For example: | ||
@@ -577,0 +601,0 @@ * |
{ | ||
"name": "basic-ftp", | ||
"version": "2.9.2", | ||
"version": "2.10.0", | ||
"description": "FTP client for Node.js with support for explicit FTPS over TLS.", | ||
@@ -5,0 +5,0 @@ "main": "./lib/ftp", |
@@ -11,3 +11,3 @@ # Basic FTP | ||
FTP is an old legacy protocol. There are many features, quirks and server implementations. It's not a goal to support all of them. Instead, the library should focus on ways to let users add custom functionality. | ||
FTP is an old legacy protocol. There are many features, quirks and server implementations. It's not a goal to support all of them. Instead, the library should focus on ways to let the user extend functionality. | ||
@@ -52,3 +52,3 @@ ## Dependencies | ||
If you encounter a problem, it can be helpful to let the client log out all communication with the FTP server. | ||
If you encounter a problem, it can be helpful to log out all communication with the FTP server. | ||
@@ -147,3 +147,3 @@ ```js | ||
You can set a callback function with `client.trackProgress` to track the progress of all uploads and downloads. To disable progress reporting, call `trackProgress` with an undefined handler. | ||
Set a callback function with `client.trackProgress` to track the progress of all uploads and downloads. To disable progress reporting, call `trackProgress` with an undefined handler. | ||
@@ -171,11 +171,11 @@ ```js | ||
For each transfer, the callback function will receive a name, the transfer type (upload/download) and the number of bytes transferred so far. The function will be called at a regular interval during a transfer. | ||
For each transfer, the callback function will receive the filename, transfer type (upload/download) and number of bytes transferred. The function will be called at a regular interval during a transfer. | ||
In addition to that, there is also a counter for all bytes transferred since the last time `trackProgress` was called. This is useful when downloading a directory with multiple files where you want to show the total bytes downloaded so far. | ||
There is also a counter for all bytes transferred since the last time `trackProgress` was called. This is useful when downloading a directory with multiple files where you want to show the total bytes downloaded so far. | ||
**Important:** Due to a bug in Node.js since version 9.7.0, the reported number of uploaded bytes might be too low. The issue has been confirmed and [is tracked by the Node.js project](https://github.com/nodejs/node/issues/19562). | ||
**Important:** Due to a bug in Node.js since version 9.7.0, the reported number of uploaded bytes might be too low. The issue has been confirmed and [is tracked by the Node.js project](https://github.com/nodejs/node/issues/19562). As soon as the fix landed in a release, this section will be updated. | ||
## Error Handling | ||
Errors originating from a connection or described by a server response as well as timeouts will reject the associated Promise aka raise an exception. Use `try-catch` when using async-await or `catch()` when using Promises. The error will be described by an object depending on the type of error. | ||
Errors originating from a connection or described by a server response as well as timeouts will reject the associated Promise. Use a try-catch-clause when using async-await or `catch()` when using Promises directly. The error description depends on the type of error. | ||
@@ -211,3 +211,3 @@ ### Timeout | ||
`Client` offers a number of extension points that allow you to change a detail and continue to use existing functionality like uploading a whole directory. | ||
The `Client` offers extension points that allow you to change a detail while still using existing functionality like uploading a whole directory. | ||
@@ -214,0 +214,0 @@ `get/set client.prepareTransfer` |
129587
2219