Last active
August 16, 2017 01:24
-
-
Save seki/09e3a096521f11d4b7ffba348482f777 to your computer and use it in GitHub Desktop.
http0serv.rb
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 'webrick' | |
require 'drb/drb' | |
require 'drb/http0' | |
require 'thread' | |
module DRb | |
module HTTP0 | |
def self.open_server(uri, config) | |
unless /^http:/ =~ uri | |
raise(DRbBadScheme, uri) unless uri =~ /^http:/ | |
raise(DRbBadURI, 'can\'t parse uri:' + uri) | |
end | |
Server.new(uri, config) | |
end | |
class Callback < WEBrick::HTTPServlet::AbstractServlet | |
def initialize(config, drb) | |
@config = config | |
@drb = drb | |
@queue = Thread::Queue.new | |
end | |
def do_POST(req, res) | |
@req = req | |
@res = res | |
@drb.push(self) | |
@res.body = @queue.pop | |
@res['content-type'] = 'application/octet-stream;' | |
end | |
def req_body | |
@req.body | |
end | |
def reply(body) | |
@queue.push(body) | |
end | |
def close | |
@queue.push('') | |
end | |
end | |
class Server | |
def initialize(uri, config) | |
@uri = uri | |
@config = config | |
@queue = Thread::Queue.new | |
setup_webrick(uri) | |
end | |
attr_reader :uri | |
def close | |
@server.shutdown if @server | |
@server = nil | |
end | |
def push(callback) | |
@queue.push(callback) | |
end | |
def accept | |
client = @queue.pop | |
ServerSide.new(client, @config, @uri) | |
end | |
def setup_webrick(uri) | |
logger = WEBrick::Log::new($stderr, WEBrick::Log::FATAL) | |
u = URI.parse(uri) | |
s = WEBrick::HTTPServer.new(:Port => u.port, | |
:AddressFamily => Socket::AF_INET, | |
:BindAddress => u.host, | |
:Logger => logger, | |
:ServerType => Thread) | |
s.mount(u.path, Callback, self) | |
@server = s | |
s.start | |
end | |
end | |
class ServerSide | |
def initialize(callback, config, uri) | |
@callback = callback | |
@config = config | |
@msg = DRbMessage.new(@config) | |
@req_stream = StrStream.new(@callback.req_body) | |
@uri = uri | |
end | |
attr_reader :uri | |
def close | |
@callback.close if @callback | |
@callback = nil | |
end | |
def alive?; false; end | |
def recv_request | |
begin | |
@msg.recv_request(@req_stream) | |
rescue | |
close | |
raise $! | |
end | |
end | |
def send_reply(succ, result) | |
begin | |
return unless @callback | |
stream = StrStream.new | |
@msg.send_reply(stream, succ, result) | |
@callback.reply(stream.buf) | |
rescue | |
close | |
raise $! | |
end | |
end | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment