1 # A ruby binding to the ebb web server
2 # Copyright (c) 2007 Ry Dahl <ry.d4hl@gmail.com>
3 # This software is released under the "MIT License". See README file for details.
4 $: << File.expand_path(File.dirname(__FILE__))
13 'rack.input' => Input.new(self)
19 def initialize(client)
24 @client.read_input(len)
28 raise NotImplementedError
32 raise NotImplementedError
37 def self.run(app, options={})
38 # port must be an integer
39 server = self.new(app, options)
40 yield server if block_given?
44 def initialize(app, options={})
45 @host = options[:Host] || '0.0.0.0'
46 @port = (options[:Port] || 4001).to_i
51 # Called by the C library on each request.
52 # env is a hash containing all the variables of the request
53 # client is a TCPSocket
54 def process_client(client)
55 status, headers, body = @app.call(client.env)
57 client.write "HTTP/1.1 %d %s\r\n" % [status, HTTP_STATUS_CODES[status]]
59 if body.respond_to? :length and status != 304
60 client.write "Connection: close\r\n"
61 headers['Content-Length'] = body.length
64 headers.each { |k, v| client.write "#{k}: #{v}\r\n" }
66 if body.kind_of?(String)
68 elsif body.kind_of?(StringIO)
69 client.write body.string
71 # Not many apps use this yet so i'll hold off on streaming
72 # responses until the rest of ebb is more developed
73 # Yes, I know streaming responses are very cool.
74 raise NotImplementedError, "Unsupported body of type #{body.class}"
79 trap('INT') { puts "got INT"; stop }
80 trap('TERM') { puts "got TERM"; stop }
83 while process_connections
84 unless @waiting_clients.empty?
86 puts "#{@waiting_clients.length} waiting clients" if @waiting_clients.length > 1
88 client = @waiting_clients.shift
89 process_client(client)
98 101 => 'Switching Protocols',
102 203 => 'Non-Authoritative Information',
104 205 => 'Reset Content',
105 206 => 'Partial Content',
106 300 => 'Multiple Choices',
107 301 => 'Moved Permanently',
108 302 => 'Moved Temporarily',
110 304 => 'Not Modified',
112 400 => 'Bad Request',
113 401 => 'Unauthorized',
114 402 => 'Payment Required',
117 405 => 'Method Not Allowed',
118 406 => 'Not Acceptable',
119 407 => 'Proxy Authentication Required',
120 408 => 'Request Time-out',
123 411 => 'Length Required',
124 412 => 'Precondition Failed',
125 413 => 'Request Entity Too Large',
126 414 => 'Request-URI Too Large',
127 415 => 'Unsupported Media Type',
128 500 => 'Internal Server Error',
129 501 => 'Not Implemented',
130 502 => 'Bad Gateway',
131 503 => 'Service Unavailable',
132 504 => 'Gateway Time-out',
133 505 => 'HTTP Version not supported'