Class: Rack::Handler::Serv

Inherits:
Object
  • Object
show all
Defined in:
lib/rack/handler/serv.rb

Constant Summary collapse

VERSION =
"0.1"

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(app, socket) ⇒ Serv

Returns a new instance of Serv.



18
19
20
21
22
23
24
25
26
27
28
29
30
# File 'lib/rack/handler/serv.rb', line 18

def initialize(app, socket)
  puts "incoming"
  @app, @socket, @done        = app, socket, false
  parser                      = Net::HTTP::RequestParser.new
  @body                       = ""
  parser.on_body              = proc { |b| @body << b }
  parser.on_message_complete  = self
  parser << (first_line = @socket.gets)
  @verb, @path, @http = first_line.split(' ')
  parser << @socket.gets until @done
rescue Net::HTTP::ParseError
  @socket.close
end

Class Method Details

.run(app, options = {}) ⇒ Object



10
11
12
13
14
15
16
# File 'lib/rack/handler/serv.rb', line 10

def self.run(app, options = {})
  Thread.abort_on_exception = true
  @@host, @@port = options[:Host] || '0.0.0.0', options[:Port] || 8080
  s = TCPServer.new(@@host, @@port)
  puts "listening #{options.inspect}"
  loop { Thread.new(s.accept) { |io| new app, io }}
end

Instance Method Details

#call(env) ⇒ Object



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
# File 'lib/rack/handler/serv.rb', line 32

def call(env)
  @done = true
  env.merge! \
    "REQUEST_METHOD"    => @verb,
    "rack.input"        => StringIO.new(@body),
    "rack.version"      => Rack::VERSION,
    "rack.errors"       => $stderr,
    "rack.multithread"  => true,
    "rack.multiprocess" => false,
    "rack.run_once"     => false,
    "rack.url_scheme"   => %w[yes on 1].include?(ENV["HTTPS"]) ? "https" : "http"
  env["SERVER_NAME"]  ||= env["HTTP_HOST"] || @@host
  env["SERVER_PORT"]  ||= @@port.to_s
  env["QUERY_STRING"] ||= ""
  status, headers, body = @app.call(env)
  @socket.puts "#{@http} #{status} #{Rack::Utils::HTTP_STATUS_CODES[status]}"
  @socket.puts headers.map { |k,v| "#{k}: #{v}" }
  @socket.puts ''
  body.each do |line|
    @socket.print line
    @socket.flush
  end
  body.close if body.respond_to? :close
  @socket.close
end