Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Introductory Rack-compliant web server
require 'socket'
require 'rack'
require 'sinatra'
# Simple, rack-compliant web server
class MyServer
STATUS_CODES = {
200 => 'OK',
500 => 'Internal Server Error'
}
attr_reader :app, :tcp_server
def initialize(app)
@app = app
end
def start
@tcp_server = TCPServer.new('localhost', 8080)
puts 'Listening on 8080...'
loop do
socket = tcp_server.accept
request = socket.gets
response = ''
puts request
env = new_env(*request.split)
status, headers, body = app.call(env)
response << "HTTP/1.1 #{status} #{STATUS_CODES[status]}\r\n"
headers.each do |k, v|
response << "#{k}: #{v}\r\n"
end
response << "Connection: close\r\n"
socket.print response
socket.print "\r\n"
if body.is_a?(String)
socket.print body
else
body.each do |chunk|
socket.print chunk
end
end
socket.close
end
end
def new_env(method, location, *args)
{
'REQUEST_METHOD' => method,
'SCRIPT_NAME' => '',
'PATH_INFO' => location,
'QUERY_STRING' => location.split('?').last,
'SERVER_NAME' => 'localhost',
'SERVER_PORT' => '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
end
# Rack needs to know how to start the server
module Rack
module Handler
class MyServer
def self.run(app, options = {})
server = ::MyServer.new(app)
server.start
end
end
end
end
Rack::Handler.register('my_server', 'Rack::Handler::MyServer')
# Sinatra app
set :server, :my_server
get '/' do
'Hello world!'
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.