You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

131 lines
2.1 KiB
Ruby

#!/usr/bin/ruby
# main.rb
require 'socket'
require 'fileutils'
require 'pathname'
require 'erb'
Root = '.'
Port = 8080
class HttpResponse
def self.process_erb(resp)
unless resp.ext === ".erb"
resp.data = resp.lazy.read
return
end
books = Dir["*"]
template = ERB.new resp.lazy.read
resp.data = template.result(binding)
return
end
def self.connection(str)
"Connection: #{str}"
end
def self.content_length(resp)
"Content-Length: #{resp.length}"
end
def self.content_type(resp)
ctype = {
".png" => "image/png",
".txt" => "text/plain",
".html" => "text/html",
".erb" => "text/html",
".css" => "text/css",
".mp3" => "audio/mpeg",
".ttf" => "font/ttf",
".mp4" => "video/mp4",
".pdf" => "application/pdf",
".webp" => "image/webp"
}
"Content-Type: #{ctype[resp.ext]}"
end
def self.build(resp)
resp.route
if resp.not_found?
return "HTTP/1.1 404 NOT FOUND\r\n"
end
process_erb(resp)
headers = [
content_length(resp),
content_type(resp),
].join("\r\n")
puts headers
return "HTTP/1.1 200 OK\r\n#{headers}\r\n\r\n#{resp.data}"
end
end
class HttpRouter
attr_reader :ext
attr_reader :length
attr_accessor :data
attr_reader :lazy
def initialize(path)
@path = Pathname.new(path)
@ext = File.extname(path)
@not_found = false
@data
end
def route
puts @path
case @path
when Pathname.new("/")
@path = Pathname.new("/index.erb")
return route
else
if File.exist? @path.basename
@lazy = File.open(@path.basename)
@length = File.size(@path.basename)
@ext = File.extname(@path)
else
@not_found = true
end
end
end
def not_found?
@not_found
end
end
class HttpServer
def initialize(port)
@server = TCPServer.new port
end
def accept_connection
while session = @server.accept
request = session.gets
verb, path, protocol = request.split(' ')
if protocol === 'HTTP/1.1'
resp = HttpRouter.new(path)
session.puts HttpResponse.build(resp)
else
session.puts 'Connection Refused'
end
session.close
end
end
end
server = HttpServer.new Port
server.accept_connection