lib/ruby_wolf/handler.rb in ruby_wolf-0.3.3 vs lib/ruby_wolf/handler.rb in ruby_wolf-0.4.0
- old
+ new
@@ -1,99 +1,104 @@
require 'http/parser'
module RubyWolf
class Handler
+ attr_reader :app, :env, :connection, :response
- attr_reader :app, :env, :connection, :response, :callback, :body, :headers, :status
-
def initialize(app, connection, &callback)
@app = app
- @connection = connection
- @callback = callback
@env = {}
+ @connection = connection
@response = ''
+
+ @callback = callback
end
def process
prepare_rack_env
- generate_response
- callback.call(response) if callback
- response
+ log_request
+ process_request
+ compose_response
+ log_response
+
+ @callback.call(response) if @callback
+ @response
end
private
def prepare_rack_env
- @env = ENV.to_h.merge(
+ @connection.headers.each do |key, value|
+ @env[rack_key(key)] = value
+ end
+
+ @env = @env.merge(
'rack.version' => ::Rack::VERSION,
'rack.errors' => STDERR,
'rack.multithread' => false,
'rack.multiprocess' => true,
'rack.runonce' => true,
'rack.url_scheme' => ENV['HTTPS'] ? 'https' : 'http',
- 'REQUEST_METHOD' => connection.method,
- 'REQUEST_PATH' => connection.path,
- 'PATH_INFO' => connection.path,
- 'QUERY_STRING' => connection.query,
+ 'REQUEST_METHOD' => @connection.method,
+ 'REQUEST_PATH' => @connection.path,
+ 'PATH_INFO' => @connection.path,
+ 'QUERY_STRING' => @connection.query,
'SERVER_PROTOCOL' => 'HTTP/1.1',
'SERVER_NAME' => 'Ruby Wolf',
'HTTP_VERSION' => 'HTTP/1.1',
- 'HTTP_HOST' => connection.headers['Host'],
- 'HTTP_USER_AGENT' => connection.headers['User-Agent'],
- 'HTTP_ACCEPT' => connection.headers['Accept'],
- 'CONTENT_LENGTH' => connection.headers['Content-Length'],
- 'CONTENT_TYPE' => connection.headers['Content-Type'],
- 'rack.input' => StringIO.new(connection.read_chunk)
+ 'rack.input' => StringIO.new(@connection.read_chunk)
)
- log_request
end
- def generate_response
- @status, @headers, @body = app.call(env)
- compose_response
- log_response
+ def process_request
+ @status, @headers, @body = @app.call(env)
+ rescue => e
+ message = "Error while processing the request: #{e.message}\n#{e.backtrace.join("\n")}"
+ @status = 500
+ @body = [message]
+ @headers = [
+ ['Content-Length', message.bytesize],
+ ['Content-Type', 'text/plain; charset=utf-8']
+ ]
+ RubyWolf.logger.error(message)
end
def compose_response
- @response += "HTTP/1.1 #{status} #{RubyWolf::CRLF}"
- headers.each do |key, value|
+ @response += "HTTP/1.1 #{@status} #{RubyWolf::CRLF}"
+ @headers.each do |key, value|
@response += "#{key}: #{value}#{RubyWolf::CRLF}"
end
@response += RubyWolf::CRLF
- body.each do |part|
+ @body.each do |part|
@response += part
end
ensure
- body.close if body.respond_to? :close
+ @body.close if @body.respond_to? :close
end
private
def log_request
- RubyWolf.logger.info(
- [
- 'HTTP/1.1',
- connection.method,
- request_path
- ].join(' ')
- )
+ RubyWolf.logger.info("HTTP/1.1 #{@connection.method} #{request_path}")
end
def log_response
- RubyWolf.logger.info(
- "Response HTTP/1.1 #{status}"
- )
+ RubyWolf.logger.info("Response HTTP/1.1 #{@status}")
end
def request_path
- if connection.query
- "#{connection.path}?#{connection.query}"
+ if @connection.query
+ "#{@connection.path}?#{@connection.query}"
else
- connection.path
+ @connection.path
end
+ end
+
+ def rack_key(key)
+ "HTTP_#{key.upcase.gsub(/[^0-9A-Z]/, '_')}"
end
end
end