Hi,
I am using the Alpakka FTP Ftp.ls() source to poll the content of a directory. Everything works fine as long as there are no subfolders in the polled directory. But as soon as there is a subfolder, my logfiles are filling up with:
ERROR] [01/25/2019 18:30:58.251] [layline-akka.stream.default-blocking-io-dispatcher-35] [akka://layline/system/StreamSupervisor-0/flow-3-2-FtpBrowserSource] Error during postStop in [akka.stream.alpakka.ftp.impl.FtpSourceFactory$$anon$1@747b2287]: Truncated server reply:
org.apache.commons.net.MalformedServerReplyException: Truncated server reply:
at org.apache.commons.net.ftp.FTP.__getReply(FTP.java:332)
at org.apache.commons.net.ftp.FTP.__getReply(FTP.java:300)
at org.apache.commons.net.ftp.FTP.sendCommand(FTP.java:523)
at org.apache.commons.net.ftp.FTP.sendCommand(FTP.java:648)
...
messages.
In my test I am accessing a Unix FTP server on a Synology NAS from an Akka application running on a Windows system. I enabled the tracing on the FTP command channel by adding:
FtpSettings.create(InetAddress.getByName(getFtpConfig().getHost()))
.withConfigureConnectionConsumer(f -> {
f.addProtocolCommandListener(
new PrintCommandListener(new PrintWriter(System.out), true));
});
From that output I can see the following:
USER *******
331 Guest login ok, send your email address as password.
PASS *******
230 Guest login ok, access restrictions apply.
SYST
215 UNIX Type: L8
PORT 192,168,178,23,17,146
200 PORT command successful.
LIST /in
150 Opening BINARY mode data connection for 'file list'.
226 Transfer complete.
PORT 192,168,178,23,17,147
18:30:58.251 TRACE Layline.Source.SourceFtp - polling returned object 1.txt
200 PORT command successful.
LIST /\in\Folder1
150 Opening BINARY mode data connection for 'file list'.
550 /\in\Folder1: No such file or directory.
QUIT
For me it seems as if the FTP Server returns the path names using the Windows \ separator (for whatever reason). For the recursive lookup of Folder1 somewhere a Unix / is added “/\in\Folder1” which leads to the 550 error.
I then had a look to the Alpakka Source code in https://github.com/akka/alpakka/blob/master/ftp/src/main/scala/akka/stream/alpakka/ftp/impl/CommonFtpOperations.scala and found this:
/**
* INTERNAL API
*/
@InternalApi
private[ftp] trait CommonFtpOperations {
type Handler = FTPClient
def listFiles(basePath: String, handler: Handler): immutable.Seq[FtpFile] = {
val path = if (!basePath.isEmpty && basePath.head != '/') s"/$basePath" else basePath
handler
Is this the place where the ‘/’ is added? Am I suppossed and can I somehow configure my client so that Unix pathes are returned? Or does the underlying Apache FTPClient automatically uses the \ if I am on a Windows System and that is not forseen in the Alpakka code?
Thanks for your help
Lay