Sha256: 4e6d192b072bb01dae1ddd09f952fd4dd731a9fccba01468eab40f7424f59877

Contents?: true

Size: 1.64 KB

Versions: 3

Compression:

Stored size: 1.64 KB

Contents

module Ftpd

  class CommandLoop

    extend Forwardable

    include Error

    def initialize(session)
      @session = session
    end

    def read_and_execute_commands
      catch :done do
        begin
          reply "220 #{server_name_and_version}"
          loop do
            begin
              s = get_command
              s = process_telnet_sequences(s)
              syntax_error unless s =~ /^(\w+)(?: (.*))?$/
              command, argument = $1.downcase, $2
              unless valid_command?(command)
                error "Syntax error, command unrecognized: #{s.chomp}", 500
              end
              command_sequence_checker.check command
              execute_command command, argument
            rescue FtpServerError => e
              reply e.message_with_code
            end
          end
        rescue Errno::ECONNRESET, Errno::EPIPE
        end
      end
    end

    private

    def_delegators :@session,
    :command_sequence_checker,
    :config,
    :execute_command,
    :reply,
    :server_name_and_version,
    :socket,
    :valid_command?

    def get_command
      s = gets_with_timeout(socket)
      throw :done if s.nil?
      s = s.chomp
      config.log.debug s
      s
    end
    
    def gets_with_timeout(socket)
      ready = IO.select([socket], nil, nil, config.session_timeout)
      timeout if ready.nil?
      ready[0].first.gets
    end

    def timeout
      reply '421 Control connection timed out.'
      throw :done
    end

    def process_telnet_sequences(s)
      telnet = Telnet.new(s)
      unless telnet.reply.empty?
        socket.write telnet.reply
      end
      telnet.plain
    end

  end

end

Version data entries

3 entries across 3 versions & 1 rubygems

Version Path
ftpd-1.0.1 lib/ftpd/command_loop.rb
ftpd-1.0.0 lib/ftpd/command_loop.rb
ftpd-0.17.0 lib/ftpd/command_loop.rb