1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00
* 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
This commit is contained in:
aamine 2002-02-19 12:33:52 +00:00
parent c1bfef9494
commit 19f7f6ea12
6 changed files with 600 additions and 524 deletions

View file

@ -1,3 +1,63 @@
Tue Feb 19 21:43:32 2002 Minero Aoki <aamine@loveruby.net>
* 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.
Tue Feb 19 17:10:25 2002 Nobuyoshi Nakada <nobu.nakada@nifty.ne.jp>
* file.c (path_check_1): do not fail on world writable *parent*

View file

@ -79,7 +79,7 @@ Net::HTTP
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
}

View file

@ -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,51 +453,37 @@ 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
#
# connection
#
protocol_param :port, '80'
HTTPVersion = '1.1'
private
def do_start
conn_socket
#
# for backward compatibility
#
if RUBY_VERSION <= '1.6' then
@@newimpl = false
else
@@newimpl = true
end
def do_finish
disconn_socket
def HTTP.version_1_2
@@newimpl = true
end
def HTTP.version_1_1
@@newimpl = false
end
def HTTP.is_version_1_2?
@@newimpl
end
def HTTP.setimplversion( obj )
f = @@newimpl
obj.instance_eval { @newimpl = f }
end
private_class_method :setimplversion
#
# short cut methods
@ -520,32 +506,72 @@ module Net
end
#
# connection
#
protocol_param :default_port, '80'
protocol_param :socket_type, '::Net::InternetMessageIO'
class << HTTP
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
private
def do_start
conn_socket
end
def do_finish
disconn_socket
end
#
# proxy
#
public
class << self
def Proxy( p_addr, p_port = nil )
p_addr or return self
# no proxy
@is_proxy_class = false
@proxy_addr = nil
@proxy_port = nil
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
end
def HTTP.Proxy( p_addr, p_port = nil )
p_addr or return self
@is_proxy_class = false
@proxy_addr = nil
@proxy_port = nil
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
@ -604,40 +630,6 @@ module Net
end
#
# 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,16 +1336,34 @@ 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
#
# 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
SuccessCode === self or error!
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

View file

@ -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

View file

@ -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

View file

@ -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