GH-8786: Make FtpSession.finalizeRaw() robust
Fixes https://github.com/spring-projects/spring-integration/issues/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`**
This commit is contained in:
committed by
Christian Tzolov
parent
264b21eda7
commit
d95bc681dd
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2020 the original author or authors.
|
||||
* Copyright 2002-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -111,6 +111,10 @@ public class FtpSession implements Session<FTPFile> {
|
||||
if (!this.readingRaw.compareAndSet(true, false)) {
|
||||
throw new IOException("Raw read is not in process");
|
||||
}
|
||||
if (FTPReply.isNegativePermanent(this.client.getReplyCode())) {
|
||||
// The 'readRaw()' has failed - nothing to complete.
|
||||
return true;
|
||||
}
|
||||
if (this.client.completePendingCommand()) {
|
||||
int replyCode = this.client.getReplyCode();
|
||||
if (LOGGER.isDebugEnabled()) {
|
||||
|
||||
@@ -758,6 +758,22 @@ public class FtpServerOutboundTests extends FtpTestSupport {
|
||||
this.config.latch = null;
|
||||
}
|
||||
|
||||
@Test
|
||||
void finalizeRawIsOkEvenIfReadRawIsNot() throws IOException {
|
||||
Session<FTPFile> session = this.sessionFactory.getSession();
|
||||
IOException expectedException = null;
|
||||
try (InputStream stream = session.readRaw("no_such_file")) {
|
||||
stream.read(); // Just to avoid empty 'try' block
|
||||
}
|
||||
catch (IOException ex) {
|
||||
expectedException = ex;
|
||||
}
|
||||
finally {
|
||||
assertThat(session.finalizeRaw()).isTrue();
|
||||
}
|
||||
assertThat(expectedException).hasMessage("Failed to obtain InputStream for remote file no_such_file: 550");
|
||||
}
|
||||
|
||||
private void resetSessionCache() {
|
||||
((CachingSessionFactory<?>) this.sessionFactory).resetCache();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user