1require 'drb/drb' 2require 'net/http' 3require 'uri' 4 5module DRb 6 module HTTP0 7 class StrStream 8 def initialize(str='') 9 @buf = str 10 end 11 attr_reader :buf 12 13 def read(n) 14 begin 15 return @buf[0,n] 16 ensure 17 @buf[0,n] = '' 18 end 19 end 20 21 def write(s) 22 @buf.concat s 23 end 24 end 25 26 def self.uri_option(uri, config) 27 return uri, nil 28 end 29 30 def self.open(uri, config) 31 unless /^http:/ =~ uri 32 raise(DRbBadScheme, uri) unless uri =~ /^http:/ 33 raise(DRbBadURI, 'can\'t parse uri:' + uri) 34 end 35 ClientSide.new(uri, config) 36 end 37 38 class ClientSide 39 def initialize(uri, config) 40 @uri = uri 41 @res = nil 42 @config = config 43 @msg = DRbMessage.new(config) 44 @proxy = ENV['HTTP_PROXY'] 45 end 46 47 def close; end 48 def alive?; false; end 49 50 def send_request(ref, msg_id, *arg, &b) 51 stream = StrStream.new 52 @msg.send_request(stream, ref, msg_id, *arg, &b) 53 @reply_stream = StrStream.new 54 post(@uri, stream.buf) 55 end 56 57 def recv_reply 58 @msg.recv_reply(@reply_stream) 59 end 60 61 def post(url, data) 62 it = URI.parse(url) 63 path = [(it.path=='' ? '/' : it.path), it.query].compact.join('?') 64 http = Net::HTTP.new(it.host, it.port) 65 sio = StrStream.new 66 http.post(path, data, {'Content-Type'=>'application/octetstream;'}) do |str| 67 sio.write(str) 68 if @config[:load_limit] < sio.buf.size 69 raise TypeError, 'too large packet' 70 end 71 end 72 @reply_stream = sio 73 end 74 end 75 end 76 DRbProtocol.add_protocol(HTTP0) 77end 78