Created
April 3, 2014 00:47
-
-
Save tmornini/9946289 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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