Package org.apache.ftpserver.impl

Source Code of org.apache.ftpserver.impl.FtpIoSession

/*
* 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.impl;

import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.security.cert.Certificate;
import java.util.Date;
import java.util.Set;
import java.util.UUID;

import javax.net.ssl.SSLPeerUnverifiedException;
import javax.net.ssl.SSLSession;

import org.apache.ftpserver.ftplet.DataType;
import org.apache.ftpserver.ftplet.FileSystemView;
import org.apache.ftpserver.ftplet.FtpFile;
import org.apache.ftpserver.ftplet.FtpReply;
import org.apache.ftpserver.ftplet.FtpSession;
import org.apache.ftpserver.ftplet.Structure;
import org.apache.ftpserver.ftplet.User;
import org.apache.ftpserver.listener.Listener;
import org.apache.mina.core.filterchain.IoFilterChain;
import org.apache.mina.core.future.CloseFuture;
import org.apache.mina.core.future.ReadFuture;
import org.apache.mina.core.future.WriteFuture;
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;
import org.apache.mina.core.write.WriteRequest;
import org.apache.mina.core.write.WriteRequestQueue;
import org.apache.mina.filter.ssl.SslFilter;
import org.slf4j.LoggerFactory;

/**
* <strong>Internal class, do not use directly.</strong>
*
* @author <a href="http://mina.apache.org">Apache MINA Project</a> *
*/
public class FtpIoSession implements IoSession {

  /**
   * Contains user name between USER and PASS commands
   */
  public static final String ATTRIBUTE_PREFIX = "org.apache.ftpserver.";

  private static final String ATTRIBUTE_USER_ARGUMENT = ATTRIBUTE_PREFIX
      + "user-argument";

  private static final String ATTRIBUTE_SESSION_ID = ATTRIBUTE_PREFIX
      + "session-id";

  private static final String ATTRIBUTE_USER = ATTRIBUTE_PREFIX + "user";

  private static final String ATTRIBUTE_LANGUAGE = ATTRIBUTE_PREFIX
      + "language";

  private static final String ATTRIBUTE_LOGIN_TIME = ATTRIBUTE_PREFIX
      + "login-time";

  private static final String ATTRIBUTE_DATA_CONNECTION = ATTRIBUTE_PREFIX
      + "data-connection";

  private static final String ATTRIBUTE_FILE_SYSTEM = ATTRIBUTE_PREFIX
      + "file-system";

  private static final String ATTRIBUTE_RENAME_FROM = ATTRIBUTE_PREFIX
      + "rename-from";

  private static final String ATTRIBUTE_FILE_OFFSET = ATTRIBUTE_PREFIX
      + "file-offset";

  private static final String ATTRIBUTE_DATA_TYPE = ATTRIBUTE_PREFIX
      + "data-type";

  private static final String ATTRIBUTE_STRUCTURE = ATTRIBUTE_PREFIX
      + "structure";

  private static final String ATTRIBUTE_FAILED_LOGINS = ATTRIBUTE_PREFIX
      + "failed-logins";

  private static final String ATTRIBUTE_LISTENER = ATTRIBUTE_PREFIX
      + "listener";

  private static final String ATTRIBUTE_MAX_IDLE_TIME = ATTRIBUTE_PREFIX
      + "max-idle-time";

  private static final String ATTRIBUTE_LAST_ACCESS_TIME = ATTRIBUTE_PREFIX
      + "last-access-time";

  private static final String ATTRIBUTE_CACHED_REMOTE_ADDRESS = ATTRIBUTE_PREFIX
      + "cached-remote-address";

  private IoSession wrappedSession;

  private FtpServerContext context;

  /**
   * Last reply that was sent to the client, if any.
   */
  private FtpReply lastReply = null;

  /* Begin wrapped IoSession methods */

  /**
   * @see IoSession#close()
   */
  public CloseFuture close() {
    return wrappedSession.close();
  }

  /**
   * @see IoSession#close(boolean)
   */
  public CloseFuture close(boolean immediately) {
    return wrappedSession.close(immediately);
  }

  /**
   * @see IoSession#containsAttribute(Object)
   */
  public boolean containsAttribute(Object key) {
    return wrappedSession.containsAttribute(key);
  }

  /**
   * @see IoSession#getAttachment()
   */
  @SuppressWarnings("deprecation")
  public Object getAttachment() {
    return wrappedSession.getAttachment();
  }

  /**
   * @see IoSession#getAttribute(Object)
   */
  public Object getAttribute(Object key) {
    return wrappedSession.getAttribute(key);
  }

  /**
   * @see IoSession#getAttribute(Object, Object)
   */
  public Object getAttribute(Object key, Object defaultValue) {
    return wrappedSession.getAttribute(key, defaultValue);
  }

  /**
   * @see IoSession#getAttributeKeys()
   */
  public Set<Object> getAttributeKeys() {
    return wrappedSession.getAttributeKeys();
  }

  /**
   * @see IoSession#getBothIdleCount()
   */
  public int getBothIdleCount() {
    return wrappedSession.getBothIdleCount();
  }

  /**
   * @see IoSession#getCloseFuture()
   */
  public CloseFuture getCloseFuture() {
    return wrappedSession.getCloseFuture();
  }

  /**
   * @see IoSession#getConfig()
   */
  public IoSessionConfig getConfig() {
    return wrappedSession.getConfig();
  }

  /**
   * @see IoSession#getCreationTime()
   */
  public long getCreationTime() {
    return wrappedSession.getCreationTime();
  }

  /**
   * @see IoSession#getFilterChain()
   */
  public IoFilterChain getFilterChain() {
    return wrappedSession.getFilterChain();
  }

  /**
   * @see IoSession#getHandler()
   */
  public IoHandler getHandler() {
    return wrappedSession.getHandler();
  }

  /**
   * @see IoSession#getId()
   */
  public long getId() {
    return wrappedSession.getId();
  }

  /**
   * @see IoSession#getIdleCount(IdleStatus)
   */
  public int getIdleCount(IdleStatus status) {
    return wrappedSession.getIdleCount(status);
  }

  /**
   * @see IoSession#getLastBothIdleTime()
   */
  public long getLastBothIdleTime() {
    return wrappedSession.getLastBothIdleTime();
  }

  /**
   * @see IoSession#getLastIdleTime(IdleStatus)
   */
  public long getLastIdleTime(IdleStatus status) {
    return wrappedSession.getLastIdleTime(status);
  }

  /**
   * @see IoSession#getLastIoTime()
   */
  public long getLastIoTime() {
    return wrappedSession.getLastIoTime();
  }

  /**
   * @see IoSession#getLastReadTime()
   */
  public long getLastReadTime() {
    return wrappedSession.getLastReadTime();
  }

  /**
   * @see IoSession#getLastReaderIdleTime()
   */
  public long getLastReaderIdleTime() {
    return wrappedSession.getLastReaderIdleTime();
  }

  /**
   * @see IoSession#getLastWriteTime()
   */
  public long getLastWriteTime() {
    return wrappedSession.getLastWriteTime();
  }

  /**
   * @see IoSession#getLastWriterIdleTime()
   */
  public long getLastWriterIdleTime() {
    return wrappedSession.getLastWriterIdleTime();
  }

  /**
   * @see IoSession#getLocalAddress()
   */
  public SocketAddress getLocalAddress() {
    return wrappedSession.getLocalAddress();
  }

  /**
   * @see IoSession#getReadBytes()
   */
  public long getReadBytes() {
    return wrappedSession.getReadBytes();
  }

  /**
   * @see IoSession#getReadBytesThroughput()
   */
  public double getReadBytesThroughput() {
    return wrappedSession.getReadBytesThroughput();
  }

  /**
   * @see IoSession#getReadMessages()
   */
  public long getReadMessages() {
    return wrappedSession.getReadMessages();
  }

  /**
   * @see IoSession#getReadMessagesThroughput()
   */
  public double getReadMessagesThroughput() {
    return wrappedSession.getReadMessagesThroughput();
  }

  /**
   * @see IoSession#getReaderIdleCount()
   */
  public int getReaderIdleCount() {
    return wrappedSession.getReaderIdleCount();
  }

  /**
   * @see IoSession#getRemoteAddress()
   */
  public SocketAddress getRemoteAddress() {
    // when closing a socket, the remote address might be reset to null
    // therefore, we attempt to keep a cached copy around

    SocketAddress address = wrappedSession.getRemoteAddress();
    if (address == null
        && containsAttribute(ATTRIBUTE_CACHED_REMOTE_ADDRESS)) {
      return (SocketAddress) getAttribute(ATTRIBUTE_CACHED_REMOTE_ADDRESS);
    } else {
      setAttribute(ATTRIBUTE_CACHED_REMOTE_ADDRESS, address);
      return address;
    }
  }

  /**
   * @see IoSession#getScheduledWriteBytes()
   */
  public long getScheduledWriteBytes() {
    return wrappedSession.getScheduledWriteBytes();
  }

  /**
   * @see IoSession#getScheduledWriteMessages()
   */
  public int getScheduledWriteMessages() {
    return wrappedSession.getScheduledWriteMessages();
  }

  /**
   * @see IoSession#getService()
   */
  public IoService getService() {
    return wrappedSession.getService();
  }

  /**
   * @see IoSession#getServiceAddress()
   */
  public SocketAddress getServiceAddress() {
    return wrappedSession.getServiceAddress();
  }

  /**
   * @see IoSession#getTransportMetadata()
   */
  public TransportMetadata getTransportMetadata() {
    return wrappedSession.getTransportMetadata();
  }

  /**
   * @see IoSession#getWriterIdleCount()
   */
  public int getWriterIdleCount() {
    return wrappedSession.getWriterIdleCount();
  }

  /**
   * @see IoSession#getWrittenBytes()
   */
  public long getWrittenBytes() {
    return wrappedSession.getWrittenBytes();
  }

  /**
   * @see IoSession#getWrittenBytesThroughput()
   */
  public double getWrittenBytesThroughput() {
    return wrappedSession.getWrittenBytesThroughput();
  }

  /**
   * @see IoSession#getWrittenMessages()
   */
  public long getWrittenMessages() {
    return wrappedSession.getWrittenMessages();
  }

  /**
   * @see IoSession#getWrittenMessagesThroughput()
   */
  public double getWrittenMessagesThroughput() {
    return wrappedSession.getWrittenMessagesThroughput();
  }

  /**
   * @see IoSession#isClosing()
   */
  public boolean isClosing() {
    return wrappedSession.isClosing();
  }

  /**
   * @see IoSession#isConnected()
   */
  public boolean isConnected() {
    return wrappedSession.isConnected();
  }

  /**
   * @see IoSession#isIdle(IdleStatus)
   */
  public boolean isIdle(IdleStatus status) {
    return wrappedSession.isIdle(status);
  }

  /**
   * @see IoSession#read()
   */
  public ReadFuture read() {
    return wrappedSession.read();
  }

  /**
   * @see IoSession#removeAttribute(Object)
   */
  public Object removeAttribute(Object key) {
    return wrappedSession.removeAttribute(key);
  }

  /**
   * @see IoSession#removeAttribute(Object, Object)
   */
  public boolean removeAttribute(Object key, Object value) {
    return wrappedSession.removeAttribute(key, value);
  }

  /**
   * @see IoSession#replaceAttribute(Object, Object, Object)
   */
  public boolean replaceAttribute(Object key, Object oldValue, Object newValue) {
    return wrappedSession.replaceAttribute(key, oldValue, newValue);
  }

  /**
   * @see IoSession#resumeRead()
   */
  public void resumeRead() {
    wrappedSession.resumeRead();
  }

  /**
   * @see IoSession#resumeWrite()
   */
  public void resumeWrite() {
    wrappedSession.resumeWrite();
  }

  /**
   * @see IoSession#setAttachment(Object)
   */
  @SuppressWarnings("deprecation")
  public Object setAttachment(Object attachment) {
    return wrappedSession.setAttachment(attachment);
  }

  /**
   * @see IoSession#setAttribute(Object)
   */
  public Object setAttribute(Object key) {
    return wrappedSession.setAttribute(key);
  }

  /**
   * @see IoSession#setAttribute(Object, Object)
   */
  public Object setAttribute(Object key, Object value) {
    return wrappedSession.setAttribute(key, value);
  }

  /**
   * @see IoSession#setAttributeIfAbsent(Object)
   */
  public Object setAttributeIfAbsent(Object key) {
    return wrappedSession.setAttributeIfAbsent(key);
  }

  /**
   * @see IoSession#setAttributeIfAbsent(Object, Object)
   */
  public Object setAttributeIfAbsent(Object key, Object value) {
    return wrappedSession.setAttributeIfAbsent(key, value);
  }

  /**
   * @see IoSession#suspendRead()
   */
  public void suspendRead() {
    wrappedSession.suspendRead();
  }

  /**
   * @see IoSession#suspendWrite()
   */
  public void suspendWrite() {
    wrappedSession.suspendWrite();
  }

  /**
   * @see IoSession#write(Object)
   */
  public WriteFuture write(Object message) {
    WriteFuture future = wrappedSession.write(message);
    this.lastReply = (FtpReply) message;
    return future;
  }

  /**
   * @see IoSession#write(Object, SocketAddress)
   */
  public WriteFuture write(Object message, SocketAddress destination) {
    WriteFuture future = wrappedSession.write(message, destination);
    this.lastReply = (FtpReply) message;
    return future;
  }

  /* End wrapped IoSession methods */

  public void resetState() {
    removeAttribute(ATTRIBUTE_RENAME_FROM);
    removeAttribute(ATTRIBUTE_FILE_OFFSET);
  }

  public synchronized ServerDataConnectionFactory getDataConnection() {
    if (containsAttribute(ATTRIBUTE_DATA_CONNECTION)) {
      return (ServerDataConnectionFactory) getAttribute(ATTRIBUTE_DATA_CONNECTION);
    } else {
      IODataConnectionFactory dataCon = new IODataConnectionFactory(
          context, this);
      dataCon
          .setServerControlAddress(((InetSocketAddress) getLocalAddress())
              .getAddress());
      setAttribute(ATTRIBUTE_DATA_CONNECTION, dataCon);

      return dataCon;
    }
  }

  public FileSystemView getFileSystemView() {
    return (FileSystemView) getAttribute(ATTRIBUTE_FILE_SYSTEM);
  }

  public User getUser() {
    return (User) getAttribute(ATTRIBUTE_USER);
  }

  /**
   * Is logged-in
   */
  public boolean isLoggedIn() {
    return containsAttribute(ATTRIBUTE_USER);
  }

  public Listener getListener() {
    return (Listener) getAttribute(ATTRIBUTE_LISTENER);
  }

  public void setListener(Listener listener) {
    setAttribute(ATTRIBUTE_LISTENER, listener);
  }

  public FtpSession getFtpletSession() {
    return new DefaultFtpSession(this);
  }

  public String getLanguage() {
    return (String) getAttribute(ATTRIBUTE_LANGUAGE);
  }

  public void setLanguage(String language) {
    setAttribute(ATTRIBUTE_LANGUAGE, language);

  }

  public String getUserArgument() {
    return (String) getAttribute(ATTRIBUTE_USER_ARGUMENT);
  }

  public void setUser(User user) {
    setAttribute(ATTRIBUTE_USER, user);

  }

  public void setUserArgument(String userArgument) {
    setAttribute(ATTRIBUTE_USER_ARGUMENT, userArgument);

  }

  public int getMaxIdleTime() {
    return (Integer) getAttribute(ATTRIBUTE_MAX_IDLE_TIME, 0);
  }

  public void setMaxIdleTime(int maxIdleTime) {
    setAttribute(ATTRIBUTE_MAX_IDLE_TIME, maxIdleTime);

    int listenerTimeout = getListener().getIdleTimeout();

    // the listener timeout should be the upper limit, unless set to
    // unlimited
    // if the user limit is set to be unlimited, use the listener value is
    // the threshold
    // (already used as the default for all sessions)
    // else, if the user limit is less than the listener idle time, use the
    // user limit
    if (listenerTimeout <= 0
        || (maxIdleTime > 0 && maxIdleTime < listenerTimeout)) {
      wrappedSession.getConfig().setBothIdleTime(maxIdleTime);
    }
  }

  public synchronized void increaseFailedLogins() {
    int failedLogins = (Integer) getAttribute(ATTRIBUTE_FAILED_LOGINS, 0);
    failedLogins++;
    setAttribute(ATTRIBUTE_FAILED_LOGINS, failedLogins);
  }

  public int getFailedLogins() {
    return (Integer) getAttribute(ATTRIBUTE_FAILED_LOGINS, 0);
  }

  public void setLogin(FileSystemView fsview) {
    setAttribute(ATTRIBUTE_LOGIN_TIME, new Date());
    setAttribute(ATTRIBUTE_FILE_SYSTEM, fsview);
  }

  public void reinitialize() {
    logoutUser();
    removeAttribute(ATTRIBUTE_USER);
    removeAttribute(ATTRIBUTE_USER_ARGUMENT);
    removeAttribute(ATTRIBUTE_LOGIN_TIME);
    removeAttribute(ATTRIBUTE_FILE_SYSTEM);
    removeAttribute(ATTRIBUTE_RENAME_FROM);
    removeAttribute(ATTRIBUTE_FILE_OFFSET);
  }

  public void logoutUser() {
    ServerFtpStatistics stats = ((ServerFtpStatistics) context
        .getFtpStatistics());
    if (stats != null) {
      stats.setLogout(this);
      LoggerFactory.getLogger(this.getClass()).debug(
          "Statistics login decreased due to user logout");
    } else {
      LoggerFactory
          .getLogger(this.getClass())
          .warn(
              "Statistics not available in session, can not decrease login  count");
    }
  }

  public void setFileOffset(long fileOffset) {
    setAttribute(ATTRIBUTE_FILE_OFFSET, fileOffset);

  }

  public void setRenameFrom(FtpFile renFr) {
    setAttribute(ATTRIBUTE_RENAME_FROM, renFr);

  }

  public FtpFile getRenameFrom() {
    return (FtpFile) getAttribute(ATTRIBUTE_RENAME_FROM);
  }

  public long getFileOffset() {
    return (Long) getAttribute(ATTRIBUTE_FILE_OFFSET, 0L);
  }

  public void setStructure(Structure structure) {
    setAttribute(ATTRIBUTE_STRUCTURE, structure);
  }

  public void setDataType(DataType dataType) {
    setAttribute(ATTRIBUTE_DATA_TYPE, dataType);

  }

  /**
   * @see FtpSession#getSessionId()
   */
  public UUID getSessionId() {
    synchronized (wrappedSession) {
      if (!wrappedSession.containsAttribute(ATTRIBUTE_SESSION_ID)) {
        wrappedSession.setAttribute(ATTRIBUTE_SESSION_ID, UUID
            .randomUUID());
      }
      return (UUID) wrappedSession.getAttribute(ATTRIBUTE_SESSION_ID);
    }
  }

  public FtpIoSession(IoSession wrappedSession, FtpServerContext context) {
    this.wrappedSession = wrappedSession;
    this.context = context;
  }

  public Structure getStructure() {
    return (Structure) getAttribute(ATTRIBUTE_STRUCTURE, Structure.FILE);
  }

  public DataType getDataType() {
    return (DataType) getAttribute(ATTRIBUTE_DATA_TYPE, DataType.ASCII);
  }

  public Date getLoginTime() {
    return (Date) getAttribute(ATTRIBUTE_LOGIN_TIME);
  }

  public Date getLastAccessTime() {
    return (Date) getAttribute(ATTRIBUTE_LAST_ACCESS_TIME);
  }

  public Certificate[] getClientCertificates() {
    if (getFilterChain().contains(SslFilter.class)) {
      SslFilter sslFilter = (SslFilter) getFilterChain().get(
          SslFilter.class);

      SSLSession sslSession = sslFilter.getSslSession(this);

      if (sslSession != null) {
        try {
          return sslSession.getPeerCertificates();
        } catch (SSLPeerUnverifiedException e) {
          // ignore, certificate will not be available to the session
        }
      }

    }

    // no certificates available
    return null;

  }

  public void updateLastAccessTime() {
    setAttribute(ATTRIBUTE_LAST_ACCESS_TIME, new Date());

  }

  /**
   * @see IoSession#getCurrentWriteMessage()
   */
  public Object getCurrentWriteMessage() {
    return wrappedSession.getCurrentWriteMessage();
  }

  /**
   * @see IoSession#getCurrentWriteRequest()
   */
  public WriteRequest getCurrentWriteRequest() {
    return wrappedSession.getCurrentWriteRequest();
  }

  /**
   * @see IoSession#isBothIdle()
   */
  public boolean isBothIdle() {
    return wrappedSession.isBothIdle();
  }

  /**
   * @see IoSession#isReaderIdle()
   */
  public boolean isReaderIdle() {
    return wrappedSession.isReaderIdle();
  }

  /**
   * @see IoSession#isWriterIdle()
   */
  public boolean isWriterIdle() {
    return wrappedSession.isWriterIdle();
  }

  /**
   * Indicates whether the control socket for this session is secure, that is,
   * running over SSL/TLS
   *
   * @return true if the control socket is secured
   */
  public boolean isSecure() {
    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());
    }
  }

  /**
   * Returns the last reply that was sent to the client.
   *
   * @return the last reply that was sent to the client.
   */
  public FtpReply getLastReply() {
    return lastReply;
  }

  /**
   * @see IoSession#getWriteRequestQueue()
   */
  public WriteRequestQueue getWriteRequestQueue() {
    return wrappedSession.getWriteRequestQueue();
  }

  /**
   * @see IoSession#isReadSuspended()
   */
  public boolean isReadSuspended() {
    return wrappedSession.isReadSuspended();
  }

  /**
   * @see IoSession#isWriteSuspended()
   */
  public boolean isWriteSuspended() {
    return wrappedSession.isWriteSuspended();
  }

  /**
   * @see IoSession#setCurrentWriteRequest(WriteRequest)
   */
  public void setCurrentWriteRequest(WriteRequest currentWriteRequest) {
    wrappedSession.setCurrentWriteRequest(currentWriteRequest);
  }

  /**
   * @see IoSession#updateThroughput(long, boolean)
   */
  public void updateThroughput(long currentTime, boolean force) {
    wrappedSession.updateThroughput(currentTime, force);
  }
}
TOP

Related Classes of org.apache.ftpserver.impl.FtpIoSession

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.