class Sorta::Http::Worker

Constants

STATUS_CODES

Attributes

app[R]
pipe[R]

Public Class Methods

new(pipe, app, logger:) click to toggle source
# File lib/sorta/http/worker.rb, line 12
def initialize(pipe, app, logger:)
  @pipe = pipe
  @app = app

  Ractor.current[:logger] = logger
end

Public Instance Methods

logger() click to toggle source
# File lib/sorta/http/worker.rb, line 19
def logger
  Ractor.current[:logger]
end
run() click to toggle source
# File lib/sorta/http/worker.rb, line 23
def run
  loop do
    socket = pipe.take
    request = socket.gets

    if request.nil?
      socket.close
      next
    end

    env = new_env(*request.split)
    # logger.info "#{env['REQUEST_METHOD']} #{env['PATH_INFO']}"
    status, headers, body =
      begin
        app.call(env)
      rescue => e
        # TODO: сделать нормальную обработку ошибок
        logger.error "#{e.message}\n#{e.backtrace.join("\n")}"
        [500, {}, [e.message]]
      end

    socket.print "HTTP/1.1 #{status} #{STATUS_CODES[status]}\r\n"
    headers.each do |k, v|
      socket.print "#{k}: #{v}\r\n"
    end
    socket.print "Connection: close\r\n"
    socket.print "\r\n"

    if body.is_a?(String)
      socket.print body
    else
      body.each do |chunk|
        socket.print chunk
      end
    end
  rescue => e
    puts e
    logger.error "#{e.message}\n#{e.backtrace.join("\n")}"
  ensure
    socket.close
    next
  end
end

Private Instance Methods

new_env(method, location, *args) click to toggle source
# File lib/sorta/http/worker.rb, line 69
def new_env(method, location, *args)
  {
    'REQUEST_METHOD'   => method,
    'SCRIPT_NAME'      => '',
    'PATH_INFO'        => location,
    'QUERY_STRING'     => location.split('?').last,
    'SERVER_NAME'      => 'localhost',
    'SERVER_POST'      => '8080',
    'rack.version'     => ::Rack.version.split('.'),
    'rack.url_scheme'  => 'http',
    'rack.input'       => StringIO.new(''),
    'rack.errors'      => StringIO.new(''),
    'rack.multithread' => false,
    'rack.run_once'    => false
  }
end