promise-ftp unknown command with ftp.get

1.5k Views Asked by At

I am using promise ftp to get a file and getting an error "unknown command". Putting debug mode on gives me the following output.

[connection] > 'USER ecopo108'
[connection] < '331 User userrrrr OK. Password required\r\n'
[parser] < '331 User userrrrr  OK. Password required\r\n'
[parser] Response: code=331, buffer='User userrrrr OK. Password required'
[connection] > 'PASS password'
[connection] < '230 OK. Current restricted directory is /\r\n'
[parser] < '230 OK. Current restricted directory is /\r\n'
[parser] Response: code=230, buffer='OK. Current restricted directory is /'
[connection] > 'FEAT'
[connection] < '211-Extensions supported:\r\n EPRT\r\n IDLE\r\n MDTM\r\n SIZE\r\n MFMT\r\n REST STREAM\r\n MLST type*;size*;sizd*;modify*;UNIX.mode*;UNIX.uid*;UNIX.gid*;unique*;\r\n MLSD\r\n AUTH TLS\r\n PBSZ\r\n PROT\r\n UTF8\r\n TVFS\r\n ESTA\r\n PASV\r\n EPSV\r\n SPSV\r\n ESTP\r\n211 End.\r\n'
[parser] < '211-Extensions supported:\r\n EPRT\r\n IDLE\r\n MDTM\r\n SIZE\r\n MFMT\r\n REST STREAM\r\n MLST type*;size*;sizd*;modify*;UNIX.mode*;UNIX.uid*;UNIX.gid*;unique*;\r\n MLSD\r\n AUTH TLS\r\n PBSZ\r\n PROT\r\n UTF8\r\n TVFS\r\n ESTA\r\n PASV\r\n EPSV\r\n SPSV\r\n ESTP\r\n211 End.\r\n'
[parser] Response: code=211, buffer='Extensions supported:\r\n EPRT\r\n IDLE\r\n MDTM\r\n SIZE\r\n MFMT\r\n REST STREAM\r\n MLST type*;size*;sizd*;modify*;UNIX.mode*;UNIX.uid*;UNIX.gid*;unique*;\r\n MLSD\r\n AUTH TLS\r\n PBSZ\r\n PROT\r\n UTF8\r\n TVFS\r\n ESTA\r\n PASV\r\n EPSV\r\n SPSV\r\n ESTP\r\nEnd.'
[connection] > 'OPTS UTF8 ON'
[connection] < '200 OK, UTF-8 enabled\r\n'
[parser] < '200 OK, UTF-8 enabled\r\n'
[parser] Response: code=200, buffer='OK, UTF-8 enabled'
[connection] > 'TYPE I'
[connection] < '200 TYPE is now 8-bit binary\r\n'
[parser] < '200 TYPE is now 8-bit binary\r\n'
[parser] Response: code=200, buffer='TYPE is now 8-bit binary'
[connection] > 'CWD ./public_html'
[connection] < '250 OK. Current directory is /public_html\r\n'
[parser] < '250 OK. Current directory is /public_html\r\n'
[parser] Response: code=250, buffer='OK. Current directory is /public_html'
[connection] > 'EPSV'
[connection] < '500 Unknown command\r\n'
[parser] < '500 Unknown command\r\n'
[parser] Response: code=500, buffer='Unknown command'
{ Error: Unknown command
    at makeError (C:\Users\Devon\Desktop\logfiles\node_modules\@icetee\ftp\lib\connection.js:1128:13)
    at Parser.<anonymous> (C:\Users\Devon\Desktop\logfiles\node_modules\@icetee\ftp\lib\connection.js:122:25)
    at emitTwo (events.js:126:13)
    at Parser.emit (events.js:214:7)
    at Parser._write (C:\Users\Devon\Desktop\logfiles\node_modules\@icetee\ftp\lib\parser.js:61:10)
    at doWrite (_stream_writable.js:396:12)
    at writeOrBuffer (_stream_writable.js:382:5)
    at Parser.Writable.write (_stream_writable.js:290:11)
    at Socket.ondata (C:\Users\Devon\Desktop\logfiles\node_modules\@icetee\ftp\lib\connection.js:298:20)
    at emitOne (events.js:116:13)
    at Socket.emit (events.js:211:7)
    at addChunk (_stream_readable.js:263:12)
    at readableAddChunk (_stream_readable.js:250:11)
    at Socket.Readable.push (_stream_readable.js:208:10)
    at TCP.onread (net.js:601:20) code: 500 }
[connection] < '500 Logout.\r\n'

The following is my code to get the robot.txt file however it doesn't get into the .then block after the ftp.get I can pull it down with an ftp client like Filezilla using the same configuration (port,host,user and pass). I get the same result without the ftp.cmd and have tried multiple different paths

const PromiseFtp = require("promise-ftp");
const fs = require("fs");

const config = {
  host: "host",
  user: "user",
  password: "pass",
  debug: console.log
};
function testFtp() {
  var ftp = new PromiseFtp();
  ftp
    .connect(config)
    .then(() => {
      return ftp.cwd("./public_html");
    })
    .then(() => {
      return ftp.get("robots.txt");
    })
    .then(function(stream) {
      return new Promise(function(resolve, reject) {
        stream.once("close", resolve);
        stream.once("error", reject);
        stream.pipe(fs.createWriteStream("robots.txt"));
      });
    })
    .then(function() {
      return ftp.end();
    })
    .catch(err => {
      console.log(err);
      ftp.end();
    });
}

testFtp();

using node.js & promise-ftp 1.3.5

1

There are 1 best solutions below

0
On

According to the response of the server to the FEAT command the server is claiming support for EPRT and EPSV extensions:

> FEAT
< 211-Extensions supported:
<  EPRT
<  ...
<  EPSV
<  ...
< 211 End

Based on this the FTP client is using these commands, but now the server is claiming that the command is not supported, contradicting its own statement earlier:

> EPSV
< 500 Unknown command

This means that either the server is broken or that there is some broken (transparent?) FTP proxy in the middle which does not support EPSV but fails to delete the claimed support from the servers original response to the FEAT command.

In any way - it is not the fault of the FTP client. The problem is not your code but on the server side.

Based on the code for node-ftp which is used by promise-ftp there must be a way to set an option forcePasv to enforce the use of PASV even if the server claims to support EPSV. I'm not really familiar with all the code but I suggest you try something like this:

const config = {
  ...
  debug: console.log,
  forcePasv: true,
};