basic-ftp
Advanced tools
Comparing version 4.5.2 to 4.5.3
# Changelog | ||
## 4.5.3 | ||
- Fixed: Allow 'undefined' to be passed to trackProgress. (#125, @FabianMeul) | ||
## 4.5.2 | ||
@@ -4,0 +9,0 @@ |
@@ -168,7 +168,7 @@ /// <reference types="node" /> | ||
* This will also reset the overall transfer counter that can be used for multiple transfers. You can | ||
* also pass `undefined` as a handler to stop reporting to an earlier one. | ||
* also call the function without a handler to stop reporting to an earlier one. | ||
* | ||
* @param handler Handler function to call on transfer progress. | ||
*/ | ||
trackProgress(handler: ProgressHandler): void; | ||
trackProgress(handler?: ProgressHandler): void; | ||
/** | ||
@@ -296,3 +296,12 @@ * Upload data from a readable stream or a local file to a remote file. | ||
protectWhitespace(path: string): Promise<string>; | ||
protected _exitAtCurrentDirectory<T>(func: () => Promise<T>): Promise<T>; | ||
/** | ||
* Try all available transfer strategies and pick the first one that works. Update `client` to | ||
* use the working strategy for all successive transfer requests. | ||
* | ||
* @param strategies | ||
* @returns a function that will try the provided strategies. | ||
*/ | ||
protected _enterFirstCompatibleMode(strategies: TransferStrategy[]): TransferStrategy; | ||
/** | ||
* DEPRECATED, use `uploadFrom`. | ||
@@ -323,9 +332,1 @@ * @deprecated | ||
} | ||
/** | ||
* Try all available transfer strategies and pick the first one that works. Update `client` to | ||
* use the working strategy for all successive transfer requests. | ||
* | ||
* @param strategies | ||
* @returns a function that will try the provided strategies. | ||
*/ | ||
export declare function enterFirstCompatibleMode(strategies: TransferStrategy[], client: Client): TransferStrategy; |
@@ -39,3 +39,3 @@ "use strict"; | ||
this.ftp = new FtpContext_1.FTPContext(timeout); | ||
this.prepareTransfer = enterFirstCompatibleMode([transfer_1.enterPassiveModeIPv6, transfer_1.enterPassiveModeIPv4], this); | ||
this.prepareTransfer = this._enterFirstCompatibleMode([transfer_1.enterPassiveModeIPv6, transfer_1.enterPassiveModeIPv4]); | ||
this.parseList = parseList_1.parseList; | ||
@@ -294,3 +294,3 @@ this._progressTracker = new ProgressTracker_1.ProgressTracker(); | ||
* This will also reset the overall transfer counter that can be used for multiple transfers. You can | ||
* also pass `undefined` as a handler to stop reporting to an earlier one. | ||
* also call the function without a handler to stop reporting to an earlier one. | ||
* | ||
@@ -496,3 +496,3 @@ * @param handler Handler function to call on transfer progress. | ||
async removeDir(remoteDirPath) { | ||
return exitAtCurrentDirectory(async () => { | ||
return this._exitAtCurrentDirectory(async () => { | ||
await this.cd(remoteDirPath); | ||
@@ -504,3 +504,3 @@ await this.clearWorkingDir(); | ||
} | ||
}, this); | ||
}); | ||
} | ||
@@ -537,3 +537,3 @@ /** | ||
async uploadFromDir(localDirPath, remoteDirPath) { | ||
return exitAtCurrentDirectory(async () => { | ||
return this._exitAtCurrentDirectory(async () => { | ||
if (remoteDirPath) { | ||
@@ -543,3 +543,3 @@ await this.ensureDir(remoteDirPath); | ||
return await this._uploadToWorkingDir(localDirPath); | ||
}, this); | ||
}); | ||
} | ||
@@ -571,3 +571,3 @@ /** | ||
async downloadToDir(localDirPath, remoteDirPath) { | ||
return exitAtCurrentDirectory(async () => { | ||
return this._exitAtCurrentDirectory(async () => { | ||
if (remoteDirPath) { | ||
@@ -577,3 +577,3 @@ await this.cd(remoteDirPath); | ||
return await this._downloadFromWorkingDir(localDirPath); | ||
}, this); | ||
}); | ||
} | ||
@@ -641,3 +641,43 @@ /** | ||
} | ||
async _exitAtCurrentDirectory(func) { | ||
const userDir = await this.pwd(); | ||
try { | ||
return await func(); | ||
} | ||
finally { | ||
if (!this.closed) { | ||
await ignoreError(() => this.cd(userDir)); | ||
} | ||
} | ||
} | ||
/** | ||
* Try all available transfer strategies and pick the first one that works. Update `client` to | ||
* use the working strategy for all successive transfer requests. | ||
* | ||
* @param strategies | ||
* @returns a function that will try the provided strategies. | ||
*/ | ||
_enterFirstCompatibleMode(strategies) { | ||
return async (ftp) => { | ||
ftp.log("Trying to find optimal transfer strategy..."); | ||
for (const strategy of strategies) { | ||
try { | ||
const res = await strategy(ftp); | ||
ftp.log("Optimal transfer strategy found."); | ||
this.prepareTransfer = strategy; // eslint-disable-line require-atomic-updates | ||
return res; | ||
} | ||
catch (err) { | ||
// Receiving an FTPError means that the last transfer strategy failed and we should | ||
// try the next one. Any other exception should stop the evaluation of strategies because | ||
// something else went wrong. | ||
if (!(err instanceof FtpContext_1.FTPError)) { | ||
throw err; | ||
} | ||
} | ||
} | ||
throw new Error("None of the available transfer strategies work."); | ||
}; | ||
} | ||
/** | ||
* DEPRECATED, use `uploadFrom`. | ||
@@ -684,32 +724,2 @@ * @deprecated | ||
exports.Client = Client; | ||
/** | ||
* Try all available transfer strategies and pick the first one that works. Update `client` to | ||
* use the working strategy for all successive transfer requests. | ||
* | ||
* @param strategies | ||
* @returns a function that will try the provided strategies. | ||
*/ | ||
function enterFirstCompatibleMode(strategies, client) { | ||
return async function autoDetect(ftp) { | ||
ftp.log("Trying to find optimal transfer strategy..."); | ||
for (const strategy of strategies) { | ||
try { | ||
const res = await strategy(ftp); | ||
ftp.log("Optimal transfer strategy found."); | ||
client.prepareTransfer = strategy; // eslint-disable-line require-atomic-updates | ||
return res; | ||
} | ||
catch (err) { | ||
// Receiving an FTPError means that the last transfer strategy failed and we should | ||
// try the next one. Any other exception should stop the evaluation of strategies because | ||
// something else went wrong. | ||
if (!(err instanceof FtpContext_1.FTPError)) { | ||
throw err; | ||
} | ||
} | ||
} | ||
throw new Error("None of the available transfer strategies work."); | ||
}; | ||
} | ||
exports.enterFirstCompatibleMode = enterFirstCompatibleMode; | ||
async function ensureLocalDirectory(path) { | ||
@@ -732,12 +742,1 @@ try { | ||
} | ||
async function exitAtCurrentDirectory(func, client) { | ||
const userDir = await client.pwd(); | ||
try { | ||
return await func(); | ||
} | ||
finally { | ||
if (!client.closed) { | ||
await ignoreError(() => client.cd(userDir)); | ||
} | ||
} | ||
} |
@@ -16,1 +16,8 @@ /// <reference types="node" /> | ||
export declare function upgradeSocket(socket: Socket, options: ConnectionOptions): Promise<TLSSocket>; | ||
/** | ||
* Returns true if an IP is a private address according to https://tools.ietf.org/html/rfc1918#section-3. | ||
* This will handle IPv4-mapped IPv6 addresses correctly but return false for all other IPv6 addresses. | ||
* | ||
* @param ip The IP as a string, e.g. "192.168.0.1" | ||
*/ | ||
export declare function ipIsPrivateV4Address(ip?: string): boolean; |
@@ -49,1 +49,18 @@ "use strict"; | ||
exports.upgradeSocket = upgradeSocket; | ||
/** | ||
* Returns true if an IP is a private address according to https://tools.ietf.org/html/rfc1918#section-3. | ||
* This will handle IPv4-mapped IPv6 addresses correctly but return false for all other IPv6 addresses. | ||
* | ||
* @param ip The IP as a string, e.g. "192.168.0.1" | ||
*/ | ||
function ipIsPrivateV4Address(ip = "") { | ||
// Handle IPv4-mapped IPv6 addresses like ::ffff:192.168.0.1 | ||
if (ip.startsWith("::ffff:")) { | ||
ip = ip.substr(7); // Strip ::ffff: prefix | ||
} | ||
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 | ||
} | ||
exports.ipIsPrivateV4Address = ipIsPrivateV4Address; |
@@ -5,4 +5,4 @@ /// <reference types="node" /> | ||
protected buf: Buffer; | ||
constructor(); | ||
_write(chunk: Buffer | string | any, _: string, callback: (error: Error | null) => void): void; | ||
getText(encoding: string): string; | ||
} |
@@ -6,17 +6,14 @@ "use strict"; | ||
constructor() { | ||
super(); | ||
super(...arguments); | ||
this.buf = Buffer.alloc(0); | ||
this._write = (chunk, _, done) => { | ||
if (chunk) { | ||
if (chunk instanceof Buffer) { | ||
this.buf = Buffer.concat([this.buf, chunk]); | ||
} | ||
else { | ||
done(new Error("StringWriter expects chunks of type 'Buffer'.")); | ||
return; | ||
} | ||
} | ||
done(); | ||
}; | ||
} | ||
_write(chunk, _, callback) { | ||
if (chunk instanceof Buffer) { | ||
this.buf = Buffer.concat([this.buf, chunk]); | ||
callback(null); | ||
} | ||
else { | ||
callback(new Error("StringWriter expects chunks of type 'Buffer'.")); | ||
} | ||
} | ||
getText(encoding) { | ||
@@ -23,0 +20,0 @@ return this.buf.toString(encoding); |
@@ -54,3 +54,3 @@ "use strict"; | ||
const controlHost = ftp.socket.remoteAddress; | ||
if (ipIsPrivateV4Address(target.host) && controlHost && !ipIsPrivateV4Address(controlHost)) { | ||
if (netUtils_1.ipIsPrivateV4Address(target.host) && controlHost && !netUtils_1.ipIsPrivateV4Address(controlHost)) { | ||
target.host = controlHost; | ||
@@ -77,18 +77,2 @@ } | ||
exports.parsePasvResponse = parsePasvResponse; | ||
/** | ||
* Returns true if an IP is a private address according to https://tools.ietf.org/html/rfc1918#section-3. | ||
* This will handle IPv4-mapped IPv6 addresses correctly but return false for all other IPv6 addresses. | ||
* | ||
* @param ip The IP as a string, e.g. "192.168.0.1" | ||
*/ | ||
function ipIsPrivateV4Address(ip = "") { | ||
// Handle IPv4-mapped IPv6 addresses like ::ffff:192.168.0.1 | ||
if (ip.startsWith("::ffff:")) { | ||
ip = ip.substr(7); // Strip ::ffff: prefix | ||
} | ||
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 | ||
} | ||
function connectForPassiveTransfer(host, port, ftp) { | ||
@@ -95,0 +79,0 @@ return new Promise((resolve, reject) => { |
{ | ||
"name": "basic-ftp", | ||
"version": "4.5.2", | ||
"version": "4.5.3", | ||
"description": "FTP client for Node.js, supports explicit FTPS over TLS, IPv6, Async/Await, and Typescript.", | ||
@@ -39,8 +39,8 @@ "main": "dist/index", | ||
"devDependencies": { | ||
"@types/node": "13.1.1", | ||
"@typescript-eslint/eslint-plugin": "2.13.0", | ||
"@typescript-eslint/parser": "2.13.0", | ||
"@types/node": "13.1.6", | ||
"@typescript-eslint/eslint-plugin": "2.16.0", | ||
"@typescript-eslint/parser": "2.16.0", | ||
"eslint": "6.8.0", | ||
"js-yaml": ">=3.13.1", | ||
"mocha": "6.2.2", | ||
"mocha": "7.0.0", | ||
"mock-fs": "4.10.4", | ||
@@ -47,0 +47,0 @@ "rimraf": "3.0.0", |
# Basic FTP | ||
[![Build Status](https://travis-ci.org/patrickjuchli/basic-ftp.svg?branch=master)](https://travis-ci.org/patrickjuchli/basic-ftp) [![npm version](https://img.shields.io/npm/v/basic-ftp.svg)](https://www.npmjs.com/package/basic-ftp) | ||
[![Build Status](https://travis-ci.org/patrickjuchli/basic-ftp.svg?branch=master)](https://travis-ci.org/patrickjuchli/basic-ftp) [![dependencies](https://img.shields.io/david/patrickjuchli/basic-ftp)](https://david-dm.org/patrickjuchli/basic-ftp) [![npm version](https://img.shields.io/npm/v/basic-ftp.svg)](https://www.npmjs.com/package/basic-ftp) | ||
@@ -168,3 +168,3 @@ This is an FTP client for Node.js. It supports explicit FTPS over TLS, Passive Mode over IPv6, has a Promise-based API, and offers methods to operate on whole directories. | ||
Set a callback function with `client.trackProgress` to track the progress of any transfer. Transfers are uploads, downloads or directory listings. To disable progress reporting, call `trackProgress` with an undefined handler. | ||
Set a callback function with `client.trackProgress` to track the progress of any transfer. Transfers are uploads, downloads or directory listings. To disable progress reporting, call `trackProgress` without a handler. | ||
@@ -240,2 +240,2 @@ ```js | ||
This library uses parts of the [directory listing parsers](https://github.com/apache/commons-net/tree/master/src/main/java/org/apache/commons/net/ftp/parser) written by The Apache Software Foundation. They've been made available under the Apache 2.0 license. See the [included notice](NOTICE.txt) and headers in the respective files containing the original copyright texts and a description of changes. | ||
This library uses parts of the [directory listing parsers](https://github.com/apache/commons-net/tree/master/src/main/java/org/apache/commons/net/ftp/parser) written by The Apache Software Foundation. They've been made available under the Apache 2.0 license. See the [included notice](NOTICE.txt) and headers in the respective files containing the original copyright texts and a description of changes. |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
141324
2897
240