Skip to content

Commit d95bc68

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 264b21e commit d95bc68

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
@@ -758,6 +758,22 @@ public void allEvents() throws InterruptedException {
758758
this.config.latch = null;
759759
}
760760

761+
@Test
762+
void finalizeRawIsOkEvenIfReadRawIsNot() throws IOException {
763+
Session<FTPFile> session = this.sessionFactory.getSession();
764+
IOException expectedException = null;
765+
try (InputStream stream = session.readRaw("no_such_file")) {
766+
stream.read(); // Just to avoid empty 'try' block
767+
}
768+
catch (IOException ex) {
769+
expectedException = ex;
770+
}
771+
finally {
772+
assertThat(session.finalizeRaw()).isTrue();
773+
}
774+
assertThat(expectedException).hasMessage("Failed to obtain InputStream for remote file no_such_file: 550");
775+
}
776+
761777
private void resetSessionCache() {
762778
((CachingSessionFactory<?>) this.sessionFactory).resetCache();
763779
}

0 commit comments

Comments
 (0)