molex-ftp-client 1.2.1 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +47 -0
- package/README.md +109 -331
- package/benchmark.js +86 -0
- package/lib/FTPClient.js +103 -46
- package/lib/commands.js +132 -44
- package/lib/connection.js +11 -8
- package/lib/performance.js +29 -0
- package/lib/utils.js +0 -19
- package/package.json +1 -1
package/lib/connection.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const
|
|
1
|
+
const { createOptimizedSocket } = require('./performance');
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Handle FTP connection establishment and authentication
|
|
@@ -21,14 +21,10 @@ class FTPConnection {
|
|
|
21
21
|
this.client._debug(`Connecting to ${host}:${port} as ${user}`);
|
|
22
22
|
|
|
23
23
|
return new Promise((resolve, reject) => {
|
|
24
|
-
this.client.socket =
|
|
24
|
+
this.client.socket = createOptimizedSocket({ host, port }, () => {
|
|
25
25
|
this.client.connected = true;
|
|
26
26
|
this.client._debug('TCP connection established');
|
|
27
27
|
|
|
28
|
-
if (this.client.keepAlive) {
|
|
29
|
-
this.client.socket.setKeepAlive(true, 10000);
|
|
30
|
-
}
|
|
31
|
-
|
|
32
28
|
this.client.emit('connected');
|
|
33
29
|
});
|
|
34
30
|
|
|
@@ -72,7 +68,7 @@ class FTPConnection {
|
|
|
72
68
|
this.client.emit('close');
|
|
73
69
|
});
|
|
74
70
|
|
|
75
|
-
setTimeout(() => reject(new Error('Connection timeout')), 10000);
|
|
71
|
+
setTimeout(() => reject(new Error('Connection timeout')), this.client.timeout || 10000);
|
|
76
72
|
});
|
|
77
73
|
}
|
|
78
74
|
|
|
@@ -161,11 +157,18 @@ class FTPConnection {
|
|
|
161
157
|
if (this.client.connected) {
|
|
162
158
|
this.client._debug('Closing connection...');
|
|
163
159
|
try {
|
|
160
|
+
// Clean up data socket if exists
|
|
161
|
+
if (this.client.dataSocket) {
|
|
162
|
+
this.client.dataSocket.destroy();
|
|
163
|
+
this.client.dataSocket = null;
|
|
164
|
+
}
|
|
164
165
|
await this.sendCommand('QUIT');
|
|
165
166
|
} catch (err) {
|
|
166
167
|
this.client._debug('Error during QUIT:', err.message);
|
|
167
168
|
}
|
|
168
|
-
this.client.socket
|
|
169
|
+
if (this.client.socket) {
|
|
170
|
+
this.client.socket.end();
|
|
171
|
+
}
|
|
169
172
|
this.client.connected = false;
|
|
170
173
|
this.client.authenticated = false;
|
|
171
174
|
this.client._debug('Connection closed');
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TCP Performance optimization utilities
|
|
3
|
+
* Applies sensible defaults for FTP connections
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
const net = require('net');
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Create an optimized TCP socket connection
|
|
10
|
+
* Automatically applies TCP_NODELAY and keep-alive
|
|
11
|
+
* @param {Object} options - Connection options (host, port)
|
|
12
|
+
* @param {Function} callback - Callback on connection
|
|
13
|
+
* @returns {net.Socket}
|
|
14
|
+
*/
|
|
15
|
+
function createOptimizedSocket(options, callback) {
|
|
16
|
+
const socket = net.createConnection(options, callback);
|
|
17
|
+
|
|
18
|
+
// TCP_NODELAY - Disable Nagle's algorithm for lower latency
|
|
19
|
+
socket.setNoDelay(true);
|
|
20
|
+
|
|
21
|
+
// SO_KEEPALIVE - Detect dead connections
|
|
22
|
+
socket.setKeepAlive(true, 10000);
|
|
23
|
+
|
|
24
|
+
return socket;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
module.exports = {
|
|
28
|
+
createOptimizedSocket
|
|
29
|
+
};
|
package/lib/utils.js
CHANGED
|
@@ -3,24 +3,6 @@
|
|
|
3
3
|
* Utilities for building and parsing FTP commands
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
/**
|
|
7
|
-
* Parse PASV response to extract host and port
|
|
8
|
-
* @param {string} message - PASV response message
|
|
9
|
-
* @returns {Object} - { host, port }
|
|
10
|
-
*/
|
|
11
|
-
function parsePasvResponse(message) {
|
|
12
|
-
const match = message.match(/\((\d+),(\d+),(\d+),(\d+),(\d+),(\d+)\)/);
|
|
13
|
-
|
|
14
|
-
if (!match) {
|
|
15
|
-
throw new Error('Failed to parse PASV response');
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
const host = `${match[1]}.${match[2]}.${match[3]}.${match[4]}`;
|
|
19
|
-
const port = parseInt(match[5]) * 256 + parseInt(match[6]);
|
|
20
|
-
|
|
21
|
-
return { host, port };
|
|
22
|
-
}
|
|
23
|
-
|
|
24
6
|
/**
|
|
25
7
|
* Parse MDTM response to Date object
|
|
26
8
|
* @param {string} message - MDTM response message
|
|
@@ -76,7 +58,6 @@ function maskPassword(command) {
|
|
|
76
58
|
}
|
|
77
59
|
|
|
78
60
|
module.exports = {
|
|
79
|
-
parsePasvResponse,
|
|
80
61
|
parseMdtmResponse,
|
|
81
62
|
normalizePath,
|
|
82
63
|
getParentDir,
|