Skip to content

Commit 9227acd

Browse files
artembilantzolov
authored andcommitted
GH-8786: Make FtpSession.finalizeRaw() robust
Fixes #8786 If `FtpSession.readRaw()` fails, the next `FtpSession.finalizeRaw()` call would lead to `FTPClient.completePendingCommand()` failure since there is no command to finish. * Fix `FtpSession.finalizeRaw()` to exit earlier positively in case of `FTPReply.isNegativePermanent()` for the current reply code set by the failure from a previous `FtpSession.readRaw()` **Cherry-pick to `6.1.x`, `6.0.x` & `5.5.x`**
1 parent 59df2b9 commit 9227acd

File tree

2 files changed

+21
-1
lines changed

2 files changed

+21
-1
lines changed

spring-integration-ftp/src/main/java/org/springframework/integration/ftp/session/FtpSession.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2020 the original author or authors.
2+
* Copyright 2002-2023 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.
@@ -111,6 +111,10 @@ public boolean finalizeRaw() throws IOException {
111111
if (!this.readingRaw.compareAndSet(true, false)) {
112112
throw new IOException("Raw read is not in process");
113113
}
114+
if (FTPReply.isNegativePermanent(this.client.getReplyCode())) {
115+
// The 'readRaw()' has failed - nothing to complete.
116+
return true;
117+
}
114118
if (this.client.completePendingCommand()) {
115119
int replyCode = this.client.getReplyCode();
116120
if (LOGGER.isDebugEnabled()) {

spring-integration-ftp/src/test/java/org/springframework/integration/ftp/outbound/FtpServerOutboundTests.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -752,6 +752,22 @@ public void allEvents() throws InterruptedException {
752752
this.config.latch = null;
753753
}
754754

755+
@Test
756+
void finalizeRawIsOkEvenIfReadRawIsNot() throws IOException {
757+
Session<FTPFile> session = this.sessionFactory.getSession();
758+
IOException expectedException = null;
759+
try (InputStream stream = session.readRaw("no_such_file")) {
760+
stream.read(); // Just to avoid empty 'try' block
761+
}
762+
catch (IOException ex) {
763+
expectedException = ex;
764+
}
765+
finally {
766+
assertThat(session.finalizeRaw()).isTrue();
767+
}
768+
assertThat(expectedException).hasMessage("Failed to obtain InputStream for remote file no_such_file: 550");
769+
}
770+
755771
private void resetSessionCache() {
756772
((CachingSessionFactory<?>) this.sessionFactory).resetCache();
757773
}

0 commit comments

Comments
 (0)