class TinyServer

Constants

CONTENT_TYPE_MAPPING
DEFAULT_CONTENT_TYPE

Public Class Methods

new(port,root) click to toggle source
# File lib/ninja_server/tiny_server.rb, line 5
def initialize(port,root)
  @port = port
  @root = root
end

Public Instance Methods

shutdown() click to toggle source
# File lib/ninja_server/tiny_server.rb, line 52
def shutdown
  exit
end
start() click to toggle source
# File lib/ninja_server/tiny_server.rb, line 19
def start
  server = TCPServer.new("localhost", @port) # Server bound to port

  loop do
    client = server.accept    # Wait for a client to connect
    request = client.gets
    STDERR.puts request
    path = requested_file(request)

    path = File.join(path, 'index.html') if File.directory?(path)

    if File.exist?(path) && !File.directory?(path)
      File.open(path,"rb") do |file|
        client.print "HTTP/1.1 200 OK\r\n" + #status
                     "Content-Type: #{content_type(file)}\r\n" +
                     "Content-Length: #{file.size}\r\n" +
                     "Connection: close\r\n" +
                     "\r\n"
        IO.copy_stream(file,client)
      end
    else
      message = "File not found\n"
      client.print "HTTP/1.1 404 Not Found\r\n" +
                   "Content-Type: text/plain\r\n" +
                   "Content-Length: #{message.size}\r\n" +
                   "Connection: close\r\n" +
                   "\r\n"
      client.print message
    end
    client.close
  end
end

Private Instance Methods

content_type(path) click to toggle source

helper method to obtain content type from file extension

# File lib/ninja_server/tiny_server.rb, line 58
def content_type(path)
  ext = File.extname(path).split('.').last
  CONTENT_TYPE_MAPPING.fetch(ext, DEFAULT_CONTENT_TYPE)
end
requested_file(request_line) click to toggle source

helper method to generate path on server

# File lib/ninja_server/tiny_server.rb, line 64
def requested_file(request_line)
  request_uri = request_line.split(' ')[1]
  path = URI.unescape(URI(request_uri).path)

  clean = []

  parts = path.split('/')
  parts.each do |part|
    next if part.empty? || part == '.'
    part == '..' ? clean.pop : clean << part
  end

  File.join(@root, *clean)
end