This is an automated email from the ASF dual-hosted git repository.
ggregory pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-vfs.git
The following commit(s) were added to refs/heads/master by this push:
new d2f6f34 fix the sftp channel don't return to the pool when exception
on SftpFileObject.doGetOutputStream (#215)
d2f6f34 is described below
commit d2f6f34f9700bd66a226d2ceb1495ac0d4c8f223
Author: zhouwenqing <[email protected]>
AuthorDate: Sat Nov 27 01:21:12 2021 +0800
fix the sftp channel don't return to the pool when exception on
SftpFileObject.doGetOutputStream (#215)
* fix the sftp channel don't return to the pool when exception on
SftpFileObject.doGetOutputStream
* Add test case for SftpFileObject#doGetOutputStream return the channel to
pool when there is some exceptions.
---
.../commons/vfs2/provider/sftp/SftpFileObject.java | 10 +-
.../sftp/AbstractSftpProviderTestCase.java | 2 +-
.../sftp/SftpPermissionExceptionTestCase.java | 124 +++++++++++++++++++++
3 files changed, 134 insertions(+), 2 deletions(-)
diff --git
a/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/sftp/SftpFileObject.java
b/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/sftp/SftpFileObject.java
index 45fe984..9ef7aa9 100644
---
a/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/sftp/SftpFileObject.java
+++
b/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/sftp/SftpFileObject.java
@@ -217,7 +217,15 @@ public class SftpFileObject extends
AbstractFileObject<SftpFileSystem> {
*/
final ChannelSftp channel = getAbstractFileSystem().getChannel();
- return new SftpOutputStream(channel, channel.put(relPath, bAppend ?
ChannelSftp.APPEND : ChannelSftp.OVERWRITE));
+ try {
+ return new SftpOutputStream(channel, channel.put(relPath, bAppend
? ChannelSftp.APPEND : ChannelSftp.OVERWRITE));
+ } catch (Exception ex) {
+ // when channel.put throw exception eg.
com.jcraft.jsch.SftpException: Permission denied
+ // returns the channel to the pool
+ getAbstractFileSystem().putChannel(channel);
+ throw ex;
+ }
+
}
@Override
diff --git
a/commons-vfs2/src/test/java/org/apache/commons/vfs2/provider/sftp/AbstractSftpProviderTestCase.java
b/commons-vfs2/src/test/java/org/apache/commons/vfs2/provider/sftp/AbstractSftpProviderTestCase.java
index 49a8007..8ec4920 100644
---
a/commons-vfs2/src/test/java/org/apache/commons/vfs2/provider/sftp/AbstractSftpProviderTestCase.java
+++
b/commons-vfs2/src/test/java/org/apache/commons/vfs2/provider/sftp/AbstractSftpProviderTestCase.java
@@ -420,7 +420,7 @@ abstract class AbstractSftpProviderTestCase extends
AbstractProviderTestConfig {
protected static String ConnectionUri;
- private static SshServer Server;
+ protected static SshServer Server;
private static final String TEST_URI = "test.sftp.uri";
diff --git
a/commons-vfs2/src/test/java/org/apache/commons/vfs2/provider/sftp/SftpPermissionExceptionTestCase.java
b/commons-vfs2/src/test/java/org/apache/commons/vfs2/provider/sftp/SftpPermissionExceptionTestCase.java
new file mode 100644
index 0000000..e7bed24
--- /dev/null
+++
b/commons-vfs2/src/test/java/org/apache/commons/vfs2/provider/sftp/SftpPermissionExceptionTestCase.java
@@ -0,0 +1,124 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.vfs2.provider.sftp;
+
+import java.io.File;
+import java.nio.file.Paths;
+
+import org.apache.commons.vfs2.AbstractVfsTestCase;
+import org.apache.commons.vfs2.Capability;
+import org.apache.commons.vfs2.FileObject;
+import org.apache.commons.vfs2.Selectors;
+import org.apache.commons.vfs2.VFS;
+import org.apache.sshd.server.channel.ChannelSession;
+import org.junit.Assert;
+import org.junit.Test;
+
+/**
+ * Test SftpFileObject.doGetOutputStream return the channel to pool, even
throw a sftp write permission exception.
+ */
+public class SftpPermissionExceptionTestCase extends
AbstractSftpProviderTestCase {
+
+ /**
+ * Sets up a scratch folder for the test to use.
+ */
+ protected FileObject createScratchFolder() throws Exception {
+ final FileObject scratchFolder = getWriteFolder();
+
+ // Make sure the test folder is empty
+ scratchFolder.delete(Selectors.EXCLUDE_SELF);
+ scratchFolder.createFolder();
+ scratchFolder.setWritable(false, false);
+ return scratchFolder;
+ }
+
+ /**
+ * Returns the capabilities required by the tests of this test case.
+ */
+ @Override
+ protected Capability[] getRequiredCapabilities() {
+ return new Capability[] {Capability.CREATE, Capability.DELETE,
Capability.GET_TYPE, Capability.LIST_CHILDREN,
+ Capability.READ_CONTENT, Capability.WRITE_CONTENT};
+ }
+
+
+ /**
+ * Test SftpFileObject.doGetOutputStream return the channel to pool, when
there is a exception in channel.put .
+ */
+ @Test
+ public void testGetOutputStreamException() throws Exception {
+ final File localFile = new
File("src/test/resources/test-data/test.zip");
+
+ final FileObject localFileObject =
VFS.getManager().toFileObject(localFile);
+
+ final FileObject scratchFolder = createScratchFolder();
+
+
+ // try to create local file
+ String fileName = "filecopy.txt";
+ FileObject fileObjectCopy = scratchFolder.resolveFile(fileName);
+ fileObjectCopy.setWritable(false, false);
+ fileObjectCopy.copyFrom(localFileObject, Selectors.SELECT_SELF);
+
+ // try to set the local file to readonly
+
Paths.get(AbstractVfsTestCase.getTestDirectory(),scratchFolder.getName().getBaseName(),
fileName).toFile().setWritable(false);
+ for (int i = 0; i < 30; i++) {
+ try{
+ fileObjectCopy = scratchFolder.resolveFile(fileName);
+ Assert.assertFalse(fileObjectCopy.isWriteable());
+ fileObjectCopy.copyFrom(localFileObject,
Selectors.SELECT_SELF);
+ Assert.fail("permission fail");
+ } catch (Exception ex) {
+ // ignore no perminison
+ }
+ }
+
+ // try to get created channel number.
+ int channelId = Server.getActiveSessions().get(0).registerChannel(new
ChannelSession());
+ Assert.assertTrue("create too many sftp channel more", channelId<30);
+
+ // try to set the local file to writable
+
Paths.get(AbstractVfsTestCase.getTestDirectory(),scratchFolder.getName().getBaseName(),
fileName).toFile().setWritable(true);
+
+
+ fileObjectCopy = scratchFolder.resolveFile(fileName);
+ Assert.assertTrue(fileObjectCopy.isWriteable());
+ fileObjectCopy.copyFrom(localFileObject, Selectors.SELECT_SELF);
+
+
+
+ }
+
+ /**
+ * Creates the test suite for the sftp file system.
+ */
+ public static junit.framework.Test suite() throws Exception {
+ final SftpProviderTestSuite suite = new SftpProviderTestSuite(new
SftpPermissionExceptionTestCase()){
+ @Override
+ protected void addBaseTests() throws Exception {
+ // Just tries to read
+ addTests(SftpPermissionExceptionTestCase.class);
+ }
+ };
+ return suite;
+ }
+
+ @Override
+ protected boolean isExecChannelClosed() {
+ return false;
+ }
+}