diff --git a/lib/net/http.rb b/lib/net/http.rb index 6a74ce28ce..a3d271c574 100644 --- a/lib/net/http.rb +++ b/lib/net/http.rb @@ -19,20 +19,20 @@ class HTTPBadResponse < HTTPError; end class HTTPSession < Session - Version = '1.1.1' + Version = '1.1.2' session_setvar :port, '80' - session_setvar :command_type, 'HTTPCommand' + session_setvar :command_type, 'Net::HTTPCommand' def get( path = '/', header = nil, ret = '' ) confirm_connection - @proto.get path, header, ret + @proto.get edit_path(path), header, ret end def head( path = '/', header = nil ) confirm_connection - @proto.head path, header + @proto.head edit_path(path), header end @@ -44,13 +44,35 @@ class HTTPSession < Session @socket.reopen end end + + def do_finish + unless @proto.error_occured or @socket.closed? then + head '/', { 'Connection' => 'Close' } + end + end + + + def edit_path( path ) + path + end + + class << self + def Proxy( addr, port ) + klass = super + klass.module_eval %- + def edit_path( path ) + 'http://' + address + (port == self.port ? '' : ":\#{port}") + path + end + - + klass + end + end end HTTP = HTTPSession - class HTTPCommand < Command HTTPVersion = '1.1' @@ -61,7 +83,7 @@ class HTTPCommand < Command @in_header = {} @in_header[ 'Host' ] = sock.addr #@in_header[ 'User-Agent' ] = "Ruby http version #{HTTPSession::Version}" - @in_header[ 'Connection' ] = 'Keep-Alive' + @in_header[ 'Connection' ] = 'keep-alive' @in_header[ 'Accept' ] = '*/*' super sock @@ -71,10 +93,9 @@ class HTTPCommand < Command attr :http_version def get( path, u_header = nil, ret = '' ) - @socket.writeline sprintf( 'GET %s HTTP/%s', path, HTTPVersion ) - write_header u_header - check_reply SuccessCode - header = read_header + header = get_response( + sprintf( 'GET %s HTTP/%s', path, HTTPVersion ), u_header ) + if chunked? header then clen = read_chunked_body( ret ) header.delete 'transfer-encoding' @@ -89,10 +110,8 @@ class HTTPCommand < Command def head( path, u_header = nil ) - @socket.writeline sprintf( 'HEAD %s HTTP/%s', path, HTTPVersion ) - write_header u_header - check_reply SuccessCode - header = read_header + header = get_response( + sprintf( 'HEAD %s HTTP/%s', path, HTTPVersion ), u_header ) @socket.close unless keep_alive? header header @@ -113,14 +132,25 @@ class HTTPCommand < Command def do_quit unless @socket.closed? then - head '/', { 'Connection' => 'Close' } + @socket.close end end + def get_response( line, u_header ) + @socket.writeline line + write_header u_header + rep = get_reply + header = read_header + reply_must rep, SuccessCode + + header + end def get_reply str = @socket.readline - /\AHTTP\/(\d+\.\d+)?\s+(\d\d\d)\s+(.*)\z/i === str + unless /\AHTTP\/(\d+\.\d+)?\s+(\d\d\d)\s*(.*)\z/i === str then + raise HTTPBadResponse, "wrong status line format: #{str}" + end @http_version = $1 status = $2 discrip = $3 diff --git a/lib/net/pop.rb b/lib/net/pop.rb index 7098bb9499..74c0e1815b 100644 --- a/lib/net/pop.rb +++ b/lib/net/pop.rb @@ -52,10 +52,10 @@ Net::Session class POP3Session < Session - Version = '1.1.1' + Version = '1.1.2' session_setvar :port, '110' - session_setvar :command_type, 'POP3Command' + session_setvar :command_type, 'Net::POP3Command' attr :mails @@ -189,7 +189,7 @@ Net::POP3Session class APOPSession < POP3Session - session_setvar :command_type, 'APOPCommand' + session_setvar :command_type, 'Net::APOPCommand' end diff --git a/lib/net/session.rb b/lib/net/session.rb index 951902a4cc..ec116322f6 100644 --- a/lib/net/session.rb +++ b/lib/net/session.rb @@ -1,6 +1,6 @@ =begin -= net/session.rb version 1.1.1 += net/session.rb version 1.1.2 written by Minero Aoki @@ -20,7 +20,7 @@ module Net == Net::Session -the abstruct class for Internet session +the abstruct class for Internet protocol session === Super Class @@ -30,7 +30,7 @@ Object : Version - The version of Session class. It is a string like "1.1.1". + The version of Session class. It is a string like "1.1.2". === Class Methods @@ -77,7 +77,7 @@ Object class Session - Version = '1.1.1' + Version = '1.1.2' class << self @@ -92,6 +92,41 @@ Object end end + def Proxy( p_addr, p_port ) + klass = Class.new( self ) + klass.module_eval %- + + def initialize( addr, port ) + @proxyaddr = '#{p_addr}' + @proxyport = '#{p_port}' + super @proxyaddr, @proxyport + @address = addr + @port = port + end + + def connect + tmpa, tmpp = @address, @port + @address, @port = @proxyaddr, @proxyport + super + @address, @port = tmpa, tmpp + end + private :connect + + attr :proxyaddr + attr :proxyport + - + def klass.proxy? + true + end + + klass + end + + def proxy? + false + end + + private def session_setvar( name, val ) @@ -108,17 +143,16 @@ Object # # sub-class requirements # - # class method command_type - # class method port + # session_setvar command_type + # session_setvar port # - # private method proto_initialize # private method do_start (optional) # private method do_finish (optional) # session_setvar :port, 'nil' session_setvar :command_type, 'nil' - session_setvar :socket_type, 'ProtocolSocket' + session_setvar :socket_type, 'Net::ProtocolSocket' def initialize( addr = 'localhost', port = nil ) @@ -233,9 +267,11 @@ Object def initialize( sock ) @socket = sock + @error_occured = false end attr :socket, true + attr :error_occured def quit if @socket and not @socket.closed? then @@ -245,19 +281,24 @@ Object @socket.close unless @socket.closed? @socket = nil end + @error_occured = false end end private def check_reply( *oks ) - rep = get_reply + reply_must( get_reply, *oks ) + end + + def reply_must( rep, *oks ) oks.each do |i| if i === rep then return rep end end + @error_occured = true rep.error! @socket.sending end @@ -271,6 +312,7 @@ Object class ProtoServerError < ProtocolError ; end class ProtoAuthError < ProtocolError ; end class ProtoCommandError < ProtocolError ; end + class ProtoRetryError < ProtocolError ; end class ReplyCode @@ -322,6 +364,10 @@ MES Error = ProtoServerError end + class RetryCode < ReplyCode + Error = ProtoRetryError + end + class UnknownCode < ReplyCode Error = ProtoUnknownError end @@ -618,18 +664,18 @@ Object def each_crlf_line( src ) buf = '' beg = 0 - pos = nil + pos = s = bin = nil - src.each do |b| - buf << b + src.each do |bin| + buf << bin beg = 0 - while (pos = buf.index(TERMEXP, beg)) and (pos < buf.size - 2) do - pos += $&.size - tmp = buf[ beg, pos - beg ] - tmp.chop! - yield tmp << CRLF - beg = pos + while pos = buf.index( TERMEXP, beg ) do + s = $&.size + break if pos + s == buf.size - 1 and buf[-1] == ?\r + + yield buf[ beg, pos - beg ] << CRLF + beg = pos + s end buf = buf[ beg, buf.size - beg ] if beg != 0 end @@ -638,11 +684,8 @@ Object beg = 0 while pos = buf.index( TERMEXP, beg ) do - pos += $&.size - tmp = buf[ beg, pos - beg ] - tmp.chop! - yield tmp << CRLF - beg = pos + yield buf[ beg, pos - beg ] << CRLF + beg = pos + $&.size end end diff --git a/lib/net/smtp.rb b/lib/net/smtp.rb index 8a16bc1724..b0f9b54b9a 100644 --- a/lib/net/smtp.rb +++ b/lib/net/smtp.rb @@ -58,10 +58,10 @@ Net::Session class SMTPSession < Session - Version = '1.1.1' + Version = '1.1.2' session_setvar :port, '25' - session_setvar :command_type, 'SMTPCommand' + session_setvar :command_type, 'Net::SMTPCommand' def sendmail( mailsrc, fromaddr, toaddrs )