summaryrefslogtreecommitdiff
path: root/lib/net
diff options
context:
space:
mode:
authoraamine <aamine@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2002-02-19 12:33:52 +0000
committeraamine <aamine@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2002-02-19 12:33:52 +0000
commit19f7f6ea122df49a54c0fe40791feab1a53f6cd9 (patch)
tree89d99ac69ec027324c5844faaed269f95b8a5753 /lib/net
parentc1bfef949450c0ad55024670af2245a7833a59b4 (diff)
aamine
* lib/net/protocol.rb: rename Protocol.port to default_port. * lib/net/smtp.rb: ditto. * lib/net/pop.rb: ditto. * lib/net/http.rb: ditto. * lib/net/protocol.rb: rename BufferedSocket class to InternetMessageIO. * lib/net/smtp.rb: ditto. * lib/net/pop.rb: ditto. * lib/net/http.rb: ditto. * lib/net/protocol.rb: rename InternetMessageIO#write_pendstr to write_message. * lib/net/smtp.rb: ditto. * lib/net/protocol.rb: new method InternetMessageIO#through_message. * lib/net/smtp.rb: ditto. * lib/net/protocol.rb: rename InternetMessageIO#read_pendstr to read_message_to. * lib/net/pop.rb: ditto. * lib/net/protocol.rb: rename InternetMessageIO#read_pendlist to each_list_item * lib/net/pop.rb: ditto. * lib/net/protocol.rb: Now block size is 1024. * lib/net/smtp.rb: new methods SMTP#esmtp? and #esmtp=. * lib/net/http.rb: Using singleton method syntax instead of singleton class clause, to avoid behavior change of class variables in ruby 1.7. * lib/net/http.rb: HTTPResponse class does not inherit from Net::Response. * lib/net/http.rb: devide HTTP#connecting into {begin,end}_transport. * lib/net/http.rb: unused class Accumulator removed. * lib/net/http.rb: Net::HTTP reads response. not HTTPRequest. * lib/net/http.rb: proxy related class-instance-variables are not initialized correctly. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@2096 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'lib/net')
-rw-r--r--lib/net/http.rb617
-rw-r--r--lib/net/pop.rb79
-rw-r--r--lib/net/protocol.rb311
-rw-r--r--lib/net/smtp.rb49
4 files changed, 536 insertions, 520 deletions
diff --git a/lib/net/http.rb b/lib/net/http.rb
index e1bda208fa..536c924355 100644
--- a/lib/net/http.rb
+++ b/lib/net/http.rb
@@ -2,7 +2,7 @@
= net/http.rb
-Copyright (c) 1999-2001 Yukihiro Matsumoto
+Copyright (c) 1999-2002 Yukihiro Matsumoto
written & maintained by Minero Aoki <aamine@loveruby.net>
This file is derived from "http-access.rb".
@@ -97,7 +97,7 @@ URI class will be included in ruby standard library.
Net::HTTP.start( 'auth.some.domain' ) {|http|
response , = http.get( '/need-auth.cgi',
- 'Authentication' => ["#{account}:#{password}"].pack('m').strip )
+ 'Authorization' => 'Basic ' + ["#{account}:#{password}"].pack('m').strip )
print response.body
}
@@ -453,50 +453,36 @@ module Net
class HTTP < Protocol
- #
- # constructors
- #
-
- class << self
-
- def start( address, port = nil, p_addr = nil, p_port = nil, &block )
- new( address, port, p_addr, p_port ).start( &block )
- end
-
- alias newobj new
-
- def new( address, port = nil, p_addr = nil, p_port = nil )
- obj = Proxy(p_addr, p_port).newobj(address, port)
- setimplversion obj
- obj
- end
-
- end
-
- def initialize( addr, port = nil )
- super
- @curr_http_version = HTTPVersion
- @seems_1_0_server = false
- end
+ HTTPVersion = '1.1'
#
- # connection
+ # for backward compatibility
#
- protocol_param :port, '80'
+ if RUBY_VERSION <= '1.6' then
+ @@newimpl = false
+ else
+ @@newimpl = true
+ end
- HTTPVersion = '1.1'
+ def HTTP.version_1_2
+ @@newimpl = true
+ end
- private
+ def HTTP.version_1_1
+ @@newimpl = false
+ end
- def do_start
- conn_socket
+ def HTTP.is_version_1_2?
+ @@newimpl
end
- def do_finish
- disconn_socket
+ def HTTP.setimplversion( obj )
+ f = @@newimpl
+ obj.instance_eval { @newimpl = f }
end
+ private_class_method :setimplversion
#
@@ -521,31 +507,71 @@ module Net
#
- # proxy
+ # connection
#
- public
+ protocol_param :default_port, '80'
+ protocol_param :socket_type, '::Net::InternetMessageIO'
- class << self
- def Proxy( p_addr, p_port = nil )
- p_addr or return self
-
- p_port ||= port()
- mod = ProxyDelta
- proxyclass = Class.new(self)
- proxyclass.module_eval {
- include mod
- @is_proxy_class = true
- @proxy_address = p_addr
- @proxy_port = p_port
- }
- proxyclass
+ class << HTTP
+ def start( address, port = nil, p_addr = nil, p_port = nil, &block )
+ new( address, port, p_addr, p_port ).start( &block )
end
- @is_proxy_class = false
- @proxy_addr = nil
- @proxy_port = nil
+ alias newobj new
+ def new( address, port = nil, p_addr = nil, p_port = nil )
+ obj = Proxy(p_addr, p_port).newobj(address, port)
+ setimplversion obj
+ obj
+ end
+ end
+
+ def initialize( addr, port = nil )
+ super
+ @curr_http_version = HTTPVersion
+ @seems_1_0_server = false
+ end
+
+ private
+
+ def do_start
+ conn_socket
+ end
+
+ def do_finish
+ disconn_socket
+ end
+
+
+ #
+ # proxy
+ #
+
+ public
+
+ # no proxy
+ @is_proxy_class = false
+ @proxy_addr = nil
+ @proxy_port = nil
+
+ def HTTP.Proxy( p_addr, p_port = nil )
+ p_addr or return self
+
+ p_port ||= port()
+ delta = ProxyDelta
+ proxyclass = Class.new(self)
+ proxyclass.module_eval {
+ include delta
+ # with proxy
+ @is_proxy_class = true
+ @proxy_address = p_addr
+ @proxy_port = p_port
+ }
+ proxyclass
+ end
+
+ class << HTTP
def proxy_class?
@is_proxy_class
end
@@ -571,7 +597,7 @@ module Net
private
- # without proxy
+ # no proxy
def conn_address
address
@@ -605,40 +631,6 @@ module Net
#
- # for backward compatibility
- #
-
- if Version < '1.2.0' then ###noupdate
- @@newimpl = false
- else
- @@newimpl = true
- end
-
- class << self
-
- def version_1_2
- @@newimpl = true
- end
-
- def version_1_1
- @@newimpl = false
- end
-
- def is_version_1_2?
- @@newimpl
- end
-
- private
-
- def setimplversion( obj )
- f = @@newimpl
- obj.instance_eval { @newimpl = f }
- end
-
- end
-
-
- #
# http operations
#
@@ -682,6 +674,7 @@ module Net
res
end
+
def request_get( path, initheader = nil, &block )
request Get.new(path,initheader), &block
end
@@ -703,12 +696,14 @@ module Net
alias post2 request_post
alias put2 request_put
+
def send_request( name, path, body = nil, header = nil )
r = HTTPGenericRequest.new( name, (body ? true : false), true,
path, header )
request r, body
end
+
def request( req, body = nil, &block )
unless active? then
start {
@@ -717,17 +712,21 @@ module Net
}
end
- connecting( req ) {
- req.__send__( :exec,
- @socket, @curr_http_version, edit_path(req.path), body )
- yield req.response if block_given?
- }
- req.response
+ begin_transport req
+ req.__send__(:exec,
+ @socket, @curr_http_version, edit_path(req.path), body)
+ begin
+ res = HTTPResponse.read_new(@socket, req.response_body_permitted?)
+ end while HTTPContinue === res
+ yield res if block_given?
+ end_transport req, res
+
+ res
end
private
- def connecting( req )
+ def begin_transport( req )
if @socket.closed? then
reconn_socket
end
@@ -735,14 +734,15 @@ module Net
req['connection'] = 'close'
end
req['host'] = addr_port()
+ end
- yield req
- req.response.__send__ :terminate
- @curr_http_version = req.response.http_version
+ def end_transport( req, res )
+ res.__send__ :terminate
+ @curr_http_version = res.http_version
- if not req.response.body then
+ if not res.body then
@socket.close
- elsif keep_alive? req, req.response then
+ elsif keep_alive? req, res then
D 'Conn keep-alive'
if @socket.closed? then # (only) read stream had been closed
D 'Conn (but seems 1.0 server)'
@@ -788,71 +788,7 @@ module Net
end
-
-
- class Code
-
- def http_mkchild( bodyexist = nil )
- c = mkchild(nil)
- be = if bodyexist.nil? then @body_exist else bodyexist end
- c.instance_eval { @body_exist = be }
- c
- end
-
- def body_exist?
- @body_exist
- end
-
- end
-
- HTTPInformationCode = InformationCode.http_mkchild( false )
- HTTPSuccessCode = SuccessCode .http_mkchild( true )
- HTTPRedirectionCode = RetriableCode .http_mkchild( true )
- HTTPRetriableCode = HTTPRedirectionCode
- HTTPClientErrorCode = FatalErrorCode .http_mkchild( true )
- HTTPFatalErrorCode = HTTPClientErrorCode
- HTTPServerErrorCode = ServerErrorCode.http_mkchild( true )
-
-
- HTTPSwitchProtocol = HTTPInformationCode.http_mkchild
-
- HTTPOK = HTTPSuccessCode.http_mkchild
- HTTPCreated = HTTPSuccessCode.http_mkchild
- HTTPAccepted = HTTPSuccessCode.http_mkchild
- HTTPNonAuthoritativeInformation = HTTPSuccessCode.http_mkchild
- HTTPNoContent = HTTPSuccessCode.http_mkchild( false )
- HTTPResetContent = HTTPSuccessCode.http_mkchild( false )
- HTTPPartialContent = HTTPSuccessCode.http_mkchild
-
- HTTPMultipleChoice = HTTPRedirectionCode.http_mkchild
- HTTPMovedPermanently = HTTPRedirectionCode.http_mkchild
- HTTPMovedTemporarily = HTTPRedirectionCode.http_mkchild
- HTTPNotModified = HTTPRedirectionCode.http_mkchild( false )
- HTTPUseProxy = HTTPRedirectionCode.http_mkchild( false )
-
- HTTPBadRequest = HTTPClientErrorCode.http_mkchild
- HTTPUnauthorized = HTTPClientErrorCode.http_mkchild
- HTTPPaymentRequired = HTTPClientErrorCode.http_mkchild
- HTTPForbidden = HTTPClientErrorCode.http_mkchild
- HTTPNotFound = HTTPClientErrorCode.http_mkchild
- HTTPMethodNotAllowed = HTTPClientErrorCode.http_mkchild
- HTTPNotAcceptable = HTTPClientErrorCode.http_mkchild
- HTTPProxyAuthenticationRequired = HTTPClientErrorCode.http_mkchild
- HTTPRequestTimeOut = HTTPClientErrorCode.http_mkchild
- HTTPConflict = HTTPClientErrorCode.http_mkchild
- HTTPGone = HTTPClientErrorCode.http_mkchild
- HTTPLengthRequired = HTTPClientErrorCode.http_mkchild
- HTTPPreconditionFailed = HTTPClientErrorCode.http_mkchild
- HTTPRequestEntityTooLarge = HTTPClientErrorCode.http_mkchild
- HTTPRequestURITooLarge = HTTPClientErrorCode.http_mkchild
- HTTPUnsupportedMediaType = HTTPClientErrorCode.http_mkchild
-
- HTTPNotImplemented = HTTPServerErrorCode.http_mkchild
- HTTPBadGateway = HTTPServerErrorCode.http_mkchild
- HTTPServiceUnavailable = HTTPServerErrorCode.http_mkchild
- HTTPGatewayTimeOut = HTTPServerErrorCode.http_mkchild
- HTTPVersionNotSupported = HTTPServerErrorCode.http_mkchild
-
+ HTTPSession = HTTP
###
@@ -1013,7 +949,6 @@ module Net
@request_has_body = reqbody
@response_has_body = resbody
@path = path
- @response = nil
@header = tmp = {}
return unless initheader
@@ -1029,10 +964,9 @@ module Net
attr_reader :method
attr_reader :path
- attr_reader :response
def inspect
- "\#<#{type}>"
+ "\#<#{self.type} #{@method}>"
end
def request_body_permitted?
@@ -1045,24 +979,19 @@ module Net
alias body_exist? response_body_permitted?
-
- private
-
#
# write
#
- def exec( sock, ver, path, body, &block )
+ private
+
+ def exec( sock, ver, path, body )
if body then
check_body_premitted
- check_arg_b body, block
- sendreq_with_body sock, ver, path, body, &block
+ send_request_with_body sock, ver, path, body
else
- check_arg_n body
- sendreq_no_body sock, ver, path
+ request sock, ver, path
end
- @response = r = get_response(sock)
- r
end
def check_body_premitted
@@ -1070,21 +999,7 @@ module Net
raise ArgumentError, 'HTTP request body is not premitted'
end
- def check_arg_b( data, block )
- (data and block) and raise ArgumentError, 'both of data and block given'
- (data or block) or raise ArgumentError, 'str or block required'
- end
-
- def check_arg_n( data )
- data and raise ArgumentError, "data is not permitted for #{@method}"
- end
-
-
- def sendreq_no_body( sock, ver, path )
- request sock, ver, path
- end
-
- def sendreq_with_body( sock, ver, path, body )
+ def send_request_with_body( sock, ver, path, body )
if block_given? then
ac = Accumulator.new
yield ac # must be yield, DO NOT USE block.call
@@ -1111,17 +1026,6 @@ module Net
end
sock.writeline ''
end
-
- #
- # read
- #
-
- def get_response( sock )
- begin
- resp = HTTPResponse.new_from_socket(sock, response_body_permitted?)
- end while ContinueCode === resp
- resp
- end
end
@@ -1138,30 +1042,6 @@ module Net
end
- class Accumulator
-
- def initialize
- @buf = ''
- end
-
- def write( s )
- @buf.concat s
- end
-
- def <<( s )
- @buf.concat s
- self
- end
-
- def terminate
- ret = @buf
- @buf = nil
- ret
- end
-
- end
-
-
class HTTP
class Get < HTTPRequest
@@ -1196,20 +1076,164 @@ module Net
### response
###
- class HTTPResponse < Response
+ class HTTPResponse
+ # predefine HTTPResponse class to allow inheritance
- include HTTPHeader
+ def self.body_permitted?
+ self::HAS_BODY
+ end
+
+ def self.exception_type
+ self::EXCEPTION_TYPE
+ end
+ end
+
+
+ class HTTPUnknownResponse < HTTPResponse
+ HAS_BODY = true
+ EXCEPTION_TYPE = ProtocolError
+ end
+ class HTTPInformation < HTTPResponse
+ HAS_BODY = false
+ EXCEPTION_TYPE = ProtocolError
+ end
+ class HTTPSuccess < HTTPResponse
+ HAS_BODY = true
+ EXCEPTION_TYPE = ProtocolError
+ end
+ class HTTPRedirection < HTTPResponse
+ HAS_BODY = true
+ EXCEPTION_TYPE = ProtoRetriableError
+ end
+ class HTTPClientError < HTTPResponse
+ HAS_BODY = true
+ EXCEPTION_TYPE = ProtoFatalError
+ end
+ class HTTPServerError < HTTPResponse
+ HAS_BODY = true
+ EXCEPTION_TYPE = ProtoServerError
+ end
+ class HTTPContinue < HTTPInformation
+ HAS_BODY = false
+ end
+ class HTTPSwitchProtocol < HTTPInformation
+ HAS_BODY = false
+ end
+ class HTTPOK < HTTPSuccess
+ HAS_BODY = true
+ end
+ class HTTPCreated < HTTPSuccess
+ HAS_BODY = true
+ end
+ class HTTPAccepted < HTTPSuccess
+ HAS_BODY = true
+ end
+ class HTTPNonAuthoritativeInformation < HTTPSuccess
+ HAS_BODY = true
+ end
+ class HTTPNoContent < HTTPSuccess
+ HAS_BODY = false
+ end
+ class HTTPResetContent < HTTPSuccess
+ HAS_BODY = false
+ end
+ class HTTPPartialContent < HTTPSuccess
+ HAS_BODY = true
+ end
+ class HTTPMultipleChoice < HTTPRedirection
+ HAS_BODY = true
+ end
+ class HTTPMovedPermanently < HTTPRedirection
+ HAS_BODY = true
+ end
+ class HTTPMovedTemporarily < HTTPRedirection
+ HAS_BODY = true
+ end
+ class HTTPNotModified < HTTPRedirection
+ HAS_BODY = false
+ end
+ class HTTPUseProxy < HTTPRedirection
+ HAS_BODY = false
+ end
+ class HTTPBadRequest < HTTPClientError
+ HAS_BODY = true
+ end
+ class HTTPUnauthorized < HTTPClientError
+ HAS_BODY = true
+ end
+ class HTTPPaymentRequired < HTTPClientError
+ HAS_BODY = true
+ end
+ class HTTPForbidden < HTTPClientError
+ HAS_BODY = true
+ end
+ class HTTPNotFound < HTTPClientError
+ HAS_BODY = true
+ end
+ class HTTPMethodNotAllowed < HTTPClientError
+ HAS_BODY = true
+ end
+ class HTTPNotAcceptable < HTTPClientError
+ HAS_BODY = true
+ end
+ class HTTPProxyAuthenticationRequired < HTTPClientError
+ HAS_BODY = true
+ end
+ class HTTPRequestTimeOut < HTTPClientError
+ HAS_BODY = true
+ end
+ class HTTPConflict < HTTPClientError
+ HAS_BODY = true
+ end
+ class HTTPGone < HTTPClientError
+ HAS_BODY = true
+ end
+ class HTTPLengthRequired < HTTPClientError
+ HAS_BODY = true
+ end
+ class HTTPPreconditionFailed < HTTPClientError
+ HAS_BODY = true
+ end
+ class HTTPRequestEntityTooLarge < HTTPClientError
+ HAS_BODY = true
+ end
+ class HTTPRequestURITooLarge < HTTPClientError
+ HAS_BODY = true
+ end
+ class HTTPUnsupportedMediaType < HTTPClientError
+ HAS_BODY = true
+ end
+ class HTTPInternalServerError < HTTPServerError
+ HAS_BODY = true
+ end
+ class HTTPNotImplemented < HTTPServerError
+ HAS_BODY = true
+ end
+ class HTTPBadGateway < HTTPServerError
+ HAS_BODY = true
+ end
+ class HTTPServiceUnavailable < HTTPServerError
+ HAS_BODY = true
+ end
+ class HTTPGatewayTimeOut < HTTPServerError
+ HAS_BODY = true
+ end
+ class HTTPVersionNotSupported < HTTPServerError
+ HAS_BODY = true
+ end
+
+
+ class HTTPResponse # redefine
CODE_CLASS_TO_OBJ = {
- '1' => HTTPInformationCode,
- '2' => HTTPSuccessCode,
- '3' => HTTPRedirectionCode,
- '4' => HTTPClientErrorCode,
- '5' => HTTPServerErrorCode
+ '1' => HTTPInformation,
+ '2' => HTTPSuccess,
+ '3' => HTTPRedirection,
+ '4' => HTTPClientError,
+ '5' => HTTPServerError
}
-
CODE_TO_OBJ = {
- '100' => ContinueCode,
+ '100' => HTTPContinue,
'101' => HTTPSwitchProtocol,
'200' => HTTPOK,
@@ -1223,7 +1247,6 @@ module Net
'300' => HTTPMultipleChoice,
'301' => HTTPMovedPermanently,
'302' => HTTPMovedTemporarily,
- '303' => HTTPMovedPermanently,
'304' => HTTPNotModified,
'305' => HTTPUseProxy,
@@ -1238,13 +1261,13 @@ module Net
'408' => HTTPRequestTimeOut,
'409' => HTTPConflict,
'410' => HTTPGone,
- '411' => HTTPFatalErrorCode,
+ '411' => HTTPLengthRequired,
'412' => HTTPPreconditionFailed,
'413' => HTTPRequestEntityTooLarge,
'414' => HTTPRequestURITooLarge,
'415' => HTTPUnsupportedMediaType,
- '500' => HTTPFatalErrorCode,
+ '501' => HTTPInternalServerError,
'501' => HTTPNotImplemented,
'502' => HTTPBadGateway,
'503' => HTTPServiceUnavailable,
@@ -1255,50 +1278,57 @@ module Net
class << self
- def new_from_socket( sock, hasbody )
- resp = readnew( sock, hasbody )
+ def read_new( sock, hasbody )
+ httpv, code, msg = read_response_status(sock)
+ res = response_class(code).new( httpv, code, msg, sock, hasbody )
+ read_response_header sock, res
+ res
+ end
+
+ private
+
+ def read_response_status( sock )
+ str = sock.readline
+ m = /\AHTTP(?:\/(\d+\.\d+))?\s+(\d\d\d)\s*(.*)\z/in.match(str) or
+ raise HTTPBadResponse, "wrong status line: #{str.dump}"
+ return m.to_a[1,3]
+ end
+ def response_class( code )
+ CODE_TO_OBJ[code] or
+ CODE_CLASS_TO_OBJ[code[0,1]] or
+ HTTPUnknownResponse
+ end
+
+ def read_response_header( sock, res )
while true do
line = sock.readuntil( "\n", true ) # ignore EOF
line.sub!( /\s+\z/, '' ) # don't use chop!
break if line.empty?
- m = /\A([^:]+):\s*/.match( line )
- m or raise HTTPBadResponse, 'wrong header line format'
- nm = m[1]
+ m = /\A([^:]+):\s*/.match(line) or
+ raise HTTPBadResponse, 'wrong header line format'
+ name = m[1]
line = m.post_match
- if resp.key? nm then
- resp[nm] << ', ' << line
+ if res.key? name then
+ res[name] << ', ' << line
else
- resp[nm] = line
+ res[name] = line
end
end
-
- resp
- end
-
- private
-
- def readnew( sock, hasbody )
- str = sock.readline
- m = /\AHTTP(?:\/(\d+\.\d+))?\s+(\d\d\d)\s*(.*)\z/in.match( str )
- m or raise HTTPBadResponse, "wrong status line: #{str}"
- discard, httpv, stat, desc = *m.to_a
-
- new( stat, desc, sock, hasbody, httpv )
end
end
- def initialize( stat, msg, sock, be, hv )
- code = CODE_TO_OBJ[stat] ||
- CODE_CLASS_TO_OBJ[stat[0,1]] ||
- UnknownCode
- super code, stat, msg
- @socket = sock
- @body_exist = be
- @http_version = hv
+ include HTTPHeader
+
+ def initialize( httpv, code, msg, sock, hasbody )
+ @http_version = httpv
+ @code = code
+ @message = msg
+ @socket = sock
+ @body_exist = hasbody
@header = {}
@body = nil
@@ -1306,15 +1336,33 @@ module Net
end
attr_reader :http_version
+ attr_reader :code
+ attr_reader :message
+ alias msg message
def inspect
- "#<#{type} #{code}>"
+ "#<#{type} #{@code} readbody=#{@read}>"
end
- def value
- SuccessCode === self or error!
+ #
+ # response <-> exception relationship
+ #
+
+ def code_type
+ self.type
end
+ def error!
+ raise error_type.new(@code + ' ' + @message.dump, self)
+ end
+
+ def error_type
+ type::EXCEPTION_TYPE
+ end
+
+ def value
+ HTTPSuccess === self or error!
+ end
#
# header (for backward compatibility)
@@ -1340,8 +1388,7 @@ module Net
to = procdest(dest, block)
stream_check
-
- if @body_exist and code_type.body_exist? then
+ if @body_exist and self.type.body_permitted? then
read_body_0 to
@body = to
else
@@ -1393,7 +1440,7 @@ module Net
@socket.read 2 # \r\n
end
until @socket.readline.empty? do
- ;
+ # none
end
end
@@ -1402,11 +1449,10 @@ module Net
end
def procdest( dest, block )
- if dest and block then
- raise ArgumentError, 'both of arg and block are given for HTTP method'
- end
+ (dest and block) and
+ raise ArgumentError, 'both of arg and block are given for HTTP method'
if block then
- ReadAdapter.new block
+ ReadAdapter.new(block)
else
dest || ''
end
@@ -1415,17 +1461,22 @@ module Net
end
- # for backward compatibility
- HTTPSession = HTTP
+ # for backward compatibility
module NetPrivate
HTTPResponse = ::Net::HTTPResponse
HTTPGenericRequest = ::Net::HTTPGenericRequest
HTTPRequest = ::Net::HTTPRequest
- Accumulator = ::Net::Accumulator
HTTPHeader = ::Net::HTTPHeader
end
+ HTTPInformationCode = HTTPInformation
+ HTTPSuccessCode = HTTPSuccess
+ HTTPRedirectionCode = HTTPRedirection
+ HTTPRetriableCode = HTTPRedirection
+ HTTPClientErrorCode = HTTPClientError
+ HTTPFatalErrorCode = HTTPClientError
+ HTTPServerErrorCode = HTTPServerError
HTTPResponceReceiver = HTTPResponse
end # module Net
diff --git a/lib/net/pop.rb b/lib/net/pop.rb
index 1dbbc9aeb0..af32e8835a 100644
--- a/lib/net/pop.rb
+++ b/lib/net/pop.rb
@@ -2,7 +2,7 @@
= net/pop.rb
-Copyright (c) 1999-2001 Yukihiro Matsumoto
+Copyright (c) 1999-2002 Yukihiro Matsumoto
written & maintained by Minero Aoki <aamine@loveruby.net>
@@ -334,43 +334,41 @@ module Net
class POP3 < Protocol
- protocol_param :port, '110'
+ protocol_param :default_port, '110'
protocol_param :command_type, '::Net::POP3Command'
protocol_param :apop_command_type, '::Net::APOPCommand'
protocol_param :mail_type, '::Net::POPMail'
+ protocol_param :socket_type, '::Net::InternetMessageIO'
- class << self
- def APOP( bool )
- bool ? APOP : POP3
- end
+ def POP3.APOP( bool )
+ bool ? APOP : POP3
+ end
- def foreach( address, port = nil,
- account = nil, password = nil, &block )
- start( address, port, account, password ) do |pop|
+ def POP3.foreach( address, port = nil,
+ account = nil, password = nil, &block )
+ start( address, port, account, password ) {|pop|
pop.each_mail( &block )
- end
- end
+ }
+ end
- def delete_all( address, port = nil,
- account = nil, password = nil, &block )
- start( address, port, account, password ) do |pop|
+ def POP3.delete_all( address, port = nil,
+ account = nil, password = nil, &block )
+ start( address, port, account, password ) {|pop|
pop.delete_all( &block )
- end
- end
-
- def auth_only( address, port = nil,
- account = nil, password = nil )
- new( address, port ).auth_only account, password
- end
+ }
+ end
+ def POP3.auth_only( address, port = nil,
+ account = nil, password = nil )
+ new( address, port ).auth_only account, password
end
def auth_only( account, password )
- active? and raise IOError, 'opening already opened POP session'
+ raise IOError, 'opening already opened POP session' if active?
start( account, password ) {
- ;
+ # none
}
end
@@ -450,13 +448,19 @@ module Net
end
- POP = POP3
+ POP = POP3
+ POPSession = POP3
+ POP3Session = POP3
class APOP < POP3
- protocol_param :command_type, '::Net::APOPCommand'
+ def APOP.command_type
+ APOPCommand
+ end
end
+ APOPSession = APOP
+
class POPMail
@@ -476,16 +480,16 @@ module Net
def pop( dest = '', &block )
if block then
- dest = ReadAdapter.new( block )
+ dest = ReadAdapter.new(block)
end
- @command.retr( @num, dest )
+ @command.retr @num, dest
end
alias all pop
alias mail pop
def top( lines, dest = '' )
- @command.top( @num, lines, dest )
+ @command.top @num, lines, dest
end
def header( dest = '' )
@@ -533,7 +537,7 @@ module Net
arr = []
atomic {
getok 'LIST'
- @socket.read_pendlist do |line|
+ @socket.each_list_item do |line|
m = /\A(\d+)[ \t]+(\d+)/.match(line) or
raise BadResponse, "illegal response: #{line}"
arr[ m[1].to_i ] = m[2].to_i
@@ -551,15 +555,15 @@ module Net
def top( num, lines = 0, dest = '' )
atomic {
- getok sprintf( 'TOP %d %d', num, lines )
- @socket.read_pendstr dest
+ getok sprintf('TOP %d %d', num, lines)
+ @socket.read_message_to dest
}
end
- def retr( num, dest = '', &block )
+ def retr( num, dest = '' )
atomic {
getok sprintf('RETR %d', num)
- @socket.read_pendstr dest, &block
+ @socket.read_message_to dest
}
end
@@ -571,7 +575,7 @@ module Net
def uidl( num )
atomic {
- getok( sprintf('UIDL %d', num) ).msg.split(' ')[1]
+ getok( sprintf('UIDL %d', num) ).message.split(' ')[1]
}
end
@@ -624,11 +628,4 @@ module Net
end
-
- # for backward compatibility
-
- POPSession = POP3
- POP3Session = POP3
- APOPSession = APOP
-
end # module Net
diff --git a/lib/net/protocol.rb b/lib/net/protocol.rb
index 1cf1cfdb09..e0ad521f88 100644
--- a/lib/net/protocol.rb
+++ b/lib/net/protocol.rb
@@ -2,7 +2,7 @@
= net/protocol.rb
-Copyright (c) 1999-2001 Yukihiro Matsumoto
+Copyright (c) 1999-2002 Yukihiro Matsumoto
written & maintained by Minero Aoki <aamine@loveruby.net>
@@ -31,6 +31,10 @@ module Net
class << self
+ def port
+ default_port
+ end
+
private
def protocol_param( name, val )
@@ -47,9 +51,9 @@ module Net
#
# --- Configuration Staffs for Sub Classes ---
#
- # protocol_param port
- # protocol_param command_type
- # protocol_param socket_type (optional)
+ # class method default_port
+ # class method command_type
+ # class method socket_type
#
# private method do_start
# private method do_finish
@@ -58,27 +62,21 @@ module Net
# private method conn_port
#
- protocol_param :port, 'nil'
- protocol_param :command_type, 'nil'
- protocol_param :socket_type, '::Net::BufferedSocket'
-
def Protocol.start( address, port = nil, *args )
- instance = new( address, port )
+ instance = new(address, port)
if block_given? then
- ret = nil
- instance.start( *args ) { ret = yield(instance) }
- ret
+ instance.start(*args) { return yield(instance) }
else
- instance.start( *args )
+ instance.start(*args)
instance
end
end
def initialize( addr, port = nil )
@address = addr
- @port = port || type.port
+ @port = port || type.default_port
@command = nil
@socket = nil
@@ -236,7 +234,7 @@ module Net
@response = resp
end
- attr :response
+ attr_reader :response
alias data response
def inspect
@@ -289,64 +287,6 @@ module Net
UnknownCode = ReplyCode.mkchild( ProtoUnknownError )
-
- class WriteAdapter
-
- def initialize( sock, mid )
- @socket = sock
- @mid = mid
- end
-
- def inspect
- "#<#{type} socket=#{@socket.inspect}>"
- end
-
- def <<( str )
- @socket.__send__ @mid, str
- self
- end
-
- def write( str )
- @socket.__send__ @mid, str
- 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 )
- @block = block
- end
-
- def inspect
- "#<#{type}>"
- end
-
- def <<( str )
- call_block str, &@block if @block
- end
-
- private
-
- def call_block( str )
- yield str
- end
-
- end
-
-
-
class Command
def initialize( sock )
@@ -408,25 +348,10 @@ module Net
ret
end
- def begin_atomic
- ret = @atomic
- @atomic = true
- not ret
- end
-
- def end_atomic
- @atomic = false
- end
-
- alias critical atomic
- alias begin_critical begin_atomic
- alias end_critical end_atomic
-
end
-
- class BufferedSocket
+ class InternetMessageIO
class << self
alias open new
@@ -494,10 +419,6 @@ module Net
### READ
###
- #
- # basic reader
- #
-
public
def read( len, dest = '', ignore = false )
@@ -557,48 +478,9 @@ module Net
ret
end
- #
- # line oriented reader
- #
-
- public
-
- def read_pendstr( dest )
- D_off 'reading text...'
-
- rsize = 0
- while (str = readuntil("\r\n")) != ".\r\n" do
- rsize += str.size
- str.gsub!( /\A\./, '' )
- dest << str
- end
-
- D_on "read #{rsize} bytes"
- dest
- end
-
- # private use only (can not handle 'break')
- def read_pendlist
- # D_off 'reading list...'
-
- str = nil
- i = 0
- while (str = readuntil("\r\n")) != ".\r\n" do
- i += 1
- str.chop!
- yield str
- end
-
- # D_on "read #{i} items"
- end
-
- #
- # lib (reader)
- #
-
private
- BLOCK_SIZE = 1024 * 2
+ BLOCK_SIZE = 1024
def rbuf_fill
until IO.select [@socket], nil, nil, @read_timeout do
@@ -617,13 +499,39 @@ module Net
len
end
+ #
+ # message read
+ #
+
+ public
+
+ def read_message_to( dest )
+ D_off 'reading text...'
+
+ rsize = 0
+ while (str = readuntil("\r\n")) != ".\r\n" do
+ rsize += str.size
+ dest << str.sub(/\A\./, '')
+ end
+
+ D_on "read #{rsize} bytes"
+ dest
+ end
+
+ # private use only (cannot handle 'break')
+ def each_list_item
+ while (str = readuntil("\r\n")) != ".\r\n" do
+ yield str.chop
+ end
+ end
+
###
### WRITE
###
#
- # basic writer
+ # basic write
#
public
@@ -640,33 +548,45 @@ module Net
}
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
- end
- end
- }
+ private
+
+ def writing
+ @writtensize = 0
+ @debugout << '<- ' if @debugout
+ yield
+ @socket.flush
+ @debugout << "\n" if @debugout
+ @writtensize
+ end
+
+ def do_write( str )
+ @debugout << str.dump if @debugout
+ @writtensize += (n = @socket.write(str))
+ n
end
#
- # line oriented writer
+ # message write
#
public
- def write_pendstr( src, &block )
+ def write_message( src )
D_off "writing text from #{src.type}"
wsize = using_each_crlf_line {
- if block_given? then
- yield WriteAdapter.new(self, :wpend_in)
- else
- wpend_in src
- end
+ wpend_in src
+ }
+
+ D_on "wrote #{wsize} bytes text"
+ wsize
+ end
+
+ def through_message
+ D_off 'writing text from block'
+
+ wsize = using_each_crlf_line {
+ yield WriteAdapter.new(self, :wpend_in)
}
D_on "wrote #{wsize} bytes text"
@@ -758,27 +678,6 @@ module Net
end
end
- #
- # lib (writer)
- #
-
- private
-
- def writing
- @writtensize = 0
- @debugout << '<- ' if @debugout
- yield
- @socket.flush
- @debugout << "\n" if @debugout
- @writtensize
- end
-
- def do_write( str )
- @debugout << str.dump if @debugout
- @writtensize += (n = @socket.write(str))
- n
- end
-
###
### DEBUG
###
@@ -800,17 +699,75 @@ module Net
@debugout << msg
@debugout << "\n"
end
+
+ end
+
+
+ class WriteAdapter
+
+ def initialize( sock, mid )
+ @socket = sock
+ @mid = mid
+ end
+
+ def inspect
+ "#<#{type} socket=#{@socket.inspect}>"
+ end
+
+ def write( str )
+ @socket.__send__ @mid, str
+ end
+
+ alias print write
+
+ def <<( str )
+ write str
+ self
+ end
+
+ def puts( str = '' )
+ write str.sub(/\n?/, "\n")
+ end
+
+ def printf( *args )
+ write sprintf(*args)
+ end
+
+ end
+
+
+ class ReadAdapter
+
+ def initialize( block )
+ @block = block
+ end
+ def inspect
+ "#<#{type}>"
+ end
+
+ def <<( str )
+ call_block str, &@block if @block
+ end
+
+ private
+
+ def call_block( str )
+ yield str
+ end
+
end
# for backward compatibility
module NetPrivate
- Response = ::Net::Response
- WriteAdapter = ::Net::WriteAdapter
- ReadAdapter = ::Net::ReadAdapter
- Command = ::Net::Command
- Socket = ::Net::BufferedSocket
+ Response = ::Net::Response
+ Command = ::Net::Command
+ Socket = ::Net::InternetMessageIO
+ BufferedSocket = ::Net::InternetMessageIO
+ WriteAdapter = ::Net::WriteAdapter
+ ReadAdapter = ::Net::ReadAdapter
end
+ BufferedSocket = ::Net::InternetMessageIO
end # module Net
diff --git a/lib/net/smtp.rb b/lib/net/smtp.rb
index 363fc39088..8652f0f5d0 100644
--- a/lib/net/smtp.rb
+++ b/lib/net/smtp.rb
@@ -2,7 +2,7 @@
= net/smtp.rb
-Copyright (c) 1999-2001 Yukihiro Matsumoto
+Copyright (c) 1999-2002 Yukihiro Matsumoto
written & maintained by Minero Aoki <aamine@loveruby.net>
@@ -220,15 +220,25 @@ module Net
class SMTP < Protocol
- protocol_param :port, '25'
+ protocol_param :default_port, '25'
protocol_param :command_type, '::Net::SMTPCommand'
+ protocol_param :socket_type, '::Net::InternetMessageIO'
+
def initialize( addr, port = nil )
super
@esmtp = true
end
- attr :esmtp
+ def esmtp?
+ @esmtp
+ end
+
+ def esmtp=( bool )
+ @esmtp = bool
+ end
+
+ alias esmtp esmtp?
private
@@ -279,29 +289,28 @@ module Net
def send_mail( mailsrc, from_addr, *to_addrs )
do_ready from_addr, to_addrs.flatten
- command().write_mail mailsrc, nil
+ command().write_mail mailsrc
end
alias sendmail send_mail
def ready( from_addr, *to_addrs, &block )
do_ready from_addr, to_addrs.flatten
- command().write_mail nil, block
+ command().through_mail &block
end
private
def do_ready( from_addr, to_addrs )
- if to_addrs.empty? then
- raise ArgumentError, 'mail destination does not given'
- end
+ raise ArgumentError, 'mail destination does not given' if to_addrs.empty?
command().mailfrom from_addr
command().rcpt to_addrs
- command().data
end
end
+ SMTPSession = SMTP
+
class SMTPCommand < Command
@@ -366,15 +375,20 @@ module Net
end
end
- def data
- return unless begin_atomic
- getok 'DATA', ContinueCode
+ def write_mail( src )
+ atomic {
+ getok 'DATA', ContinueCode
+ @socket.write_message src
+ check_reply SuccessCode
+ }
end
- def write_mail( mailsrc, block )
- @socket.write_pendstr mailsrc, &block
- check_reply SuccessCode
- end_atomic
+ def through_mail( &block )
+ atomic {
+ getok 'DATA', ContinueCode
+ @socket.through_message(&block)
+ check_reply SuccessCode
+ }
end
def quit
@@ -421,9 +435,6 @@ module Net
# for backward compatibility
-
- SMTPSession = SMTP
-
module NetPrivate
SMTPCommand = ::Net::SMTPCommand
end