[ 
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)

Reply via email to