Skip to content

Instantly share code, notes, and snippets.

@tmornini
Created April 3, 2014 00:47
Show Gist options
  • Save tmornini/9946289 to your computer and use it in GitHub Desktop.
Save tmornini/9946289 to your computer and use it in GitHub Desktop.
require 'uri'
require 'reel'
require 'subledger/json'
require 'subledger/uuid'
module Subledger
module Server
class Reel < Reel::Server::HTTP
def initialize host = '0.0.0.0', port = 3000
super host, port, &method(:on_connection)
end
private
def on_connection connection
connection.each_request do |request|
if request.websocket?
handle_websocket request.websocket
else
handle_request connection: connection,
request: request
end
end
end
def handle_websocket websocket
websocket << 'Hello everyone out there in WebSocket land!'
websocket.close
end
EXPECT = 'Expect'
EXPECT_CONTINUE = '100-continue'
EXPECT_CONTINUE_RESPONSE = "HTTP/1.1 100 Continue\r\n\r\n"
def handle_request args
request = args[:request]
if request.headers[EXPECT] == EXPECT_CONTINUE
args[:connection].socket << EXPECT_CONTINUE_RESPONSE
end
handle_dispatch args
rescue Exception => e
handle_exception args.merge! exception: e
end
def handle_dispatch args
connection = args[:connection]
request = args[:request]
response = Cell[:handler].handle request: request,
request_id: Uuid.as_string
connection.respond *response[:response]
end
def handle_exception args
exception = args[:exception]
if exception.respond_to? :status_code
respond_with_exception args
else
respond_with_five_hundred args
end
end
def respond_with_exception args
request = args[:request]
exception = args[:exception]
status_code = exception.status_code
reason = exception.message
decomposer = Decomposer.new uri_klass: URI
exception_args = decomposer.decompose request: request
verb = exception_args[:verb]
uri = exception_args[:path]
query = exception_args[:query_string]
body_hash = { status: status_code,
reason: reason,
verb: verb,
path: uri,
query: query }
body = Json.dump(body_hash) + "\n"
args[:connection].respond status_code,
{ },
body
end
def respond_with_five_hundred args
exception = args[:exception]
backtrace = exception.backtrace.join "\n"
message = "#{exception.class}\n#{exception.message}\n#{backtrace}"
Logger.new.fatal code: self.class.name,
entry: message
args[:connection].respond :internal_server_error,
{ },
["500 Internal Server Error\n"]
end
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment