diff options
author | aamine <aamine@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2001-12-30 19:18:45 +0000 |
---|---|---|
committer | aamine <aamine@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2001-12-30 19:18:45 +0000 |
commit | f3d9a0cc213f8b09155f063e057afb576178557e (patch) | |
tree | 92cf1665627f99c3fccdb3cf806f809348b3bd5c /lib/net/protocol.rb | |
parent | 653f326bb108108b82890e37400b4ca6e851e7ed (diff) |
aamine
* lib/net/protocol.rb: Protocol#start returns the return value of block.
* lib/net/protocol.rb: set timeout limit by default.
* lib/net/protocol.rb: new methods WriteAdapter#write, puts, print, printf.
* lib/net/http.rb: rename HTTP#get2 to request_get, post2 to request_post ...
* lib/net/smtp.rb: should not resolve HELO domain automatically.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@1951 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'lib/net/protocol.rb')
-rw-r--r-- | lib/net/protocol.rb | 414 |
1 files changed, 202 insertions, 212 deletions
diff --git a/lib/net/protocol.rb b/lib/net/protocol.rb index 4f95434f99..f21bdf72f1 100644 --- a/lib/net/protocol.rb +++ b/lib/net/protocol.rb @@ -28,27 +28,17 @@ module Net Version = '1.2.3' Revision = %q$Revision$.split(/\s+/)[1] - class << self - - def start( address, port = nil, *args ) - instance = new( address, port ) - if block_given? then - instance.start( *args ) { yield instance } - else - instance.start( *args ) - instance - end - end + class << self private def protocol_param( name, val ) - module_eval %- - def self.#{name.id2name} - #{val} - end - - + module_eval <<-End, __FILE__, __LINE__ + 1 + def self.#{name.id2name} + #{val} + end + End end end @@ -61,11 +51,11 @@ module Net # protocol_param command_type # protocol_param socket_type (optional) # - # private method do_start (optional) - # private method do_finish (optional) + # private method do_start + # private method do_finish # - # private method on_connect (optional) - # private method on_disconnect (optional) + # private method conn_address + # private method conn_port # protocol_param :port, 'nil' @@ -73,6 +63,19 @@ module Net protocol_param :socket_type, '::Net::BufferedSocket' + def Protocol.start( address, port = nil, *args ) + instance = new( address, port ) + + if block_given? then + ret = nil + instance.start( *args ) { ret = yield(instance) } + ret + else + instance.start( *args ) + instance + end + end + def initialize( addr, port = nil ) @address = addr @port = port || type.port @@ -82,8 +85,8 @@ module Net @active = false - @open_timeout = nil - @read_timeout = nil + @open_timeout = 30 + @read_timeout = 60 @dout = nil end @@ -112,90 +115,80 @@ module Net end # - # open session + # open # def start( *args ) - active? and raise IOError, 'protocol has been opened already' + @active and raise IOError, 'protocol has been opened already' if block_given? then begin - _start args - yield self + do_start( *args ) + @active = true + return yield(self) ensure - finish if active? + finish if @active end - else - _start args end + + do_start( *args ) + @active = true nil end private - def _start( args ) - connect - do_start( *args ) - @active = true - end + # abstract do_start() - def connect - conn_socket @address, @port + def conn_socket + @socket = type.socket_type.open( + conn_address(), conn_port(), + @open_timeout, @read_timeout, @dout ) on_connect - conn_command @socket end - def re_connect + alias conn_address address + alias conn_port port + + def reconn_socket @socket.reopen @open_timeout on_connect end - def conn_socket( addr, port ) - @socket = type.socket_type.open( - addr, port, @open_timeout, @read_timeout, @dout ) - end - - def conn_command( sock ) - @command = type.command_type.new( sock ) + def conn_command + @command = type.command_type.new(@socket) end def on_connect end - def do_start - end - # - # close session + # close # public def finish - active? or raise IOError, 'already closed protocol' - - do_finish if @command and not @command.critical? - disconnect + active? or raise IOError, 'closing already closed protocol' + do_finish @active = false nil end private - def do_finish - @command.quit - end + # abstract do_finish() - def disconnect + def disconn_command + @command.quit if @command and not @command.critical? @command = nil + end + + def disconn_socket if @socket and not @socket.closed? then @socket.close end @socket = nil - on_disconnect - end - - def on_disconnect end end @@ -220,7 +213,7 @@ module Net end def error! - raise @code_type.error_type.new( code + ' ' + Net.quote(msg), self ) + raise @code_type.error_type.new( code + ' ' + msg.dump, self ) end end @@ -305,20 +298,31 @@ module Net end def inspect - "#<#{type}>" + "#<#{type} socket=#{@socket.inspect}>" end - def write( str ) + def <<( str ) @socket.__send__ @mid, str + self end - def <<( str ) + def write( str ) @socket.__send__ @mid, str - self + end + + alias print write + + def puts( str = '' ) + @socket.__send__ @mid, str.sub(/\n?/, "\n") + end + + def printf( *args ) + @socket.__send__ @mid, sprintf(*args) end end + class ReadAdapter def initialize( block ) @@ -330,25 +334,13 @@ module Net end def <<( str ) - callblock( str, &@block ) if @block + call_block str, &@block if @block end private - def callblock( str ) - begin - user_break = true - yield str - user_break = false - rescue Exception - user_break = false - raise - ensure - if user_break then - @block = nil - return # stop breaking - end - end + def call_block( str ) + yield str end end @@ -360,7 +352,7 @@ module Net def initialize( sock ) @socket = sock @last_reply = nil - @critical = false + @atomic = false end attr_accessor :socket @@ -370,23 +362,20 @@ module Net "#<#{type}>" end - # abstract quit - + # abstract quit() private - # abstract get_reply() - def check_reply( *oks ) - @last_reply = get_reply - reply_must( @last_reply, *oks ) + @last_reply = get_reply() + reply_must @last_reply, *oks end + # abstract get_reply() + def reply_must( rep, *oks ) oks.each do |i| - if i === rep then - return rep - end + return rep if i === rep end rep.error! end @@ -396,7 +385,6 @@ module Net check_reply expect end - # # error handle # @@ -404,80 +392,77 @@ module Net public def critical? - @critical + @atomic end def error_ok - @critical = false + @atomic = false end - private - def critical - @critical = true + def atomic + @atomic = true ret = yield - @critical = false + @atomic = false ret end - def begin_critical - ret = @critical - @critical = true + def begin_atomic + ret = @atomic + @atomic = true not ret end - def end_critical - @critical = false + def end_atomic + @atomic = false end + alias critical atomic + alias begin_critical begin_atomic + alias end_critical end_atomic + end + class BufferedSocket - def initialize( addr, port, otime = nil, rtime = nil, dout = nil ) - @addr = addr - @port = port + class << self + alias open new + end + def initialize( addr, port, otime = nil, rtime = nil, dout = nil ) + @address = addr + @port = port @read_timeout = rtime - @debugout = dout - @socket = nil - @sending = '' - @rbuf = '' + @socket = nil + @rbuf = nil connect otime D 'opened' end - def connect( otime ) - D "opening connection to #{@addr}..." - timeout( otime ) { - @socket = TCPsocket.new( @addr, @port ) - } - end - private :connect - - attr :pipe, true + attr_reader :address + attr_reader :port - class << self - alias open new + def ip_address + @socket or return '' + @socket.addr[3] end - def inspect - "#<#{type} #{closed? ? 'closed' : 'opened'}>" - end + attr_reader :socket - def reopen( otime = nil ) - D 'reopening...' - close - connect otime - D 'reopened' + def connect( otime ) + D "opening connection to #{@address}..." + timeout( otime ) { + @socket = TCPsocket.new( @address, @port ) + } + @rbuf = '' end - - attr :socket, true + private :connect def close if @socket then @@ -490,48 +475,43 @@ module Net @rbuf = '' end - def closed? - not @socket + def reopen( otime = nil ) + D 'reopening...' + close + connect otime + D 'reopened' end - def address - @addr.dup + def closed? + not @socket end - alias addr address - - attr_reader :port - - def ip_address - @socket or return '' - @socket.addr[3] + def inspect + "#<#{type} #{closed? ? 'closed' : 'opened'}>" end - alias ipaddr ip_address - - attr_reader :sending - + ### + ### READ + ### # - # input + # basic reader # public - CRLF = "\r\n" - - def read( len, dest = '', igneof = false ) + def read( len, dest = '', ignore = false ) D_off "reading #{len} bytes..." rsize = 0 begin while rsize + @rbuf.size < len do - rsize += rbuf_moveto( dest, @rbuf.size ) + rsize += rbuf_moveto(dest, @rbuf.size) rbuf_fill end rbuf_moveto dest, len - rsize rescue EOFError - raise unless igneof + raise unless ignore end D_on "read #{len} bytes" @@ -544,7 +524,7 @@ module Net rsize = 0 begin while true do - rsize += rbuf_moveto( dest, @rbuf.size ) + rsize += rbuf_moveto(dest, @rbuf.size) rbuf_fill end rescue EOFError @@ -555,28 +535,34 @@ module Net dest end - def readuntil( target, igneof = false ) + def readuntil( target, ignore = false ) dest = '' begin while true do - idx = @rbuf.index( target ) + idx = @rbuf.index(target) break if idx rbuf_fill end rbuf_moveto dest, idx + target.size rescue EOFError - raise unless igneof + raise unless ignore rbuf_moveto dest, @rbuf.size end dest end def readline - ret = readuntil( "\n" ) + ret = readuntil("\n") ret.chop! ret end + # + # line oriented reader + # + + public + def read_pendstr( dest ) D_off 'reading text...' @@ -590,7 +576,7 @@ module Net D_on "read #{rsize} bytes" dest end - + # private use only (can not handle 'break') def read_pendlist # D_off 'reading list...' @@ -606,6 +592,10 @@ module Net # D_on "read #{i} items" end + # + # lib (reader) + # + private BLOCK_SIZE = 1024 * 2 @@ -623,50 +613,60 @@ module Net def rbuf_moveto( dest, len ) dest << (s = @rbuf.slice!(0, len)) - @debugout << %Q<read "#{Net.quote s}"\n> if @debugout + @debugout << %Q[-> #{s.dump}\n] if @debugout len end + ### + ### WRITE + ### + # - # output + # basic writer # public def write( str ) writing { - do_write str + do_write str } end def writeline( str ) writing { - do_write str + "\r\n" + do_write str + "\r\n" } end def write_bin( src, block ) writing { - if block then - block.call WriteAdapter.new(self, :do_write) - else - src.each do |bin| - do_write bin + if block then + block.call WriteAdapter.new(self, :do_write) + else + src.each do |bin| + do_write bin + end end - end } end - def write_pendstr( src, block ) + # + # line oriented writer + # + + public + + def write_pendstr( src, &block ) D_off "writing text from #{src.type}" wsize = using_each_crlf_line { - if block then - block.call WriteAdapter.new(self, :wpend_in) - else - wpend_in src - end + if block_given? then + yield WriteAdapter.new(self, :wpend_in) + else + wpend_in src + end } D_on "wrote #{wsize} bytes text" @@ -688,22 +688,22 @@ module Net def using_each_crlf_line writing { - @wbuf = '' + @wbuf = '' - yield + yield - if not @wbuf.empty? then # unterminated last line - if @wbuf[-1] == ?\r then - @wbuf.chop! + if not @wbuf.empty? then # unterminated last line + if @wbuf[-1] == ?\r then + @wbuf.chop! + end + @wbuf.concat "\r\n" + do_write @wbuf + elsif @writtensize == 0 then # empty src + do_write "\r\n" end - @wbuf.concat "\r\n" - do_write @wbuf - elsif @writtensize == 0 then # empty src - do_write "\r\n" - end - do_write ".\r\n" + do_write ".\r\n" - @wbuf = nil + @wbuf = nil } end @@ -758,34 +758,32 @@ module Net end end + # + # lib (writer) + # + + private def writing @writtensize = 0 - @sending = '' - + @debugout << '<- ' if @debugout yield - - if @debugout then - @debugout << 'write "' - @debugout << @sending - @debugout << "\"\n" - end @socket.flush + @debugout << "\n" if @debugout @writtensize end - def do_write( arg ) - if @debugout or @sending.size < 128 then - @sending << Net.quote( arg ) - else - @sending << '...' unless @sending[-1] == ?. - end - - s = @socket.write( arg ) - @writtensize += s - s + def do_write( str ) + @debugout << str.dump if @debugout + @writtensize += (n = @socket.write(str)) + n end + ### + ### DEBUG + ### + + private def D_off( msg ) D msg @@ -806,14 +804,6 @@ module Net end - def Net.quote( str ) - str = str.gsub( "\n", '\\n' ) - str.gsub!( "\r", '\\r' ) - str.gsub!( "\t", '\\t' ) - str - end - - # for backward compatibility module NetPrivate Response = ::Net::Response |