-
-
Save matugm/efe0a1c4fc53310f7ac93dcd1f041f6c to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'socket' | |
class RequestParser | |
def parse(request) | |
method, path, version = request.lines[0].split | |
{ | |
path: path, | |
method: method, | |
headers: parse_headers(request) | |
} | |
end | |
def parse_headers(request) | |
headers = {} | |
request.lines[1..-1].each do |line| | |
return headers if line == "\r\n" | |
header, value = line.split | |
header = normalize(header) | |
headers[header] = value | |
end | |
end | |
def normalize(header) | |
header.gsub(":", "").downcase.to_sym | |
end | |
end | |
class Response | |
attr_reader :code | |
def initialize(code:, data: "") | |
@response = | |
"HTTP/1.1 #{code}\r\n" + | |
"Content-Length: #{data.size}\r\n" + | |
"\r\n" + | |
"#{data}\r\n" | |
@code = code | |
end | |
def send(client) | |
client.write(@response) | |
end | |
end | |
class ResponseBuilder | |
SERVER_ROOT = "/tmp/web-server/" | |
def prepare(request) | |
if request.fetch(:path) == "/" | |
respond_with(SERVER_ROOT + "index.html") | |
else | |
respond_with(SERVER_ROOT + request.fetch(:path)) | |
end | |
end | |
def respond_with(path) | |
if File.exists?(path) | |
send_ok_response(File.binread(path)) | |
else | |
send_file_not_found | |
end | |
end | |
def send_ok_response(data) | |
Response.new(code: 200, data: data) | |
end | |
def send_file_not_found | |
Response.new(code: 404) | |
end | |
end | |
server = TCPServer.new('localhost', 8080) | |
loop { | |
client = server.accept | |
request = client.readpartial(2048) | |
request = RequestParser.new.parse(request) | |
response = ResponseBuilder.new.prepare(request) | |
puts "#{client.peeraddr[3]} #{request.fetch(:path)} - #{response.code}" | |
response.send(client) | |
client.close | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
There are a few problems with this code:
if File.exists?(path)
== Xif File.exist?(path)
== 2714 FE0FAlso the
SERVER_ROOT = "/tmp/web-server/"
assumes the person knows to create a folder called/tmp/
and then/web-server/
. The simple path would be to just do this:SERVER_ROOT = ""
OR
SERVER_ROOT = "/"
The former works, but the latter won't the way you set up the code. Not a criticism just articulating that for people who see the the
/
and prefer it and don't realize there then needs to be other changes for that option to work.Ahh last thing. You infer the creation of an HTML file and that this will then render it, but it won't actually render it. It'll present the code, but not the rendering of that code. The
content_type
needs to be added to the the initialize method and the @ response:This was helpful and I learned a lot. The bug fixes were not a deterrent as it forced me to understand more and look up some things, which is why I sought out your article in the first place. Win win. Just adding this help in case someone is more junior and struggling more and how to proceed to solve the issues is less obvious to them. Blocking isn't good, struggling is good...at least I think that way.
Thanks again!