Skip to content

Instantly share code, notes, and snippets.

@vano468
Last active January 29, 2017 13:49
Show Gist options
  • Save vano468/cc52e6dab2748f1299ad507737142399 to your computer and use it in GitHub Desktop.
Save vano468/cc52e6dab2748f1299ad507737142399 to your computer and use it in GitHub Desktop.
Simplest implementation of rack compatible web server
require 'socket'
require 'http_tools'
require 'sinatra/base'
require 'sinatra/cookies'
class Server
DEFAULT_HOST = 'localhost'
DEFAULT_PORT = 3000
def self.run(app, **options)
new(app, options).listen
end
attr_reader :app, :server
def initialize(app, **options)
@app = app
@server = TCPServer.new(
options[:host] || DEFAULT_HOST,
options[:port] || DEFAULT_PORT)
end
def listen
loop do
Thread.new(server.accept) do |client|
handle_connection(client)
end
end
end
private
def handle_connection(client)
env = build_env(client)
status, headers, body = app.call(env)
client << HTTPTools::Builder.response(status, headers)
body.each { |row| client << row }
ensure
client.close
end
def build_env(client)
parser = HTTPTools::Parser.new
parser << client.gets until parser.finished?
parser.env
end
end
class Application < Sinatra::Application
helpers Sinatra::Cookies
get '/' do
"Hello, #{cookies[:name] || 'guest'}!"
end
get '/set' do
cookies[:name] = params[:name]
redirect to('/')
end
end
Server.run(Application.new)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment