Repository navigation
sftp.put hangs after creating the file #247
Description
Hi,
I'm trying to do a simple upload of a small CSV file I'm generating on the fly.
Here is the relevant portion of the code
const data = Buffer.from(csv)
const sftp = new Client()
try {
await sftp.connect({
host: HOST,
username: USERNAME,
password: PASSWORD,
port: PORT,
debug: console.info
})
await sftp.put(data, '/path/to/file.csv')
} catch (e) {
console.error(e)
} finally {
await sftp.end()
}When doing so, most of the time the upload will hang, with logs showing:
CLIENT[sftp]: exists -> /path/to/file.csv
CLIENT[sftp]: stat -> /path/to/file.csv
DEBUG[SFTP]: Outgoing: Writing STAT
DEBUG: Outgoing: Writing CHANNEL_DATA (0)
DEBUG: Parser: IN_PACKET
DEBUG: Parser: Decrypting
DEBUG: Parser: pktLen:60,padLen:9,remainLen:48
DEBUG: Parser: IN_PACKETDATA
DEBUG: Parser: Decrypting
DEBUG: Parser: HMAC size:32
DEBUG: Parser: IN_PACKETDATAVERIFY
DEBUG: Parser: Verifying MAC
DEBUG: Parser: IN_PACKETDATAVERIFY (Valid HMAC)
DEBUG: Parser: IN_PACKETDATAAFTER, packet: CHANNEL_DATA (0)
DEBUG[SFTP]: Parser: Response: ATTRS
CLIENT[sftp]: stats <- {
"mode": 33206,
"permissions": 33206,
"uid": 1026,
"gid": 100,
"size": 0,
"atime": 1595344292,
"mtime": 1595347428
}
CLIENT[sftp]: Removing listener from error
CLIENT[sftp]: Removing listener from close
DEBUG: Parser: IN_PACKETBEFORE (expecting 16)
CLIENT[sftp]: exists <- {
"mode": 33206,
"uid": 1026,
"gid": 100,
"size": 0,
"accessTime": 1595344292000,
"modifyTime": 1595347428000,
"isDirectory": false,
"isFile": true,
"isBlockDevice": false,
"isCharacterDevice": false,
"isSymbolicLink": false,
"isFIFO": false,
"isSocket": false
}
CLIENT[sftp]: put remote path info {
"path": "/path/to/file.csv",
"type": "-",
"valid": true
}
CLIENT[sftp]: put -> /path/to/file.csv
DEBUG[SFTP]: Outgoing: Writing OPEN
DEBUG: Outgoing: Writing CHANNEL_DATA (0)
CLIENT[sftp]: put source is a buffer
DEBUG: Parser: IN_PACKET
DEBUG: Parser: Decrypting
DEBUG: Parser: pktLen:44,padLen:17,remainLen:32
DEBUG: Parser: IN_PACKETDATA
DEBUG: Parser: Decrypting
DEBUG: Parser: HMAC size:32
DEBUG: Parser: IN_PACKETDATAVERIFY
DEBUG: Parser: Verifying MAC
DEBUG: Parser: IN_PACKETDATAVERIFY (Valid HMAC)
DEBUG: Parser: IN_PACKETDATAAFTER, packet: CHANNEL_DATA (0)
DEBUG[SFTP]: Parser: Response: HANDLE
DEBUG[SFTP]: Outgoing: Writing FSETSTAT
DEBUG: Outgoing: Writing CHANNEL_DATA (0)
DEBUG: Parser: IN_PACKETBEFORE (expecting 16)
DEBUG: Parser: IN_PACKET
DEBUG: Parser: Decrypting
DEBUG: Parser: pktLen:44,padLen:6,remainLen:32
DEBUG: Parser: IN_PACKETDATA
DEBUG: Parser: Decrypting
DEBUG: Parser: HMAC size:32
DEBUG: Parser: IN_PACKETDATAVERIFY
DEBUG: Parser: Verifying MAC
DEBUG: Parser: IN_PACKETDATAVERIFY (Valid HMAC)
DEBUG: Parser: IN_PACKETDATAAFTER, packet: CHANNEL_DATA (0)
DEBUG[SFTP]: Parser: Response: STATUS
DEBUG[SFTP]: Outgoing: Writing WRITE
DEBUG: Outgoing: Writing CHANNEL_DATA (0)
DEBUG: Outgoing: Writing CHANNEL_DATA (0)
DEBUG: Outgoing: Writing CHANNEL_DATA (0)
DEBUG: Outgoing: Writing CHANNEL_DATA (0)
DEBUG: Parser: IN_PACKETBEFORE (expecting 16)
DEBUG: Outgoing: Writing CHANNEL_DATA (0)
DEBUG: Parser: IN_PACKET
DEBUG: Parser: Decrypting
DEBUG: Parser: pktLen:28,padLen:18,remainLen:16
DEBUG: Parser: IN_PACKETDATA
DEBUG: Parser: Decrypting
DEBUG: Parser: HMAC size:32
DEBUG: Parser: IN_PACKETDATAVERIFY
DEBUG: Parser: Verifying MAC
DEBUG: Parser: IN_PACKETDATAVERIFY (Valid HMAC)
DEBUG: Parser: IN_PACKETDATAAFTER, packet: CHANNEL_WINDOW_ADJUST (0, 98482)
DEBUG: Parser: IN_PACKETBEFORE (expecting 16)
and it will stay like so forever
Sometime, completely at random, it will go through and in thise case the logs will be like that:
CLIENT[sftp]: exists -> /path/to/file.csv
CLIENT[sftp]: stat -> /path/to/file.csv
DEBUG[SFTP]: Outgoing: Writing STAT
DEBUG: Outgoing: Writing CHANNEL_DATA (0)
DEBUG: Parser: IN_PACKET
DEBUG: Parser: Decrypting
DEBUG: Parser: pktLen:60,padLen:9,remainLen:48
DEBUG: Parser: IN_PACKETDATA
DEBUG: Parser: Decrypting
DEBUG: Parser: HMAC size:32
DEBUG: Parser: IN_PACKETDATAVERIFY
DEBUG: Parser: Verifying MAC
DEBUG: Parser: IN_PACKETDATAVERIFY (Valid HMAC)
DEBUG: Parser: IN_PACKETDATAAFTER, packet: CHANNEL_DATA (0)
DEBUG[SFTP]: Parser: Response: ATTRS
CLIENT[sftp]: stats <- {
"mode": 33206,
"permissions": 33206,
"uid": 1026,
"gid": 100,
"size": 0,
"atime": 1595344292,
"mtime": 1595347522
}
CLIENT[sftp]: Removing listener from error
CLIENT[sftp]: Removing listener from close
DEBUG: Parser: IN_PACKETBEFORE (expecting 16)
CLIENT[sftp]: exists <- {
"mode": 33206,
"uid": 1026,
"gid": 100,
"size": 0,
"accessTime": 1595344292000,
"modifyTime": 1595347522000,
"isDirectory": false,
"isFile": true,
"isBlockDevice": false,
"isCharacterDevice": false,
"isSymbolicLink": false,
"isFIFO": false,
"isSocket": false
}
CLIENT[sftp]: put remote path info {
"path": "/path/to/file.csv",
"type": "-",
"valid": true
}
CLIENT[sftp]: put -> /path/to/file.csv
DEBUG[SFTP]: Outgoing: Writing OPEN
DEBUG: Outgoing: Writing CHANNEL_DATA (0)
CLIENT[sftp]: put source is a buffer
DEBUG: Parser: IN_PACKET
DEBUG: Parser: Decrypting
DEBUG: Parser: pktLen:44,padLen:17,remainLen:32
DEBUG: Parser: IN_PACKETDATA
DEBUG: Parser: Decrypting
DEBUG: Parser: HMAC size:32
DEBUG: Parser: IN_PACKETDATAVERIFY
DEBUG: Parser: Verifying MAC
DEBUG: Parser: IN_PACKETDATAVERIFY (Valid HMAC)
DEBUG: Parser: IN_PACKETDATAAFTER, packet: CHANNEL_DATA (0)
DEBUG[SFTP]: Parser: Response: HANDLE
DEBUG[SFTP]: Outgoing: Writing FSETSTAT
DEBUG: Outgoing: Writing CHANNEL_DATA (0)
DEBUG: Parser: IN_PACKETBEFORE (expecting 16)
DEBUG: Parser: IN_PACKET
DEBUG: Parser: Decrypting
DEBUG: Parser: pktLen:44,padLen:6,remainLen:32
DEBUG: Parser: IN_PACKETDATA
DEBUG: Parser: Decrypting
DEBUG: Parser: HMAC size:32
DEBUG: Parser: IN_PACKETDATAVERIFY
DEBUG: Parser: Verifying MAC
DEBUG: Parser: IN_PACKETDATAVERIFY (Valid HMAC)
DEBUG: Parser: IN_PACKETDATAAFTER, packet: CHANNEL_DATA (0)
DEBUG[SFTP]: Parser: Response: STATUS
DEBUG[SFTP]: Outgoing: Writing WRITE
DEBUG: Outgoing: Writing CHANNEL_DATA (0)
DEBUG: Outgoing: Writing CHANNEL_DATA (0)
DEBUG: Outgoing: Writing CHANNEL_DATA (0)
DEBUG: Outgoing: Writing CHANNEL_DATA (0)
DEBUG: Parser: IN_PACKETBEFORE (expecting 16)
DEBUG: Outgoing: Writing CHANNEL_DATA (0)
DEBUG: Outgoing: Writing CHANNEL_DATA (0)
DEBUG: Outgoing: Writing CHANNEL_DATA (0)
DEBUG: Parser: IN_PACKET
DEBUG: Parser: Decrypting
DEBUG: Parser: pktLen:28,padLen:18,remainLen:16
DEBUG: Parser: IN_PACKETDATA
DEBUG: Parser: Decrypting
DEBUG: Parser: HMAC size:32
DEBUG: Parser: IN_PACKETDATAVERIFY
DEBUG: Parser: Verifying MAC
DEBUG: Parser: IN_PACKETDATAVERIFY (Valid HMAC)
DEBUG: Parser: IN_PACKETDATAAFTER, packet: CHANNEL_WINDOW_ADJUST (0, 98482)
DEBUG: Parser: IN_PACKETBEFORE (expecting 16)
DEBUG: Parser: IN_PACKET
DEBUG: Parser: Decrypting
DEBUG: Parser: pktLen:28,padLen:18,remainLen:16
DEBUG: Parser: IN_PACKETDATA
DEBUG: Parser: Decrypting
DEBUG: Parser: HMAC size:32
DEBUG: Parser: IN_PACKETDATAVERIFY
DEBUG: Parser: Verifying MAC
DEBUG: Parser: IN_PACKETDATAVERIFY (Valid HMAC)
DEBUG: Parser: IN_PACKETDATAAFTER, packet: CHANNEL_WINDOW_ADJUST (0, 102171)
DEBUG: Parser: IN_PACKETBEFORE (expecting 16)
DEBUG: Parser: IN_PACKET
DEBUG: Parser: Decrypting
DEBUG: Parser: pktLen:44,padLen:6,remainLen:32
DEBUG: Parser: IN_PACKETDATA
DEBUG: Parser: Decrypting
DEBUG: Parser: HMAC size:32
DEBUG: Parser: IN_PACKETDATAVERIFY
DEBUG: Parser: Verifying MAC
DEBUG: Parser: IN_PACKETDATAVERIFY (Valid HMAC)
DEBUG: Parser: IN_PACKETDATAAFTER, packet: CHANNEL_DATA (0)
DEBUG[SFTP]: Parser: Response: STATUS
DEBUG: Parser: IN_PACKETBEFORE (expecting 16)
DEBUG[SFTP]: Outgoing: Writing CLOSE
DEBUG: Outgoing: Writing CHANNEL_DATA (0)
CLIENT[sftp]: Removing listener from error
CLIENT[sftp]: Removing listener from close
DEBUG: Outgoing: Writing DISCONNECT (BY_APPLICATION)
CLIENT[sftp]: Removing listener from error
I'm currently running Node v14.4.0, so I'm wondering if this could be linked to mscdex/ssh2-streams#156 ?
You mention in this issue that using a concurrency of 1 it's working all the time, and my understanding was that client.put is running in the same configuration which is why I'm opening this issue here as I'm not sure it's the same.
Do you have any idea what I could do to ensure a more consistent result while running Node >= v14.1.0 ?
Thanks
Activity
theophilusx commentedon Jul 21, 2020
p-j commentedon Jul 21, 2020
Thanks for your response @theophilusx
I plan on checking this by the end of the week. I'll be posting some feedback then.
p-j commentedon Jul 23, 2020
Hi @theophilusx
I've tested both Node v13.14 and Node v14.5 today.
Both works fine with very small files.
Moving to larger files (in my case 842Ko CSV File)
Node v13.14 continues to produce good result but Node v14.5 hangs after creating the file. I end up with an empty file on the sftp server.
I'll be conducting more tests tomorrow with Node 14.0 & upward to see if the issue is indeed introduced by v14.1 as reported in the other issue.
theophilusx commentedon Jul 23, 2020
p-j commentedon Jul 27, 2020
I can confirm this is working on v14.0.0 and not on v14.1.0 with a big enough file.
p-j commentedon Jul 27, 2020
I've also been able to reproduce the behavior with both
On Node >= 14.1
node buffer-test.js 1000 /home/testwill hang most of the timeOn Node <= 14.0
node buffer-test.js 1000 /home/testwill go through most of the timetheophilusx commentedon Jul 27, 2020
theophilusx commentedon Aug 4, 2020
theophilusx commentedon Aug 4, 2020
p-j commentedon Aug 4, 2020
Hi @theophilusx
I've made a small change to your script here: master...p-j:master
This highlights the following, in v13.12.0 I get the following:
while running v14.7.0
The difference being the
closeevent being emitted in the v14.7 and not in the v13.12theophilusx commentedon Aug 4, 2020
theophilusx commentedon Aug 5, 2020
p-j commentedon Aug 10, 2020
Seems the root cause could be here nodejs/node#32887 (comment)
theophilusx commentedon Oct 24, 2020
The ssh2 module is being re-written to address this and some other limitations of that module. The ssh2-streams module is also being deprecated. This means a re-write of ssh2-sftp-client will be necessary to work with the updated ssh2 module.
I have created the branch version-6, which will be used to do the re-write.
p-j commentedon Oct 26, 2020
Thanks for the heads up, I might have some free time in the coming weeks if you want a hand in doing so I'd be happy to help.
theophilusx commentedon Jan 2, 2021
Update: I have recently tested against the new ssh2 version. While the issues specific to fastPut and fastGet appear to be resolved in the new ssh2 version, there are still some issues with put/get which appear to be related to streams. The seems to still be a bit of work required on the new version of ssh2 before it will be ready for a release.
I have tested the existing 0.8.9 version of ssh2 against latest node v15.4.0. The changes introduced in node v14.x which caused problems with ssh2 have been rolled back. This means that ssh2 and ssh2-sftp-client seems to work OK with node version 15.4.0. However, the changes which were rolled back did provide significant performance improvements in other areas, so it is likely that at some point they will be re-applied in one fashion or another. Hopefully, the new version of ssh2 will be released before this occurs.
theophilusx commentedon Jun 4, 2021
A new version of ssh2 has been released which addresses the underlying issue which caused this issue. I will be releasing ssh2-sftp-client 7.0.0 in a week. The new version works with all known versions of node >= v10.
I'm closing this issue as it has been resolved upstream with the new ssh2 version.