You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mina.apache.org by ng...@apache.org on 2008/10/31 15:58:58 UTC

svn commit: r709438 - in /mina/ftpserver/trunk: core/src/main/java/org/apache/ftpserver/command/impl/ core/src/main/java/org/apache/ftpserver/impl/ core/src/test/java/org/apache/ftpserver/clienttests/ ftplet-api/src/main/java/org/apache/ftpserver/ftplet/

Author: ngn
Date: Fri Oct 31 07:58:58 2008
New Revision: 709438

URL: http://svn.apache.org/viewvc?rev=709438&view=rev
Log:
Do not time out session while they are transfering data (FTPSERVER-170)

Added:
    mina/ftpserver/trunk/core/src/test/java/org/apache/ftpserver/clienttests/DataTransferTimeoutTest.java
Modified:
    mina/ftpserver/trunk/core/src/main/java/org/apache/ftpserver/command/impl/APPE.java
    mina/ftpserver/trunk/core/src/main/java/org/apache/ftpserver/command/impl/LIST.java
    mina/ftpserver/trunk/core/src/main/java/org/apache/ftpserver/command/impl/MLSD.java
    mina/ftpserver/trunk/core/src/main/java/org/apache/ftpserver/command/impl/NLST.java
    mina/ftpserver/trunk/core/src/main/java/org/apache/ftpserver/command/impl/RETR.java
    mina/ftpserver/trunk/core/src/main/java/org/apache/ftpserver/command/impl/STOR.java
    mina/ftpserver/trunk/core/src/main/java/org/apache/ftpserver/command/impl/STOU.java
    mina/ftpserver/trunk/core/src/main/java/org/apache/ftpserver/impl/DefaultFtpSession.java
    mina/ftpserver/trunk/core/src/main/java/org/apache/ftpserver/impl/FtpIoSession.java
    mina/ftpserver/trunk/core/src/main/java/org/apache/ftpserver/impl/IODataConnection.java
    mina/ftpserver/trunk/ftplet-api/src/main/java/org/apache/ftpserver/ftplet/DataConnection.java
    mina/ftpserver/trunk/ftplet-api/src/main/java/org/apache/ftpserver/ftplet/FtpSession.java

Modified: mina/ftpserver/trunk/core/src/main/java/org/apache/ftpserver/command/impl/APPE.java
URL: http://svn.apache.org/viewvc/mina/ftpserver/trunk/core/src/main/java/org/apache/ftpserver/command/impl/APPE.java?rev=709438&r1=709437&r2=709438&view=diff
==============================================================================
--- mina/ftpserver/trunk/core/src/main/java/org/apache/ftpserver/command/impl/APPE.java (original)
+++ mina/ftpserver/trunk/core/src/main/java/org/apache/ftpserver/command/impl/APPE.java Fri Oct 31 07:58:58 2008
@@ -158,7 +158,7 @@
                 os = file.createOutputStream(offset);
 
                 // transfer data
-                long transSz = dataConnection.transferFromClient(os);
+                long transSz = dataConnection.transferFromClient(session.getFtpletSession(), os);
 
                 // log message
                 String userName = session.getUser().getName();

Modified: mina/ftpserver/trunk/core/src/main/java/org/apache/ftpserver/command/impl/LIST.java
URL: http://svn.apache.org/viewvc/mina/ftpserver/trunk/core/src/main/java/org/apache/ftpserver/command/impl/LIST.java?rev=709438&r1=709437&r2=709438&view=diff
==============================================================================
--- mina/ftpserver/trunk/core/src/main/java/org/apache/ftpserver/command/impl/LIST.java (original)
+++ mina/ftpserver/trunk/core/src/main/java/org/apache/ftpserver/command/impl/LIST.java Fri Oct 31 07:58:58 2008
@@ -111,7 +111,7 @@
                 ListArgument parsedArg = ListArgumentParser.parse(request
                         .getArgument());
 
-                dataConnection.transferToClient(directoryLister.listFiles(
+                dataConnection.transferToClient(session.getFtpletSession(), directoryLister.listFiles(
                         parsedArg, session.getFileSystemView(),
                         LIST_FILE_FORMATER));
             } catch (SocketException ex) {

Modified: mina/ftpserver/trunk/core/src/main/java/org/apache/ftpserver/command/impl/MLSD.java
URL: http://svn.apache.org/viewvc/mina/ftpserver/trunk/core/src/main/java/org/apache/ftpserver/command/impl/MLSD.java?rev=709438&r1=709437&r2=709438&view=diff
==============================================================================
--- mina/ftpserver/trunk/core/src/main/java/org/apache/ftpserver/command/impl/MLSD.java (original)
+++ mina/ftpserver/trunk/core/src/main/java/org/apache/ftpserver/command/impl/MLSD.java Fri Oct 31 07:58:58 2008
@@ -110,7 +110,7 @@
                 FileFormater formater = new MLSTFileFormater((String[]) session
                         .getAttribute("MLST.types"));
 
-                dataConnection.transferToClient(directoryLister.listFiles(
+                dataConnection.transferToClient(session.getFtpletSession(), directoryLister.listFiles(
                         parsedArg, session.getFileSystemView(), formater));
             } catch (SocketException ex) {
                 LOG.debug("Socket exception during data transfer", ex);

Modified: mina/ftpserver/trunk/core/src/main/java/org/apache/ftpserver/command/impl/NLST.java
URL: http://svn.apache.org/viewvc/mina/ftpserver/trunk/core/src/main/java/org/apache/ftpserver/command/impl/NLST.java?rev=709438&r1=709437&r2=709438&view=diff
==============================================================================
--- mina/ftpserver/trunk/core/src/main/java/org/apache/ftpserver/command/impl/NLST.java (original)
+++ mina/ftpserver/trunk/core/src/main/java/org/apache/ftpserver/command/impl/NLST.java Fri Oct 31 07:58:58 2008
@@ -119,7 +119,7 @@
                     formater = NLST_FILE_FORMATER;
                 }
 
-                dataConnection.transferToClient(directoryLister.listFiles(
+                dataConnection.transferToClient(session.getFtpletSession(), directoryLister.listFiles(
                         parsedArg, session.getFileSystemView(), formater));
             } catch (SocketException ex) {
                 LOG.debug("Socket exception during data transfer", ex);

Modified: mina/ftpserver/trunk/core/src/main/java/org/apache/ftpserver/command/impl/RETR.java
URL: http://svn.apache.org/viewvc/mina/ftpserver/trunk/core/src/main/java/org/apache/ftpserver/command/impl/RETR.java?rev=709438&r1=709437&r2=709438&view=diff
==============================================================================
--- mina/ftpserver/trunk/core/src/main/java/org/apache/ftpserver/command/impl/RETR.java (original)
+++ mina/ftpserver/trunk/core/src/main/java/org/apache/ftpserver/command/impl/RETR.java Fri Oct 31 07:58:58 2008
@@ -162,7 +162,7 @@
                 is = openInputStream(session, file, skipLen);
 
                 // transfer data
-                long transSz = dataConnection.transferToClient(is);
+                long transSz = dataConnection.transferToClient(session.getFtpletSession(), is);
 
                 // log message
                 String userName = session.getUser().getName();

Modified: mina/ftpserver/trunk/core/src/main/java/org/apache/ftpserver/command/impl/STOR.java
URL: http://svn.apache.org/viewvc/mina/ftpserver/trunk/core/src/main/java/org/apache/ftpserver/command/impl/STOR.java?rev=709438&r1=709437&r2=709438&view=diff
==============================================================================
--- mina/ftpserver/trunk/core/src/main/java/org/apache/ftpserver/command/impl/STOR.java (original)
+++ mina/ftpserver/trunk/core/src/main/java/org/apache/ftpserver/command/impl/STOR.java Fri Oct 31 07:58:58 2008
@@ -142,7 +142,7 @@
             OutputStream outStream = null;
             try {
                 outStream = file.createOutputStream(skipLen);
-                long transSz = dataConnection.transferFromClient(outStream);
+                long transSz = dataConnection.transferFromClient(session.getFtpletSession(), outStream);
 
                 // log message
                 String userName = session.getUser().getName();

Modified: mina/ftpserver/trunk/core/src/main/java/org/apache/ftpserver/command/impl/STOU.java
URL: http://svn.apache.org/viewvc/mina/ftpserver/trunk/core/src/main/java/org/apache/ftpserver/command/impl/STOU.java?rev=709438&r1=709437&r2=709438&view=diff
==============================================================================
--- mina/ftpserver/trunk/core/src/main/java/org/apache/ftpserver/command/impl/STOU.java (original)
+++ mina/ftpserver/trunk/core/src/main/java/org/apache/ftpserver/command/impl/STOU.java Fri Oct 31 07:58:58 2008
@@ -149,7 +149,7 @@
                 os = file.createOutputStream(0L);
 
                 // transfer data
-                long transSz = dataConnection.transferFromClient(os);
+                long transSz = dataConnection.transferFromClient(session.getFtpletSession(), os);
 
                 // log message
                 String userName = session.getUser().getName();

Modified: mina/ftpserver/trunk/core/src/main/java/org/apache/ftpserver/impl/DefaultFtpSession.java
URL: http://svn.apache.org/viewvc/mina/ftpserver/trunk/core/src/main/java/org/apache/ftpserver/impl/DefaultFtpSession.java?rev=709438&r1=709437&r2=709438&view=diff
==============================================================================
--- mina/ftpserver/trunk/core/src/main/java/org/apache/ftpserver/impl/DefaultFtpSession.java (original)
+++ mina/ftpserver/trunk/core/src/main/java/org/apache/ftpserver/impl/DefaultFtpSession.java Fri Oct 31 07:58:58 2008
@@ -231,4 +231,21 @@
         return ioSession.isSecure();
     }
 
+    /**
+     * Increase the number of bytes written on the data connection
+     * @param increment The number of bytes written
+     */
+    public void increaseWrittenDataBytes(int increment) {
+        ioSession.increaseWrittenDataBytes(increment);
+    }
+
+    /**
+     * Increase the number of bytes read on the data connection
+     * @param increment The number of bytes written
+     */
+    public void increaseReadDataBytes(int increment) {
+        ioSession.increaseReadDataBytes(increment);
+    }
+
+    
 }

Modified: mina/ftpserver/trunk/core/src/main/java/org/apache/ftpserver/impl/FtpIoSession.java
URL: http://svn.apache.org/viewvc/mina/ftpserver/trunk/core/src/main/java/org/apache/ftpserver/impl/FtpIoSession.java?rev=709438&r1=709437&r2=709438&view=diff
==============================================================================
--- mina/ftpserver/trunk/core/src/main/java/org/apache/ftpserver/impl/FtpIoSession.java (original)
+++ mina/ftpserver/trunk/core/src/main/java/org/apache/ftpserver/impl/FtpIoSession.java Fri Oct 31 07:58:58 2008
@@ -42,6 +42,7 @@
 import org.apache.mina.core.service.IoHandler;
 import org.apache.mina.core.service.IoService;
 import org.apache.mina.core.service.TransportMetadata;
+import org.apache.mina.core.session.AbstractIoSession;
 import org.apache.mina.core.session.IdleStatus;
 import org.apache.mina.core.session.IoSession;
 import org.apache.mina.core.session.IoSessionConfig;
@@ -770,4 +771,24 @@
         return getFilterChain().contains(SslFilter.class);
     }
 
+    /**
+     * Increase the number of bytes written on the data connection
+     * @param increment The number of bytes written
+     */
+    public void increaseWrittenDataBytes(int increment) {
+        if(wrappedSession instanceof AbstractIoSession ) {
+            ((AbstractIoSession)wrappedSession).increaseScheduledWriteBytes(increment);
+            ((AbstractIoSession)wrappedSession).increaseWrittenBytes(increment, System.currentTimeMillis());
+        }
+    }
+
+    /**
+     * Increase the number of bytes read on the data connection
+     * @param increment The number of bytes written
+     */
+    public void increaseReadDataBytes(int increment) {
+        if(wrappedSession instanceof AbstractIoSession ) {
+            ((AbstractIoSession)wrappedSession).increaseReadBytes(increment, System.currentTimeMillis());
+        }
+    }
 }

Modified: mina/ftpserver/trunk/core/src/main/java/org/apache/ftpserver/impl/IODataConnection.java
URL: http://svn.apache.org/viewvc/mina/ftpserver/trunk/core/src/main/java/org/apache/ftpserver/impl/IODataConnection.java?rev=709438&r1=709437&r2=709438&view=diff
==============================================================================
--- mina/ftpserver/trunk/core/src/main/java/org/apache/ftpserver/impl/IODataConnection.java (original)
+++ mina/ftpserver/trunk/core/src/main/java/org/apache/ftpserver/impl/IODataConnection.java Fri Oct 31 07:58:58 2008
@@ -32,6 +32,7 @@
 
 import org.apache.ftpserver.ftplet.DataConnection;
 import org.apache.ftpserver.ftplet.DataType;
+import org.apache.ftpserver.ftplet.FtpSession;
 import org.apache.ftpserver.usermanager.impl.TransferRateRequest;
 import org.apache.ftpserver.util.IoUtils;
 
@@ -111,8 +112,8 @@
      * @seeorg.apache.ftpserver.FtpDataConnection2#transferFromClient(java.io.
      * OutputStream)
      */
-    public final long transferFromClient(final OutputStream out)
-            throws IOException {
+    public final long transferFromClient(FtpSession session,
+            final OutputStream out) throws IOException {
         TransferRateRequest transferRateRequest = new TransferRateRequest();
         transferRateRequest = (TransferRateRequest) session.getUser()
                 .authorize(transferRateRequest);
@@ -123,7 +124,7 @@
 
         InputStream is = getDataInputStream();
         try {
-            return transfer(is, out, maxRate);
+            return transfer(session, false, is, out, maxRate);
         } finally {
             IoUtils.close(is);
         }
@@ -136,7 +137,8 @@
      * org.apache.ftpserver.FtpDataConnection2#transferToClient(java.io.InputStream
      * )
      */
-    public final long transferToClient(final InputStream in) throws IOException {
+    public final long transferToClient(FtpSession session, final InputStream in)
+            throws IOException {
         TransferRateRequest transferRateRequest = new TransferRateRequest();
         transferRateRequest = (TransferRateRequest) session.getUser()
                 .authorize(transferRateRequest);
@@ -147,7 +149,7 @@
 
         OutputStream out = getDataOutputStream();
         try {
-            return transfer(in, out, maxRate);
+            return transfer(session, true, in, out, maxRate);
         } finally {
             IoUtils.close(out);
         }
@@ -160,12 +162,19 @@
      * org.apache.ftpserver.FtpDataConnection2#transferToClient(java.lang.String
      * )
      */
-    public final void transferToClient(final String str) throws IOException {
+    public final void transferToClient(FtpSession session, final String str)
+            throws IOException {
         OutputStream out = getDataOutputStream();
         Writer writer = null;
         try {
             writer = new OutputStreamWriter(out, "UTF-8");
             writer.write(str);
+
+            // update session
+            if (session instanceof DefaultFtpSession) {
+                ((DefaultFtpSession) session).increaseWrittenDataBytes(str
+                        .getBytes("UTF-8").length);
+            }
         } finally {
             if (writer != null) {
                 writer.flush();
@@ -175,8 +184,9 @@
 
     }
 
-    private final long transfer(final InputStream in, final OutputStream out,
-            final int maxRate) throws IOException {
+    private final long transfer(FtpSession session, boolean isWrite,
+            final InputStream in, final OutputStream out, final int maxRate)
+            throws IOException {
         long transferredSize = 0L;
 
         boolean isAscii = session.getDataType() == DataType.ASCII;
@@ -190,6 +200,11 @@
 
             bos = IoUtils.getBufferedOutputStream(out);
 
+            DefaultFtpSession defaultFtpSession = null;
+            if (session instanceof DefaultFtpSession) {
+                defaultFtpSession = (DefaultFtpSession) session;
+            }
+
             boolean lastWasCR = false;
             while (true) {
 
@@ -222,6 +237,15 @@
                     break;
                 }
 
+                // update MINA session
+                if (defaultFtpSession != null) {
+                    if (isWrite) {
+                        defaultFtpSession.increaseWrittenDataBytes(count);
+                    } else {
+                        defaultFtpSession.increaseReadDataBytes(count);
+                    }
+                }
+
                 // write data
                 // if ascii, replace \n by \r\n
                 if (isAscii) {

Added: mina/ftpserver/trunk/core/src/test/java/org/apache/ftpserver/clienttests/DataTransferTimeoutTest.java
URL: http://svn.apache.org/viewvc/mina/ftpserver/trunk/core/src/test/java/org/apache/ftpserver/clienttests/DataTransferTimeoutTest.java?rev=709438&view=auto
==============================================================================
--- mina/ftpserver/trunk/core/src/test/java/org/apache/ftpserver/clienttests/DataTransferTimeoutTest.java (added)
+++ mina/ftpserver/trunk/core/src/test/java/org/apache/ftpserver/clienttests/DataTransferTimeoutTest.java Fri Oct 31 07:58:58 2008
@@ -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.ftpserver.clienttests;
+
+import java.io.File;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.Arrays;
+
+import org.apache.ftpserver.FtpServerFactory;
+import org.apache.ftpserver.listener.ListenerFactory;
+import org.apache.ftpserver.test.TestUtil;
+
+/**
+*
+* Test for FTPSERVER-170
+*
+* @author The Apache MINA Project (dev@mina.apache.org)
+* @version $Rev$, $Date$
+*
+*/
+public class DataTransferTimeoutTest extends ClientTestTemplate {
+    private static final String TESTDATA = "TESTDATA\r\nline2\r\n";
+
+    private static final String ENCODING = "UTF-8";
+
+    private static final String TEST_FILENAME = "test.txt";
+    
+    private static final File TEST_FILE = new File(ROOT_DIR, TEST_FILENAME);
+
+
+    private static byte[] testData = null;
+
+    
+    
+    @Override
+    protected FtpServerFactory createServer() throws Exception {
+        FtpServerFactory serverFactory = super.createServer();
+        
+        // set a really short timeout
+        ListenerFactory listenerFactory = new ListenerFactory(serverFactory.getListener("default"));
+        listenerFactory.setIdleTimeout(1);
+        
+        serverFactory.addListener("default", listenerFactory.createListener());
+        
+        return serverFactory;
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see org.apache.ftpserver.clienttests.ClientTestTemplate#setUp()
+     */
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        testData = TESTDATA.getBytes(ENCODING);
+
+        client.login(ADMIN_USERNAME, ADMIN_PASSWORD);
+    }
+
+    public void testTimeoutForStore() throws Exception {
+        OutputStream os = client.storeFileStream(TEST_FILENAME);
+        
+        os.write(1);
+        
+        // make sure this take longer than the timeout time, but not timeout between writes...
+        for(int i = 0; i<100; i++) {
+            Thread.sleep(20);
+            os.write(1);   
+            os.flush();
+        }
+        
+        os.close();
+
+        client.completePendingCommand();
+        
+        // we should not have been disconnected
+        client.noop();
+    }
+
+    public void testTimeoutForRetreive() throws Exception {
+        // as used by IODataConnection
+        int bufferSize = 4096;
+        byte[] buffer = new byte[bufferSize];
+        
+        byte[] testData = new byte[200 * bufferSize];
+        Arrays.fill(testData, (byte)1);
+        
+        TestUtil.writeDataToFile(TEST_FILE, testData);
+        InputStream is = client.retrieveFileStream(TEST_FILENAME);
+
+        // read one buffer size at a time, trying to trigger IODataConnection to update
+        // the session timeout for each read
+        for(int i = 0; i<100; i++) {
+            Thread.sleep(20);
+            is.read(buffer);   
+        }
+        
+        is.close();
+
+        client.completePendingCommand();
+        
+        // we should not have been disconnected
+        client.noop();
+    }
+}

Modified: mina/ftpserver/trunk/ftplet-api/src/main/java/org/apache/ftpserver/ftplet/DataConnection.java
URL: http://svn.apache.org/viewvc/mina/ftpserver/trunk/ftplet-api/src/main/java/org/apache/ftpserver/ftplet/DataConnection.java?rev=709438&r1=709437&r2=709438&view=diff
==============================================================================
--- mina/ftpserver/trunk/ftplet-api/src/main/java/org/apache/ftpserver/ftplet/DataConnection.java (original)
+++ mina/ftpserver/trunk/ftplet-api/src/main/java/org/apache/ftpserver/ftplet/DataConnection.java Fri Oct 31 07:58:58 2008
@@ -39,7 +39,7 @@
      * @return The length of the transferred data
      * @throws IOException
      */
-    long transferFromClient(OutputStream out) throws IOException;
+    long transferFromClient(FtpSession session, OutputStream out) throws IOException;
 
     /**
      * Transfer data to the client (e.g. RETR).
@@ -49,7 +49,7 @@
      * @return The length of the transferred data
      * @throws IOException
      */
-    long transferToClient(InputStream in) throws IOException;
+    long transferToClient(FtpSession session, InputStream in) throws IOException;
 
     /**
      * Transfer a string to the client, e.g. during LIST
@@ -58,6 +58,6 @@
      *            The string to transfer
      * @throws IOException
      */
-    void transferToClient(String str) throws IOException;
+    void transferToClient(FtpSession session, String str) throws IOException;
 
 }
\ No newline at end of file

Modified: mina/ftpserver/trunk/ftplet-api/src/main/java/org/apache/ftpserver/ftplet/FtpSession.java
URL: http://svn.apache.org/viewvc/mina/ftpserver/trunk/ftplet-api/src/main/java/org/apache/ftpserver/ftplet/FtpSession.java?rev=709438&r1=709437&r2=709438&view=diff
==============================================================================
--- mina/ftpserver/trunk/ftplet-api/src/main/java/org/apache/ftpserver/ftplet/FtpSession.java (original)
+++ mina/ftpserver/trunk/ftplet-api/src/main/java/org/apache/ftpserver/ftplet/FtpSession.java Fri Oct 31 07:58:58 2008
@@ -165,5 +165,4 @@
      * @return true if the control socket is secured
      */
     boolean isSecure();
-
 }