1require 'webrick' 2require 'drb/drb' 3require 'drb/http0' 4require 'thread' 5 6module DRb 7 module HTTP0 8 9 def self.open_server(uri, config) 10 unless /^http:/ =~ uri 11 raise(DRbBadScheme, uri) unless uri =~ /^http:/ 12 raise(DRbBadURI, 'can\'t parse uri:' + uri) 13 end 14 Server.new(uri, config) 15 end 16 17 class Callback < WEBrick::HTTPServlet::AbstractServlet 18 def initialize(config, drb) 19 @config = config 20 @drb = drb 21 @queue = Queue.new 22 end 23 24 def do_POST(req, res) 25 @req = req 26 @res = res 27 @drb.push(self) 28 @res.body = @queue.pop 29 @res['content-type'] = 'application/octet-stream;' 30 end 31 32 def req_body 33 @req.body 34 end 35 36 def reply(body) 37 @queue.push(body) 38 end 39 40 def close 41 @queue.push('') 42 end 43 end 44 45 class Server 46 def initialize(uri, config) 47 @uri = uri 48 @config = config 49 @queue = Queue.new 50 setup_webrick(uri) 51 end 52 attr_reader :uri 53 54 def close 55 @server.shutdown if @server 56 @server = nil 57 end 58 59 def push(callback) 60 @queue.push(callback) 61 end 62 63 def accept 64 client = @queue.pop 65 ServerSide.new(client, @config) 66 end 67 68 def setup_webrick(uri) 69 logger = WEBrick::Log::new($stderr, WEBrick::Log::FATAL) 70 u = URI.parse(uri) 71 s = WEBrick::HTTPServer.new(:Port => u.port, 72 :AddressFamily => Socket::AF_INET, 73 :BindAddress => u.host, 74 :Logger => logger, 75 :ServerType => Thread) 76 s.mount(u.path, Callback, self) 77 @server = s 78 s.start 79 end 80 end 81 82 class ServerSide 83 def initialize(callback, config) 84 @callback = callback 85 @config = config 86 @msg = DRbMessage.new(@config) 87 @req_stream = StrStream.new(@callback.req_body) 88 end 89 90 def close 91 @callback.close if @callback 92 @callback = nil 93 end 94 95 def alive?; false; end 96 97 def recv_request 98 begin 99 @msg.recv_request(@req_stream) 100 rescue 101 close 102 raise $! 103 end 104 end 105 106 def send_reply(succ, result) 107 begin 108 return unless @callback 109 stream = StrStream.new 110 @msg.send_reply(stream, succ, result) 111 @callback.reply(stream.buf) 112 rescue 113 close 114 raise $! 115 end 116 end 117 end 118 end 119end 120