Skip to content

Commit e73c3f2

Browse files
artembilanspring-builds
authored andcommitted
GH-9796: Fix SftpSession.write() for concurrency
Fixes: #9796 Issue link: #9796 The `org.apache.sshd.sftp.client.impl.SftpOutputStreamAsync` is shared object for the `DefaultSftpClient` and it cannot be used concurrently. The guarded `send()` operation in the `ConcurrentSftpClient` is not enough since `DefaultSftpClient.write()` is called directly from the `SftpOutputStreamAsync.internalFlush()`. And this in the end is called from the `SftpSession.write()` * Fix `DefaultSftpSessionFactory.ConcurrentSftpClient` to override the `write()` method instead. Guard it with a `Lock` and call `sftpMessage.waitUntilSent();` to ensure that no concurrent access to the underlying `SftpOutputStreamAsync`. (cherry picked from commit 91f4fe4)
1 parent 265bea6 commit e73c3f2

File tree

1 file changed

+9
-6
lines changed

1 file changed

+9
-6
lines changed

spring-integration-sftp/src/main/java/org/springframework/integration/sftp/session/DefaultSftpSessionFactory.java

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2024 the original author or authors.
2+
* Copyright 2002-2025 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -45,6 +45,7 @@
4545
import org.apache.sshd.common.util.security.SecurityUtils;
4646
import org.apache.sshd.sftp.client.SftpClient;
4747
import org.apache.sshd.sftp.client.SftpErrorDataHandler;
48+
import org.apache.sshd.sftp.client.SftpMessage;
4849
import org.apache.sshd.sftp.client.SftpVersionSelector;
4950
import org.apache.sshd.sftp.client.impl.AbstractSftpClient;
5051
import org.apache.sshd.sftp.client.impl.DefaultSftpClient;
@@ -438,7 +439,7 @@ public void destroy() throws Exception {
438439
*/
439440
protected class ConcurrentSftpClient extends DefaultSftpClient {
440441

441-
private final Lock sendLock = new ReentrantLock();
442+
private final Lock sftpWriteLock = new ReentrantLock();
442443

443444
protected ConcurrentSftpClient(ClientSession clientSession, SftpVersionSelector initialVersionSelector,
444445
SftpErrorDataHandler errorDataHandler) throws IOException {
@@ -447,13 +448,15 @@ protected ConcurrentSftpClient(ClientSession clientSession, SftpVersionSelector
447448
}
448449

449450
@Override
450-
public int send(int cmd, Buffer buffer) throws IOException {
451-
this.sendLock.lock();
451+
public SftpMessage write(int cmd, Buffer buffer) throws IOException {
452+
this.sftpWriteLock.lock();
452453
try {
453-
return super.send(cmd, buffer);
454+
SftpMessage sftpMessage = super.write(cmd, buffer);
455+
sftpMessage.waitUntilSent();
456+
return sftpMessage;
454457
}
455458
finally {
456-
this.sendLock.unlock();
459+
this.sftpWriteLock.unlock();
457460
}
458461
}
459462

0 commit comments

Comments
 (0)