Overriding FileSystem
See original GitHub issueI’m not a node expert and am struggling with how to override the filesystem. I have ftp-srv working fine using the default setup, even running in a docker container.
My application requires receiving a CSV file, converting it to JSON (potentially into a pg database) and send some data to a different REST API. My plan was to override ftp-srv file system based on a login and process the csv file stream into a json file so that I can reply to the ftp client immediately if there are any format errors. If conversion is successful I would then trigger a different process to push data to the REST API while retaining the original file and the JSON version. I may even move this to be done 100% in-memory. Unfortunately, having the third party write directly to our REST API is not an option because they only support FTP transfers. There are other ways I could do this, but there are other benefits for me in this approach that are outside of the scope of this problem.
The documentation on this is light so the best I’ve been able to determine is to pass a custom FileSystem object with the response from the login event (login event from your test start.js
)
server.on('login', ({connection, username, password}, resolve, reject) => {
if ((username === 'test' || username === 'testdb') && password === 'test' || username === 'anonymous') {
if (username === 'testdb') {
var root = '/code/data';
var cwd = '/';
return resolve({root: root, cwd: cwd, fs: new DbFileSystem(connection, {root: root, cwd: cwd}) });
} else {
return resolve({ root: '/code/data', cwd: '/' });
}
} else {
reject('Bad username or password');
}
});
First of all, is this the right approach?
I then assumed the next step is to extend the FileSystem class:
const { FileSystem } = require('ftp-srv/fs');
const csv = require('csvtojson')
class DbFileSystem extends FileSystem {
constructor(connection, { root, cwd } = {}) {
super(connection, root, cwd);
}
write(fileName, {append = false} = {}) {
const {fsPath} = this._resolvePath(fileName);
const stream = syncFs.createWriteStream(fsPath, {flags: !append ? 'w+' : 'a+'});
stream.on('error', () => fs.unlink(fsPath));
// conceptually, this is what I want to do while the stream is being received
// (I know this function is the wrong place for this code)
csv()
.fromStream(csvReadStream)
.on('csv',(csvRow)=>{
// csvRow is an array
})
.on('done',(error)=>{
})
return stream;
}
}
module.exports = DbFileSystem;
Perhaps this is wrong, but now I don’t know where to go next because write only creates a new stream.Writable
and stream is handled asynchrounously in the src/commands/registration/stor.js: handler
. Do I also need to override the STOR
directive? 😕
Thanks
Issue Analytics
- State:
- Created 6 years ago
- Comments:7 (2 by maintainers)
@trs just and update, this works perfectly. I am able to do everything I need. Thanks
Brilliant. I think this will work. Thanks so much. I’ll keep you updated.