class Nile::HttpServer
Attributes
bind_address[RW]
cb[RW]
port[RW]
Public Class Methods
new(address, port, cb)
click to toggle source
# File lib/nile/httpd.rb, line 11 def initialize (address, port, cb) @bind_address = address @port = port @cb = cb end
Public Instance Methods
read_request(sock)
click to toggle source
# File lib/nile/httpd.rb, line 54 def read_request sock data = sock.recv 1024 data =~ /Content-Length: (\d+)/ content_len = $1.to_i split_point = data.index "\r\n\r\n" while data.length - split_point - 4 < content_len data += sock.recv 1024 end headers = data[0..split_point-1].split("\r\n") first = headers[0] headers.delete_at(0) first =~ /(\w+)\ ([\w|\/|\?|\-|\=|\&]+)\ HTTP\// verb = $1 url = $2 headers_by_key = {} headers.each do |header| header =~ /^([\w|\-]+): (.*)/ headers_by_key[$1] = $2 end sock_domain, remote_port, remote_hostname, remote_ip = sock.peeraddr {:verb => verb, :url => url, :headers => headers_by_key, :body => data[split_point+4..data.length], :remote_ip => remote_ip, :remote_port => remote_port, :len => content_len, :overall_len => data.length} end
serve()
click to toggle source
# File lib/nile/httpd.rb, line 17 def serve webserver = TCPServer.new(@bind_address, @port) print "HttpServer running at http://#{@bind_address}:#{@port}\n" while (client = webserver.accept) Thread.start(client) do |client| start = Time.new req = read_request client http_messages = { 200 => 'OK', 204 => 'No Content', 301 => 'Moved Permanently', 302 => 'Found', 401 => 'Unauthorized', 403 => 'Forbidden', 404 => 'Not Found', 500 => 'Internal Server Error' } response = @cb.handle req, client finish = Time.new print "handling request #{req[:url]} from #{req[:remote_ip]}:#{req[:remote_port]} (#{req[:len]} bytes) --> replying #{response[0]} #{http_messages[response[0]]} (#{response[2].join("\n").length} bytes) in #{((finish - start) * 1000.0).round(2)} ms\n" client.write "HTTP/1.1 #{response[0]} #{http_messages[response[0]]}\r\n" response[1].each do |k,v| client.write "#{k}: #{v}\r\n" end client.write "\r\n" + response[2].join("\n") client.close end end end