def receive(socket)
req_count = 0
loop do
begin
req_count += 1
request = Request.new
srv_family, srv_port, srv_host, srv_addr = socket.addr
request.set_server(srv_host, srv_addr, srv_port)
cli_family, cli_port, cli_host, cli_addr = socket.peeraddr
request.set_client(cli_host, cli_addr, cli_port)
unless (Wait.wait(socket, req_count > 1 ? @keep_alive : @timeout)) then
@logger.debug("close connection.")
break
end
request.parse(socket)
request.set_reader(socket)
if (request.version == 'HTTP/1.1') then
unless (request.has_header? 'Host') then
raise ParseError, 'required Host header.'
end
end
response = build_response
if (req_count >= @max_requests || request.conn_closed?) then
response.conn_close
writer = HTTPThroughWriter.new(socket, request)
else
writer = HTTPSpoolWriter.new(socket, request)
end
response.set_writer(writer)
@document.publish('', request, response, @logger)
writer.close
@access_log.write_log(request, response, Time.now)
rescue ParseError
if (! writer || ! writer.writing?) then
write_parse_error(socket, request, $!)
end
break
rescue HTTPError
if (! writer || ! writer.writing?) then
if (write_http_error(socket, request, $!, req_count)) then
break
else
next
end
else
break
end
rescue StandardError, ScriptError
@logger.warn("failed to receive request: #{$!.message} (#{$!.class}): #{$!.backtrace[0]}")
if (! writer || ! writer.writing?) then
write_server_error(socket, request, $!)
end
break
end
if (request.conn_closed? || response.conn_closed?) then
break
end
end
nil
end