Skip to content

Commit 91f4fe4

Browse files
committed
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`. **Auto-cherry-pick to `6.4.x` & `6.3.x`**
1 parent 69aaa1d commit 91f4fe4

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.
@@ -46,6 +46,7 @@
4646
import org.apache.sshd.common.util.security.SecurityUtils;
4747
import org.apache.sshd.sftp.client.SftpClient;
4848
import org.apache.sshd.sftp.client.SftpErrorDataHandler;
49+
import org.apache.sshd.sftp.client.SftpMessage;
4950
import org.apache.sshd.sftp.client.SftpVersionSelector;
5051
import org.apache.sshd.sftp.client.impl.AbstractSftpClient;
5152
import org.apache.sshd.sftp.client.impl.DefaultSftpClient;
@@ -458,7 +459,7 @@ public void destroy() {
458459
*/
459460
protected class ConcurrentSftpClient extends DefaultSftpClient {
460461

461-
private final Lock sendLock = new ReentrantLock();
462+
private final Lock sftpWriteLock = new ReentrantLock();
462463

463464
protected ConcurrentSftpClient(ClientSession clientSession, SftpVersionSelector initialVersionSelector,
464465
SftpErrorDataHandler errorDataHandler) throws IOException {
@@ -467,13 +468,15 @@ protected ConcurrentSftpClient(ClientSession clientSession, SftpVersionSelector
467468
}
468469

469470
@Override
470-
public int send(int cmd, Buffer buffer) throws IOException {
471-
this.sendLock.lock();
471+
public SftpMessage write(int cmd, Buffer buffer) throws IOException {
472+
this.sftpWriteLock.lock();
472473
try {
473-
return super.send(cmd, buffer);
474+
SftpMessage sftpMessage = super.write(cmd, buffer);
475+
sftpMessage.waitUntilSent();
476+
return sftpMessage;
474477
}
475478
finally {
476-
this.sendLock.unlock();
479+
this.sftpWriteLock.unlock();
477480
}
478481
}
479482

0 commit comments

Comments
 (0)