-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathrequest.rb
59 lines (47 loc) · 1.4 KB
/
request.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
class Request
attr_reader :request_line, :method, :full_path, :protocol, :path, :query, :headers, :body
def initialize(client)
@client = client
end
def read
@request_line = read_request_line
puts "Request received: #{request_line.inspect}"
@method, @full_path, @protocol = request_line.split
@path, @query = full_path.split("?")
puts "Request method is #{method.inspect}, full path is #{full_path.inspect} (path: #{path.inspect}, query: #{query.inspect}) and protocol is #{protocol.inspect}."
@headers = read_headers
puts "Headers: #{headers}"
@body = read_body
puts "Body: #{body.inspect}"
self
rescue => error
puts "Error reading request: #{error}"
puts "Error's backtrace is:"
puts error.backtrace.join("\n")
self
end
def params
# easier: Hash[URI.decode_www_form(body)]
@body.split("&").each_with_object({}) do |string, hash|
k, v = string.split("=")
hash[k] = CGI.unescape(v)
end
end
private
def read_request_line
@client.gets.chomp("\r\n")
end
def read_headers
headers = {}
while (line = @client.gets)
break if line == "\r\n" # newline separates headers from body
header, content = line.split(": ", 2)
headers[header] = content.chomp("\r\n")
end
headers
end
def read_body
body_length = @headers["Content-Length"].to_i
@client.read(body_length)
end
end