[ https://issues.apache.org/jira/browse/FTPSERVER-465?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
amtlib.dll updated FTPSERVER-465: --------------------------------- Description: Generally there is a bug for Windows Explorer on Chinese Windows Platforms that when decoding UTF-8 lines the last byte will be cut out and will ususally cause an error like a wrong filename. A work-around for this bug is to make the server using GBK and tell Windows not to use UTF-8. Currently Apache Mina FtpServer supports UTF-8 only, so I made this patch to make it possible to control it. Thank you for review the patch. was: Index: org/apache/ftpserver/impl/FtpServerContext.java IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== --- org/apache/ftpserver/impl/FtpServerContext.java (revision ) +++ org/apache/ftpserver/impl/FtpServerContext.java (revision ) @@ -19,6 +19,7 @@ package org.apache.ftpserver.impl; +import java.nio.charset.Charset; import java.util.Map; import java.util.concurrent.ThreadPoolExecutor; @@ -70,4 +71,6 @@ * @return the thread pool executor for this context. */ ThreadPoolExecutor getThreadPoolExecutor(); + + Charset getCharset(); } Index: org/apache/ftpserver/impl/IODataConnection.java IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== --- org/apache/ftpserver/impl/IODataConnection.java (revision ) +++ org/apache/ftpserver/impl/IODataConnection.java (revision ) @@ -27,6 +27,7 @@ import java.io.OutputStreamWriter; import java.io.Writer; import java.net.Socket; +import java.nio.charset.Charset; import java.util.zip.DeflaterOutputStream; import java.util.zip.InflaterInputStream; @@ -171,18 +172,18 @@ * org.apache.ftpserver.FtpDataConnection2#transferToClient(java.lang.String * ) */ - public final void transferToClient(FtpSession session, final String str) + public final void transferToClient(FtpSession session, final String str, final Charset charset) throws IOException { OutputStream out = getDataOutputStream(); Writer writer = null; try { - writer = new OutputStreamWriter(out, "UTF-8"); + writer = new OutputStreamWriter(out, charset); writer.write(str); // update session if (session instanceof DefaultFtpSession) { ((DefaultFtpSession) session).increaseWrittenDataBytes(str - .getBytes("UTF-8").length); + .getBytes(charset).length); } } finally { if (writer != null) { Index: org/apache/ftpserver/impl/DefaultFtpServerContext.java IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== --- org/apache/ftpserver/impl/DefaultFtpServerContext.java (revision ) +++ org/apache/ftpserver/impl/DefaultFtpServerContext.java (revision ) @@ -19,6 +19,7 @@ package org.apache.ftpserver.impl; +import java.nio.charset.Charset; import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -278,5 +279,16 @@ threadPoolExecutor = new OrderedThreadPoolExecutor(maxThreads); } return threadPoolExecutor; + } + + private Charset charset = Charset.forName("UTF-8"); + + public void setCharset(Charset charset) { + this.charset = charset; + } + + @Override + public Charset getCharset() { + return charset; } } Index: org/apache/ftpserver/ftplet/DataConnection.java IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== --- org/apache/ftpserver/ftplet/DataConnection.java (revision ) +++ org/apache/ftpserver/ftplet/DataConnection.java (revision ) @@ -22,6 +22,7 @@ import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; +import java.nio.charset.Charset; /** * @@ -59,6 +60,6 @@ * The string to transfer * @throws IOException */ - void transferToClient(FtpSession session, String str) throws IOException; + void transferToClient(FtpSession session, String str, Charset charset) throws IOException; } \ No newline at end of file Index: org/apache/ftpserver/command/impl/LIST.java IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== --- org/apache/ftpserver/command/impl/LIST.java (revision ) +++ org/apache/ftpserver/command/impl/LIST.java (revision ) @@ -126,7 +126,7 @@ try { dataConnection.transferToClient(session.getFtpletSession(), directoryLister.listFiles( parsedArg, session.getFileSystemView(), - LIST_FILE_FORMATER)); + LIST_FILE_FORMATER), context.getCharset()); } catch (SocketException ex) { LOG.debug("Socket exception during list transfer", ex); failure = true; Index: org/apache/ftpserver/command/impl/MLSD.java IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== --- org/apache/ftpserver/command/impl/MLSD.java (revision ) +++ org/apache/ftpserver/command/impl/MLSD.java (revision ) @@ -112,7 +112,7 @@ .getAttribute("MLST.types")); dataConnection.transferToClient(session.getFtpletSession(), directoryLister.listFiles( - parsedArg, session.getFileSystemView(), formater)); + parsedArg, session.getFileSystemView(), formater), context.getCharset()); } catch (SocketException ex) { LOG.debug("Socket exception during data transfer", ex); failure = true; Index: org/apache/ftpserver/command/impl/NLST.java IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== --- org/apache/ftpserver/command/impl/NLST.java (revision ) +++ org/apache/ftpserver/command/impl/NLST.java (revision ) @@ -121,7 +121,7 @@ } dataConnection.transferToClient(session.getFtpletSession(), directoryLister.listFiles( - parsedArg, session.getFileSystemView(), formater)); + parsedArg, session.getFileSystemView(), formater), context.getCharset()); } catch (SocketException ex) { LOG.debug("Socket exception during data transfer", ex); failure = true; Index: org/apache/ftpserver/command/impl/OPTS_UTF8.java IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== --- org/apache/ftpserver/command/impl/OPTS_UTF8.java (revision ) +++ org/apache/ftpserver/command/impl/OPTS_UTF8.java (revision ) @@ -20,6 +20,7 @@ package org.apache.ftpserver.command.impl; import java.io.IOException; +import java.nio.charset.Charset; import org.apache.ftpserver.command.AbstractCommand; import org.apache.ftpserver.ftplet.FtpException; @@ -50,8 +51,7 @@ // reset state session.resetState(); - // send default message session.write(LocalizedFtpReply.translate(session, request, context, - FtpReply.REPLY_200_COMMAND_OKAY, "OPTS.UTF8", null)); + context.getCharset().contains(Charset.forName("UTF-8")) ? FtpReply.REPLY_200_COMMAND_OKAY : FtpReply.REPLY_502_COMMAND_NOT_IMPLEMENTED, "OPTS.UTF8", null)); } } Index: org/apache/ftpserver/listener/nio/NioListener.java IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== --- org/apache/ftpserver/listener/nio/NioListener.java (revision ) +++ org/apache/ftpserver/listener/nio/NioListener.java (revision ) @@ -146,7 +146,7 @@ acceptor.getFilterChain().addLast("threadPool", new ExecutorFilter(context.getThreadPoolExecutor())); acceptor.getFilterChain().addLast("codec", - new ProtocolCodecFilter(new FtpServerProtocolCodecFactory())); + new ProtocolCodecFilter(new FtpServerProtocolCodecFactory(context.getCharset()))); acceptor.getFilterChain().addLast("mdcFilter2", mdcFilter); acceptor.getFilterChain().addLast("logger", new FtpLoggingFilter()); Index: org/apache/ftpserver/listener/nio/FtpResponseEncoder.java IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== --- org/apache/ftpserver/listener/nio/FtpResponseEncoder.java (revision ) +++ org/apache/ftpserver/listener/nio/FtpResponseEncoder.java (revision ) @@ -37,16 +37,19 @@ * @author <a href="http://mina.apache.org">Apache MINA Project</a> */ public class FtpResponseEncoder extends ProtocolEncoderAdapter { - private static final CharsetEncoder ENCODER = Charset.forName("UTF-8") - .newEncoder(); + private final CharsetEncoder encoder; + public FtpResponseEncoder(Charset charset) { + this.encoder = charset.newEncoder(); + } + public void encode(IoSession session, Object message, ProtocolEncoderOutput out) throws Exception { String value = message.toString(); IoBuffer buf = IoBuffer.allocate(value.length()).setAutoExpand(true); - buf.putString(value, ENCODER); + buf.putString(value, encoder); buf.flip(); out.write(buf); Index: org/apache/ftpserver/listener/nio/FtpServerProtocolCodecFactory.java IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== --- org/apache/ftpserver/listener/nio/FtpServerProtocolCodecFactory.java (revision ) +++ org/apache/ftpserver/listener/nio/FtpServerProtocolCodecFactory.java (revision ) @@ -35,10 +35,14 @@ * @author <a href="http://mina.apache.org">Apache MINA Project</a> */ public class FtpServerProtocolCodecFactory implements ProtocolCodecFactory { - private ProtocolDecoder decoder = new TextLineDecoder(Charset - .forName("UTF-8")); + private ProtocolDecoder decoder; - private ProtocolEncoder encoder = new FtpResponseEncoder(); + private ProtocolEncoder encoder; + + public FtpServerProtocolCodecFactory(Charset charset) { + decoder = new TextLineDecoder(charset); + encoder = new FtpResponseEncoder(charset); + } public ProtocolDecoder getDecoder(IoSession session) throws Exception { return decoder; Index: org/apache/ftpserver/FtpServerFactory.java IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== --- org/apache/ftpserver/FtpServerFactory.java (revision ) +++ org/apache/ftpserver/FtpServerFactory.java (revision ) @@ -19,6 +19,7 @@ package org.apache.ftpserver; +import java.nio.charset.Charset; import java.util.LinkedHashMap; import java.util.Map; @@ -232,5 +233,13 @@ */ public void setConnectionConfig(final ConnectionConfig connectionConfig) { serverContext.setConnectionConfig(connectionConfig); + } + + public void setCharset(Charset charset) { + serverContext.setCharset(charset); + } + + public Charset getCharset() { + return serverContext.getCharset(); } } \ No newline at end of file > A patch to enable controlling the charset in order to work around a bug of > Windows Explorer in CJK environments > --------------------------------------------------------------------------------------------------------------- > > Key: FTPSERVER-465 > URL: https://issues.apache.org/jira/browse/FTPSERVER-465 > Project: FtpServer > Issue Type: Improvement > Components: Core > Environment: any > Reporter: amtlib.dll > Labels: patch > Attachments: patch > > Original Estimate: 5m > Remaining Estimate: 5m > > Generally there is a bug for Windows Explorer on Chinese Windows Platforms > that when decoding UTF-8 lines the last byte will be cut out and will > ususally cause an error like a wrong filename. A work-around for this bug is > to make the server using GBK and tell Windows not to use UTF-8. Currently > Apache Mina FtpServer supports UTF-8 only, so I made this patch to make it > possible to control it. > Thank you for review the patch. -- This message was sent by Atlassian JIRA (v6.3.4#6332)