Home | History | Annotate | Download | only in command
      1 /*
      2  * Copyright 2007 the original author or authors.
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 package org.mockftpserver.stub.command;
     17 
     18 import java.io.IOException;
     19 import java.net.InetAddress;
     20 
     21 
     22 import org.apache.log4j.Logger;
     23 import org.mockftpserver.core.command.Command;
     24 import org.mockftpserver.core.command.CommandHandler;
     25 import org.mockftpserver.core.command.InvocationRecord;
     26 import org.mockftpserver.core.command.ReplyCodes;
     27 import org.mockftpserver.core.session.Session;
     28 import org.mockftpserver.core.util.Assert;
     29 
     30 /**
     31  * CommandHandler for the PASV (Passove Mode) command. Request the Session to switch to passive
     32  * data connection mode. Return a reply code of 227, along with response text of the form:
     33  * "<i>Entering Passive Mode. (h1,h2,h3,h4,p1,p2)</i>", where <i>h1..h4</i> are the 4
     34  * bytes of the 32-bit internet host address of the server, and <i>p1..p2</i> are the 2
     35  * bytes of the 16-bit TCP port address of the data connection on the server to which
     36  * the client must connect. See RFC959 for more information.
     37  * <p>
     38  * Each invocation record stored by this CommandHandler contains no data elements.
     39  *
     40  * @version $Revision$ - $Date$
     41  *
     42  * @author Chris Mair
     43  */
     44 public final class PasvCommandHandler extends AbstractStubCommandHandler implements CommandHandler {
     45 
     46     private static final Logger LOG = Logger.getLogger(PasvCommandHandler.class);
     47 
     48     /**
     49      * Constructor. Initialize the replyCode.
     50      */
     51     public PasvCommandHandler() {
     52         setReplyCode(ReplyCodes.PASV_OK);
     53     }
     54 
     55     /**
     56      * @throws IOException
     57      * @see org.mockftpserver.core.command.CommandHandler#handleCommand(Command, Session, InvocationRecord)
     58      */
     59     public void handleCommand(Command command, Session session, InvocationRecord invocationRecord)
     60             throws IOException {
     61 
     62         int port = session.switchToPassiveMode();
     63         InetAddress server = session.getServerHost();
     64 
     65         Assert.isTrue(port > -1, "The server-side port is invalid: " + port);
     66         LOG.debug("server=" + server + " port=" + port);
     67         String hostAndPort = "(" + convertHostAndPortToStringOfBytes(server, port) + ")";
     68 
     69         sendReply(session, hostAndPort);
     70     }
     71 
     72     /**
     73      * Convert the InetAddess and port number to a comma-delimited list of byte values,
     74      * suitable for the response String from the PASV command.
     75      * @param host - the InetAddress
     76      * @param port - the port number
     77      * @return the comma-delimited list of byte values, e.g., "196,168,44,55,23,77"
     78      */
     79     static String convertHostAndPortToStringOfBytes(InetAddress host, int port) {
     80         StringBuffer buffer = new StringBuffer();
     81         byte[] address = host.getAddress();
     82         for (int i = 0; i < address.length; i++) {
     83             int positiveValue = (address[i] >=0) ? address[i] : 256 + address[i];
     84             buffer.append(positiveValue);
     85             buffer.append(",");
     86         }
     87         int p1 = port >> 8;
     88         int p2 = port % 256;
     89         buffer.append(String.valueOf(p1));
     90         buffer.append(",");
     91         buffer.append(String.valueOf(p2));
     92         return buffer.toString();
     93     }
     94 
     95 }
     96