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 044a007 Add support for customizing FTP transfer aborted status codes. Closes #51. Initial patch from Boris Petrov on GitHub but I changed the term "Status Code" to "Reply Code" in APIs and constants to match FTP terminology. 044a007 is described below commit 044a007664a65ba56539aa098ac1467a4a32b3b3 Author: Gary Gregory <gardgreg...@gmail.com> AuthorDate: Wed Mar 6 08:51:16 2019 -0500 Add support for customizing FTP transfer aborted status codes. Closes #51. Initial patch from Boris Petrov on GitHub but I changed the term "Status Code" to "Reply Code" in APIs and constants to match FTP terminology. --- .../commons/vfs2/provider/ftp/FtpFileObject.java | 16 ++++++---- .../provider/ftp/FtpFileSystemConfigBuilder.java | 34 ++++++++++++++++++++++ src/changes/changes.xml | 3 ++ 3 files changed, 48 insertions(+), 5 deletions(-) diff --git a/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/ftp/FtpFileObject.java b/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/ftp/FtpFileObject.java index 74966fb..6a1e52f 100644 --- a/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/ftp/FtpFileObject.java +++ b/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/ftp/FtpFileObject.java @@ -23,6 +23,7 @@ import java.io.OutputStream; import java.util.Calendar; import java.util.Collections; import java.util.Iterator; +import java.util.List; import java.util.Map; import java.util.TreeMap; import java.util.concurrent.atomic.AtomicBoolean; @@ -30,7 +31,6 @@ import java.util.concurrent.atomic.AtomicBoolean; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.commons.net.ftp.FTPFile; -import org.apache.commons.net.ftp.FTPReply; import org.apache.commons.vfs2.FileName; import org.apache.commons.vfs2.FileNotFolderException; import org.apache.commons.vfs2.FileObject; @@ -50,7 +50,7 @@ import org.apache.commons.vfs2.util.RandomAccessMode; * An FTP file. */ public class FtpFileObject extends AbstractFileObject<FtpFileSystem> { - + private static final long DEFAULT_TIMESTAMP = 0L; private static final Map<String, FTPFile> EMPTY_FTP_FILE_MAP = Collections .unmodifiableMap(new TreeMap<String, FTPFile>()); @@ -100,7 +100,7 @@ public class FtpFileObject extends AbstractFileObject<FtpFileSystem> { doGetChildren(); // Look for the requested child - // VFS-210 adds the null check. + // VFS-210 adds the null check. return children != null ? children.get(name) : null; } @@ -578,8 +578,7 @@ public class FtpFileObject extends AbstractFileObject<FtpFileSystem> { protected void onClose() throws IOException { final boolean ok; try { - // See VFS-674 and the accompanying PR as to why this check for "transfer aborted" is needed - ok = client.completePendingCommand() || client.getReplyCode() == FTPReply.TRANSFER_ABORTED; + ok = client.completePendingCommand() || isTransferAbortedOkReplyCode(); } finally { getAbstractFileSystem().putClient(client); } @@ -588,6 +587,13 @@ public class FtpFileObject extends AbstractFileObject<FtpFileSystem> { throw new FileSystemException("vfs.provider.ftp/finish-get.error", getName()); } } + + private boolean isTransferAbortedOkReplyCode() throws IOException { + List<Integer> transferAbortedOkStatusCodes = FtpFileSystemConfigBuilder + .getInstance() + .getTransferAbortedOkReplyCodes(getAbstractFileSystem().getFileSystemOptions()); + return transferAbortedOkStatusCodes != null && transferAbortedOkStatusCodes.contains(client.getReplyCode()); + } } /** diff --git a/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/ftp/FtpFileSystemConfigBuilder.java b/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/ftp/FtpFileSystemConfigBuilder.java index b1809d6..981e645 100644 --- a/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/ftp/FtpFileSystemConfigBuilder.java +++ b/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/ftp/FtpFileSystemConfigBuilder.java @@ -17,7 +17,11 @@ package org.apache.commons.vfs2.provider.ftp; import java.net.Proxy; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import org.apache.commons.net.ftp.FTPReply; import org.apache.commons.net.ftp.parser.FTPFileEntryParserFactory; import org.apache.commons.vfs2.FileSystem; import org.apache.commons.vfs2.FileSystemConfigBuilder; @@ -46,6 +50,7 @@ public class FtpFileSystemConfigBuilder extends FileSystemConfigBuilder { private static final String SHORT_MONTH_NAMES = _PREFIX + ".SHORT_MONTH_NAMES"; private static final String SO_TIMEOUT = _PREFIX + ".SO_TIMEOUT"; private static final String USER_DIR_IS_ROOT = _PREFIX + ".USER_DIR_IS_ROOT"; + private static final String TRANSFER_ABORTED_OK_REPLY_CODES = _PREFIX + ".TRANSFER_ABORTED_OK_REPLY_CODES"; private FtpFileSystemConfigBuilder() { super("ftp."); @@ -75,6 +80,11 @@ public class FtpFileSystemConfigBuilder extends FileSystemConfigBuilder { return FtpFileSystem.class; } + public static List<Integer> getSaneTransferAbortedOkStatusCodes() { + // See VFS-674, its accompanying PR and https://github.com/apache/commons-vfs/pull/51 as to why 426 and 550 are here + return new ArrayList<>(Arrays.asList(FTPReply.TRANSFER_ABORTED, FTPReply.FILE_UNAVAILABLE)); + } + /** * Gets the timeout in milliseconds to use for the socket connection. * @@ -239,6 +249,17 @@ public class FtpFileSystemConfigBuilder extends FileSystemConfigBuilder { } /** + * @param opts The FileSystem options. + * @return The list of status codes (apart from 200) that are considered as OK when prematurely + * closing a stream. Defaults to <code>[426, 550]</code>. + * @since 2.4 + */ + @SuppressWarnings("unchecked") + public List<Integer> getTransferAbortedOkReplyCodes(final FileSystemOptions opts) { + return (List<Integer>) getParam(opts, TRANSFER_ABORTED_OK_REPLY_CODES); + } + + /** * Sets the timeout for the initial control connection. * <p> * If you set the connectTimeout to {@code null} no connectTimeout will be set. @@ -422,4 +443,17 @@ public class FtpFileSystemConfigBuilder extends FileSystemConfigBuilder { setParam(opts, USER_DIR_IS_ROOT, userDirIsRoot ? Boolean.TRUE : Boolean.FALSE); } + /** + * Sets the list of status codes that are considered as OK when prematurely closing a stream. + * <p> + * If you set the {@code statusCodes} to an empty list, all status codes besides 200 will be + * considered as an error. + * + * @param opts The FileSystem options. + * @param statusCodes The status codes. + * @since 2.4 + */ + public void setTransferAbortedOkReplyCodes(final FileSystemOptions opts, final List<Integer> statusCodes) { + setParam(opts, TRANSFER_ABORTED_OK_REPLY_CODES, statusCodes); + } } diff --git a/src/changes/changes.xml b/src/changes/changes.xml index 237618a..56d01c9 100644 --- a/src/changes/changes.xml +++ b/src/changes/changes.xml @@ -56,6 +56,9 @@ The <action> type attribute can be add,update,fix,remove. <action issue="VFS-692" dev="ggregory" type="update" due-to="Gary Gregory"> Update Apache Commons Collections from 4.2 to 4.3. </action> + <action dev="ggregory" type="update" due-to="Boris Petrov, Gary Gregory"> + Add support for customizing FTP transfer aborted status codes. GitHub PR #51. + </action> </release> <release version="2.3" date="2019-02-01" description="New features and bug fix release."> <action issue="VFS-645" dev="ggregory" type="fix">