Working with TCP Sockets 読書メモ 第15章 ネットワークアーキテクチャパターン

Working with TCP Sockets 読書メモ 目次

ネットワークアーキテクチャパターン

  • パーツをどのように構成してアプリケーションを作るかを学ぼう
  • FTPサーバの実装例
module FTP
  class CommandHandler
    CRLF = "\r\n"

    attr_reader :connection

    def initialize(connection)
      @connection = connection
    end

    def pwd
      @pwd || Dir.pwd
    end

    def handle(data)
      cmd     = data[0..3].strip.upcase
      options = data[4..-1].strip

      case cmd
      when 'USER'
        "230 Logged in anonymously"
      when 'SYST'
        "215 UNIX Wordking With FTP"
      when 'CWD'
        if File.directory?(options)
          @pwd = options
          "250 directory changed to #{pwd}"
        else
          "550 directory not found"
        end
      when 'PWD'
        "257\"#{pwd}\" is the current directory"
      when 'PORT'
        parts      = options.split(',')
        ip_address = parts[0..3].join('.')
        port       = Integer(parts[4]) * 256 + Integer(parts[5])

        @data_socket = TCPSocket.new(ip_address, port)
        "200 Active connection established(#{port}"
      when 'RETR'
        file = File.open(File.join(pwd, options), 'r')
        connection.respond "125 Data transfer starting #{file.size} bytes"

        bytes = IO.copy_stream(file, @data_socket)
        @data_socket.close

        "226 Closing data connection, sent #{bytes} bytes"

      when 'LIST'
        connection.respond "125 Opening data connection for file list"

        result = Dir.entries(pwd).join(CRLF)
        @data_socket.write(result)
        @data_socket.close

        "226 Closing data connection, sent #{result.size} bytes"

      when 'QUIT'
        "221 Ciao"
      else
        "502 Don't know how to respoind to #{cmd}"
      end
    end
  end
end

コメントを残す

コメントを残す