Skip to content

Commit

Permalink
Merge pull request #12 from stewarttylerr/fix-compatability-bugs
Browse files Browse the repository at this point in the history
Fix compatability bugs
  • Loading branch information
trs authored May 6, 2017
2 parents cf3d543 + a75d63d commit 580b8d6
Show file tree
Hide file tree
Showing 62 changed files with 314 additions and 207 deletions.
1 change: 0 additions & 1 deletion .env
Original file line number Diff line number Diff line change
@@ -1,3 +1,2 @@
FTP_URL=ftp://127.0.0.1:8880
PASV_RANGE=8881
LOG_LEVEL=fatal
3 changes: 1 addition & 2 deletions config/testUnit/mocha.opts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
test/**/*.spec.js
--reporter list
--no-timeouts
--reporter mocha-pretty-bunyan-nyan
--ui bdd
16 changes: 8 additions & 8 deletions config/testUnit/thresholds.json
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
{
"global": {
"statements": 70,
"branches": 60,
"functions": 80,
"lines": 80
"statements": 90,
"branches": 80,
"functions": 90,
"lines": 90
},
"each": {
"statements": 0,
"branches": 0,
"functions": 0,
"lines": 0
"statements": 70,
"branches": 40,
"functions": 60,
"lines": 70
}
}
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@
"dependencies": {
"bunyan": "^1.8.9",
"lodash": "^4.17.4",
"minimist-string": "^1.0.2",
"moment": "^2.18.1",
"uuid": "^3.0.1",
"when": "^3.7.8"
Expand All @@ -68,6 +67,7 @@
"husky": "0.13.1",
"istanbul": "0.4.5",
"mocha": "3.2.0",
"mocha-pretty-bunyan-nyan": "^1.0.4",
"npm-run-all": "4.0.1",
"rimraf": "2.5.4",
"semantic-release": "^6.3.2",
Expand Down
19 changes: 15 additions & 4 deletions src/commands/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,22 @@ class FtpCommands {
this.whitelist = _.get(this.connection, 'server.options.whitelist', []).map(cmd => _.upperCase(cmd));
}

parse(message) {
const [directive, ...args] = message.replace(/"/g, '').split(' ');
const command = {
directive: _.chain(directive).trim().toUpper().value(),
arg: _.compact(args).join(' ') || null,
raw: message
};
return command;
}

handle(command) {
if (typeof command === 'string') command = this.parse(command);

// Obfuscate password from logs
const logCommand = _.cloneDeep(command);
command.directive = _.upperCase(command._[0]);
if (command.directive === 'PASS') logCommand._[1] = '********';
const logCommand = _.clone(command);
if (logCommand.directive === 'PASS') logCommand.arg = '********';

const log = this.connection.log.child({directive: command.directive});
log.trace({command: logCommand}, 'Handle command');
Expand Down Expand Up @@ -45,7 +56,7 @@ class FtpCommands {
const handler = commandRegister.handler.bind(this.connection);
return when.try(handler, { log, command, previous_command: this.previousCommand })
.finally(() => {
this.previousCommand = _.cloneDeep(command);
this.previousCommand = _.clone(command);
});
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/commands/registration/auth.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ const _ = require('lodash');
module.exports = {
directive: 'AUTH',
handler: function ({command} = {}) {
const method = _.upperCase(command._[1]);
const method = _.upperCase(command.arg);

switch (method) {
case 'TLS': return handleTLS.call(this);
Expand Down
2 changes: 1 addition & 1 deletion src/commands/registration/cdup.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ const cwd = require('./cwd').handler;
module.exports = {
directive: ['CDUP', 'XCUP'],
handler: function (args) {
args.command._ = [args.command._[0], '..'];
args.command.arg = '..';
return cwd.call(this, args);
},
syntax: '{{cmd}}',
Expand Down
2 changes: 1 addition & 1 deletion src/commands/registration/cwd.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ module.exports = {
if (!this.fs) return this.reply(550, 'File system not instantiated');
if (!this.fs.chdir) return this.reply(402, 'Not supported by file system');

return when.try(this.fs.chdir.bind(this.fs), command._[1])
return when.try(this.fs.chdir.bind(this.fs), command.arg)
.then(cwd => {
const path = cwd ? `"${escapePath(cwd)}"` : undefined;
return this.reply(250, path);
Expand Down
2 changes: 1 addition & 1 deletion src/commands/registration/dele.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ module.exports = {
if (!this.fs) return this.reply(550, 'File system not instantiated');
if (!this.fs.delete) return this.reply(402, 'Not supported by file system');

return when.try(this.fs.delete.bind(this.fs), command._[1])
return when.try(this.fs.delete.bind(this.fs), command.arg)
.then(() => {
return this.reply(250);
})
Expand Down
2 changes: 1 addition & 1 deletion src/commands/registration/help.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ module.exports = {
directive: 'HELP',
handler: function ({command} = {}) {
const registry = require('../registry');
const directive = _.upperCase(command._[1]);
const directive = _.upperCase(command.arg);
if (directive) {
if (!registry.hasOwnProperty(directive)) return this.reply(502, `Unknown command ${directive}.`);

Expand Down
2 changes: 1 addition & 1 deletion src/commands/registration/list.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ module.exports = {
const simple = command.directive === 'NLST';

let dataSocket;
const directory = command._[1] || '.';
const directory = command.arg || '.';
return this.connector.waitForConnection()
.then(socket => {
this.commandSocket.pause();
Expand Down
2 changes: 1 addition & 1 deletion src/commands/registration/mdtm.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ module.exports = {
if (!this.fs) return this.reply(550, 'File system not instantiated');
if (!this.fs.get) return this.reply(402, 'Not supported by file system');

return when.try(this.fs.get.bind(this.fs), command._[1])
return when.try(this.fs.get.bind(this.fs), command.arg)
.then(fileStat => {
const modificationTime = moment.utc(fileStat.mtime).format('YYYYMMDDHHmmss.SSS');
return this.reply(213, modificationTime);
Expand Down
2 changes: 1 addition & 1 deletion src/commands/registration/mkd.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ module.exports = {
if (!this.fs) return this.reply(550, 'File system not instantiated');
if (!this.fs.mkdir) return this.reply(402, 'Not supported by file system');

return when.try(this.fs.mkdir.bind(this.fs), command._[1])
return when.try(this.fs.mkdir.bind(this.fs), command.arg)
.then(dir => {
const path = dir ? `"${escapePath(dir)}"` : undefined;
return this.reply(257, path);
Expand Down
2 changes: 1 addition & 1 deletion src/commands/registration/mode.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
module.exports = {
directive: 'MODE',
handler: function ({command} = {}) {
return this.reply(/^S$/i.test(command._[1]) ? 200 : 504);
return this.reply(/^S$/i.test(command.arg) ? 200 : 504);
},
syntax: '{{cmd}} [mode]',
description: 'Sets the transfer mode (Stream, Block, or Compressed)',
Expand Down
2 changes: 1 addition & 1 deletion src/commands/registration/pass.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ module.exports = {

// 332 : require account name (ACCT)

const password = command._[1];
const password = command.arg;
return this.login(this.username, password)
.then(() => {
return this.reply(230);
Expand Down
2 changes: 1 addition & 1 deletion src/commands/registration/port.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ module.exports = {
directive: 'PORT',
handler: function ({command} = {}) {
this.connector = new ActiveConnector(this);
const rawConnection = _.get(command, '_[1]', '').split(',');
const rawConnection = _.get(command, 'arg', '').split(',');
if (rawConnection.length !== 6) return this.reply(425);

const ip = rawConnection.slice(0, 4).join('.');
Expand Down
2 changes: 1 addition & 1 deletion src/commands/registration/retr.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ module.exports = {
this.commandSocket.pause();
dataSocket = socket;
})
.then(() => when.try(this.fs.read.bind(this.fs), command._[1]))
.then(() => when.try(this.fs.read.bind(this.fs), command.arg))
.then(stream => {
return when.promise((resolve, reject) => {
dataSocket.on('error', err => stream.emit('error', err));
Expand Down
2 changes: 1 addition & 1 deletion src/commands/registration/rnfr.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ module.exports = {
if (!this.fs) return this.reply(550, 'File system not instantiated');
if (!this.fs.get) return this.reply(402, 'Not supported by file system');

const fileName = command._[1];
const fileName = command.arg;
return when.try(this.fs.get.bind(this.fs), fileName)
.then(() => {
this.renameFrom = fileName;
Expand Down
2 changes: 1 addition & 1 deletion src/commands/registration/rnto.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ module.exports = {
if (!this.fs.rename) return this.reply(402, 'Not supported by file system');

const from = this.renameFrom;
const to = command._[1];
const to = command.arg;

return when.try(this.fs.rename.bind(this.fs), from, to)
.then(() => {
Expand Down
3 changes: 2 additions & 1 deletion src/commands/registration/site/chmod.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ module.exports = function ({log, command} = {}) {
if (!this.fs) return this.reply(550, 'File system not instantiated');
if (!this.fs.chmod) return this.reply(402, 'Not supported by file system');

const [, mode, fileName] = command._;
const [mode, ...fileNameParts] = command.arg.split(' ');
const fileName = fileNameParts.join(' ');
return when.try(this.fs.chmod.bind(this.fs), fileName, parseInt(mode, 8))
.then(() => {
return this.reply(200);
Expand Down
14 changes: 4 additions & 10 deletions src/commands/registration/site/index.js
Original file line number Diff line number Diff line change
@@ -1,21 +1,15 @@
const _ = require('lodash');
const when = require('when');

module.exports = {
directive: 'SITE',
handler: function ({log, command} = {}) {
const registry = require('./registry');
let [, subverb, ...subparameters] = command._;
subverb = _.upperCase(subverb);
const subLog = log.child({subverb});
const subCommand = this.commands.parse(command.arg);
const subLog = log.child({subverb: subCommand.directive});

if (!registry.hasOwnProperty(subverb)) return this.reply(502);
if (!registry.hasOwnProperty(subCommand.directive)) return this.reply(502);

const subCommand = {
_: [subverb, ...subparameters],
directive: subverb
};
const handler = registry[subverb].handler.bind(this);
const handler = registry[subCommand.directive].handler.bind(this);
return when.try(handler, { log: subLog, command: subCommand });
},
syntax: '{{cmd}} [subVerb] [subParams]',
Expand Down
2 changes: 1 addition & 1 deletion src/commands/registration/size.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ module.exports = {
if (!this.fs) return this.reply(550, 'File system not instantiated');
if (!this.fs.get) return this.reply(402, 'Not supported by file system');

return when.try(this.fs.get.bind(this.fs), command._[1])
return when.try(this.fs.get.bind(this.fs), command.arg)
.then(fileStat => {
return this.reply(213, {message: fileStat.size});
})
Expand Down
2 changes: 1 addition & 1 deletion src/commands/registration/stat.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ module.exports = {
directive: 'STAT',
handler: function (args = {}) {
const {log, command} = args;
const path = _.get(command, '_[1]');
const path = _.get(command, 'arg');
if (path) {
if (!this.fs) return this.reply(550, 'File system not instantiated');
if (!this.fs.get) return this.reply(402, 'Not supported by file system');
Expand Down
2 changes: 1 addition & 1 deletion src/commands/registration/stor.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ module.exports = {
if (!this.fs.write) return this.reply(402, 'Not supported by file system');

const append = command.directive === 'APPE';
const fileName = command._[1];
const fileName = command.arg;

let dataSocket;
return this.connector.waitForConnection()
Expand Down
4 changes: 2 additions & 2 deletions src/commands/registration/stou.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,14 @@ module.exports = {
if (!this.fs) return this.reply(550, 'File system not instantiated');
if (!this.fs.get || !this.fs.getUniqueName) return this.reply(402, 'Not supported by file system');

const fileName = args.command._[1];
const fileName = args.command.arg;
return when.try(() => {
return when.try(this.fs.get.bind(this.fs), fileName)
.then(() => when.try(this.fs.getUniqueName.bind(this.fs)))
.catch(() => when.resolve(fileName));
})
.then(name => {
args.command._[1] = name;
args.command.arg = name;
return stor.call(this, args);
});
},
Expand Down
2 changes: 1 addition & 1 deletion src/commands/registration/stru.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
module.exports = {
directive: 'STRU',
handler: function ({command} = {}) {
return this.reply(/^F$/i.test(command._[1]) ? 200 : 504);
return this.reply(/^F$/i.test(command.arg) ? 200 : 504);
},
syntax: '{{cmd}} [structure]',
description: 'Set file transfer structure',
Expand Down
2 changes: 1 addition & 1 deletion src/commands/registration/type.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ const ENCODING_TYPES = {
module.exports = {
directive: 'TYPE',
handler: function ({command} = {}) {
const encoding = _.upperCase(command._[1]);
const encoding = _.upperCase(command.arg);
if (!ENCODING_TYPES.hasOwnProperty(encoding)) return this.reply(501);

this.encoding = ENCODING_TYPES[encoding];
Expand Down
2 changes: 1 addition & 1 deletion src/commands/registration/user.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ module.exports = {
handler: function ({log, command} = {}) {
if (this.username) return this.reply(530, 'Username already set');

this.username = command._[1];
this.username = command.arg;
if (!this.username) return this.reply(501, 'Must send username requirement');

if (this.server.options.anonymous === true) {
Expand Down
10 changes: 2 additions & 8 deletions src/connection.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ const _ = require('lodash');
const uuid = require('uuid');
const when = require('when');
const sequence = require('when/sequence');
const parseCommandString = require('minimist-string');

const BaseConnector = require('./connector/base');
const FileSystem = require('./fs');
Expand All @@ -26,12 +25,7 @@ class FtpConnection {
});
this.commandSocket.on('data', data => {
const messages = _.compact(data.toString('utf-8').split('\r\n'));
const handleMessage = message => {
const command = parseCommandString(message);
return this.commands.handle(command);
};

return sequence(messages.map(message => handleMessage.bind(this, message)));
return sequence(messages.map(message => this.commands.handle.bind(this.commands, message)));
});
this.commandSocket.on('timeout', () => {});
this.commandSocket.on('close', () => {
Expand Down Expand Up @@ -64,7 +58,7 @@ class FtpConnection {
return this.server.emit('login', {connection: this, username, password});
}
})
.then(({root = '/', cwd = '/', fs, blacklist = [], whitelist = []} = {}) => {
.then(({root, cwd, fs, blacklist = [], whitelist = []} = {}) => {
this.authenticated = true;
this.commands.blacklist = _.concat(this.commands.blacklist, blacklist);
this.commands.whitelist = _.concat(this.commands.whitelist, whitelist);
Expand Down
Loading

0 comments on commit 580b8d6

Please sign in to comment.