SFTP Server用于使用节点js读取目录

时间:2017-07-14 20:21:41

标签: node.js

我创建了一个基于SSH2 SFTP服务器和客户端的节点。我的目标是读取SFTP服务器的目录结构。假设我有一个包含文件夹temp的SFTP服务器,我想读取临时目录中的文件。我正在使用ssh2 npm模块来创建SFTP服务器和客户端。它正在连接到SFTP服务器但未列出目录

以下是代码

客户端SFTP

var Client = require('ssh2').Client;
var connSettings = {
     host: 'localhost',
     port: 22,
     username:'ankit',
     password:'shruti',
     method:'password'

     // You can use a key file too, read the ssh2 documentation
};

var conn = new Client();
conn.on('ready', function() {

console.log("connected to sftp server")

conn.sftp(function(err, sftp) {
        if (err) 
        throw err;

        sftp.readdir('',function(err,list)
        {

            console.log('Inside read')
            if(err)
            {
            console.log(err);    
            throw err;
            }
            console.log('showing directory listing')
            console.log(list);
            conn.end();

        })


        /** 
        var moveFrom = "/remote/file/path/file.txt";
        var moveTo = __dirname+'file1.txt';

        sftp.fastGet(moveFrom, moveTo , {}, function(downloadError){
            if(downloadError) throw downloadError;

            console.log("Succesfully uploaded");
        });
        */
 })

}).connect(connSettings);

SERVER SIDE SFTP : 

var constants = require('constants');
var fs = require('fs');

var ssh2 = require('ssh2');
var OPEN_MODE = ssh2.SFTP_OPEN_MODE;
var STATUS_CODE = ssh2.SFTP_STATUS_CODE;

var srv = new ssh2.Server({
  hostKeys: [fs.readFileSync(__dirname+'/key/id_rsa')],debug:console.log
}, function(client) {
  console.log('Client connected!');
   client.on('authentication', function(ctx) {
    if (ctx.method === 'password'
        // Note: Don't do this in production code, see
        // https://www.brendanlong.com/timing-attacks-and-usernames.html
        // In node v6.0.0+, you can use `crypto.timingSafeEqual()` to safely
        // compare two values.
        && ctx.username === 'ankit'
        && ctx.password === 'shruti')
      ctx.accept();
    else
      ctx.reject();
  }).on('ready', function() {
    console.log('Client authenticated!');
  });

  client.on('session',function(accept,reject)
  {
      console.log("Client asking for session");
      var session = accept();
      var handleCount = 0;
      var names=[]

      session.on('sftp',function(accept,reject)
      {
          console.log('Client sftp connection')
          var sftpStream = accept();

          sftpStream.on('OPENDIR',function(reqID,path)
          {
            var handle = new Buffer(4);
            handle.writeUInt32BE(handleCount++, 0, true);
            sftpStream.handle(reqID,handle);
            console.log(handle);
            console.log('Opening Read Directory for  --'+path);
            console.log(reqID);
            console.log(path);  

          }).on('READDIR',function(reqID,handle)
          {
           console.log('Read request')
           console.log(reqID);
            if(handle.length!==4)
            return sftpStream.status(reqID, STATUS_CODE.FAILURE,'There was failure')
            
                sftpStream.status(reqID, STATUS_CODE.OK,'Everything ok')
                sftpStream.name(reqID,names);     
              
              
          })
          


      })


  })

  






}).listen(0, '127.0.0.1', function() {
  console.log('Listening on port ' + this.address().port);
});

srv.listen(22)

1 个答案:

答案 0 :(得分:1)

客户端将发送多个READDIR请求。在第一次请求时,您应该发送文件列表,在第二个您应该发送EOF状态,告诉客户列表已经完成。

一个例子是:

let listSent = false;
let names = [];

sftpStream.on('OPENDIR', function (reqID, path) {
    listSent = false;
    sftpStream.handle(new Buffer());
});

sftpStream.on('READDIR', function (reqID, handle) {
    if (listSent) {
        sftpStream.status(reqID, STATUS_CODE.EOF);
        return;
    }

    sftpStream.name(reqID, names);
    listSent = true;
});