mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
o protocol.rb: version 1.1.9
o smtp.rb: arguments discription of do_ready was wrongly void git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@654 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
688169fd83
commit
d8d148d816
4 changed files with 285 additions and 347 deletions
359
lib/net/http.rb
359
lib/net/http.rb
|
@ -38,11 +38,14 @@ class HTTPBadResponse < HTTPError; end
|
|||
|
||||
== Methods
|
||||
|
||||
: get( path, header = nil, ret = '' )
|
||||
: get( path, header = nil, dest = '' )
|
||||
: get( path, header = nil ) {|str| .... }
|
||||
get data from "path" on connecting host.
|
||||
"header" is a Hash like { 'Accept' => '*/*', ... }.
|
||||
The data will be written to "ret" using "<<" method.
|
||||
This method returns response header (Hash) and "ret".
|
||||
"header" must be a Hash like { 'Accept' => '*/*', ... }.
|
||||
Data is written to "dest" by using "<<" method.
|
||||
This method returns response header (Hash) and "dest".
|
||||
|
||||
If called as iterator, give a part String of entity body.
|
||||
|
||||
: head( path, header = nil )
|
||||
get only header from "path" on connecting host.
|
||||
|
@ -53,6 +56,30 @@ class HTTPBadResponse < HTTPError; end
|
|||
'content-type' => 'Content-Type: text/html',
|
||||
... }
|
||||
|
||||
: post( path, data, header = nil, dest = '' )
|
||||
: post( path, data, header = nil ) {|str| .... }
|
||||
post "data"(must be String now) to "path" (and get entity body).
|
||||
"header" must be a Hash like { 'Accept' => '*/*', ... }.
|
||||
Data is written to "dest" by using "<<" method.
|
||||
This method returns response header (Hash) and "dest".
|
||||
|
||||
If called as iterator, give a part String of entity body.
|
||||
|
||||
ATTENTION: entity body could be empty
|
||||
|
||||
: get2( path, header = nil )
|
||||
send GET request for "path".
|
||||
"header" must be a Hash like { 'Accept' => '*/*', ... }.
|
||||
This method returns response header (Hash).
|
||||
|
||||
: get_body( dest = '' )
|
||||
: get_body {|str| .... }
|
||||
gets entity body of forwarded 'get2' or 'post2' methods.
|
||||
Data is written in "dest" by using "<<" method.
|
||||
This method returns "dest".
|
||||
|
||||
If called as iterator, give a part String of entity body.
|
||||
|
||||
=end
|
||||
|
||||
class HTTP < Protocol
|
||||
|
@ -61,19 +88,71 @@ class HTTPBadResponse < HTTPError; end
|
|||
protocol_param :command_type, '::Net::HTTPCommand'
|
||||
|
||||
|
||||
def get( path, u_header = nil, ret = '' )
|
||||
def get( path, u_header = nil, dest = nil, &block )
|
||||
u_header ||= {}
|
||||
header = connecting( u_header ) {
|
||||
@command.get ret, edit_path(path), u_header
|
||||
if block then
|
||||
dest = ReadAdapter.new( block )
|
||||
ret = nil
|
||||
else
|
||||
dest = ret = ''
|
||||
end
|
||||
resp = nil
|
||||
connecting( u_header ) {
|
||||
@command.get edit_path(path), u_header
|
||||
resp = @command.get_response
|
||||
@command.try_get_body( resp, dest )
|
||||
}
|
||||
|
||||
return header, ret
|
||||
return resp['http-header'], ret
|
||||
end
|
||||
|
||||
def head( path, u_header = nil )
|
||||
def get2( path, u_header = {} )
|
||||
only_header( :get, path, u_header )
|
||||
end
|
||||
|
||||
def get_body( dest = '', &block )
|
||||
if block then
|
||||
dest = ReadAdapter.new( block )
|
||||
end
|
||||
@command.try_get_body @response, dest
|
||||
ensure_termination @u_header
|
||||
|
||||
dest
|
||||
end
|
||||
|
||||
def head( path, u_header = {} )
|
||||
ret = only_header( :head, path, u_header )['http-header']
|
||||
ensure_termination u_header
|
||||
ret
|
||||
end
|
||||
|
||||
def post( path, data, u_header = nil, dest = nil, &block )
|
||||
u_header ||= {}
|
||||
header = connecting( u_header ) {
|
||||
@command.head edit_path(path), u_header
|
||||
if block then
|
||||
dest = ReadAdapter.new( block )
|
||||
ret = nil
|
||||
else
|
||||
dest = ret = ''
|
||||
end
|
||||
resp = nil
|
||||
connecting( u_header, true ) {
|
||||
@command.post path, u_header, data
|
||||
resp = @command.get_response
|
||||
@command.try_get_body( resp, dest )
|
||||
}
|
||||
|
||||
return resp['http-header'], ret
|
||||
end
|
||||
|
||||
def post2( path, data, u_header = {} )
|
||||
only_header :post, path, u_header, data
|
||||
end
|
||||
|
||||
# not tested because I could not setup apache (__;;;
|
||||
def put( path, src = nil, u_header = {}, &block )
|
||||
u_header ||= u_header
|
||||
connecting( u_header, true ) {
|
||||
@command.put path, u_header, src, dest
|
||||
}
|
||||
|
||||
header
|
||||
|
@ -83,30 +162,51 @@ class HTTPBadResponse < HTTPError; end
|
|||
private
|
||||
|
||||
|
||||
def only_header( mid, path, u_header, data = nil )
|
||||
@u_header = u_header ? procheader(u_header) : {}
|
||||
@response = nil
|
||||
ensure_connection @u_header
|
||||
if data then
|
||||
@command.send mid, edit_path(path), @u_header, data
|
||||
else
|
||||
@command.send mid, edit_path(path), @u_header
|
||||
end
|
||||
@response = @command.get_response
|
||||
@response['http-header']
|
||||
end
|
||||
|
||||
|
||||
# called when connecting
|
||||
def do_finish
|
||||
unless @socket.closed? then
|
||||
@command.head '/', { 'Connection' => 'Close' }
|
||||
begin
|
||||
@command.head '/', { 'Connection' => 'Close' }
|
||||
rescue EOFError
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def connecting( u_header )
|
||||
def connecting( u_header, putp = false )
|
||||
u_header = procheader( u_header )
|
||||
ensure_connection u_header
|
||||
yield
|
||||
ensure_termination u_header
|
||||
end
|
||||
|
||||
def ensure_connection( u_header )
|
||||
if not @socket then
|
||||
u_header['Connection'] = 'Close'
|
||||
start
|
||||
elsif @socket.closed? then
|
||||
@socket.reopen
|
||||
end
|
||||
end
|
||||
|
||||
header = yield
|
||||
|
||||
def ensure_termination( u_header )
|
||||
unless keep_alive? u_header then
|
||||
@socket.close
|
||||
end
|
||||
|
||||
header
|
||||
@u_header = @response = nil
|
||||
end
|
||||
|
||||
def keep_alive?( header )
|
||||
|
@ -155,6 +255,20 @@ class HTTPBadResponse < HTTPError; end
|
|||
HTTPSession = HTTP
|
||||
|
||||
|
||||
class HTTPSuccessCode < SuccessCode; end
|
||||
class HTTPCreatedCode < SuccessCode; end
|
||||
class HTTPAcceptedCode < SuccessCode; end
|
||||
class HTTPNoContentCode < SuccessCode; end
|
||||
class HTTPResetContentCode < SuccessCode; end
|
||||
class HTTPPartialContentCode < SuccessCode; end
|
||||
|
||||
class HTTPMultipleChoiceCode < RetryCode; end
|
||||
class HTTPMovedPermanentlyCode < RetryCode; end
|
||||
class HTTPMovedTemporarilyCode < RetryCode; end
|
||||
class HTTPNotModifiedCode < RetryCode; end
|
||||
class HTTPUseProxyCode < RetryCode; end
|
||||
|
||||
|
||||
class HTTPCommand < Command
|
||||
|
||||
HTTPVersion = '1.1'
|
||||
|
@ -173,40 +287,25 @@ class HTTPBadResponse < HTTPError; end
|
|||
|
||||
attr_reader :http_version
|
||||
|
||||
def get( ret, path, u_header = nil )
|
||||
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'
|
||||
header[ 'content-length' ] = "Content-Length: #{clen}"
|
||||
else
|
||||
if clen = content_length( header ) then
|
||||
@socket.read clen, ret
|
||||
else
|
||||
@socket.read_all ret
|
||||
end
|
||||
end
|
||||
|
||||
header
|
||||
def get( path, u_header )
|
||||
request sprintf('GET %s HTTP/%s', path, HTTPVersion), u_header
|
||||
end
|
||||
|
||||
def head( path, u_header )
|
||||
request sprintf('HEAD %s HTTP/%s', path, HTTPVersion), u_header
|
||||
end
|
||||
|
||||
|
||||
def head( path, u_header = nil )
|
||||
get_response sprintf( 'HEAD %s HTTP/%s', path, HTTPVersion ), u_header
|
||||
def post( path, u_header, data )
|
||||
request sprintf('POST %s HTTP/%s', path, HTTPVersion), u_header
|
||||
@socket.write data
|
||||
end
|
||||
|
||||
|
||||
# not work
|
||||
def post( path, u_header = nil )
|
||||
get_response sprintf( 'POST %s HTTP/%s', path, HTTPVersion ), u_header
|
||||
def put( path, u_header, src )
|
||||
request sprintf('PUT %s HTTP/%s', path, HTTPVersion), u_header
|
||||
@socket.write_bin src
|
||||
end
|
||||
|
||||
# not work
|
||||
def put( path, u_header = nil )
|
||||
get_response sprintf( 'PUT %s HTTP/%s', path, HTTPVersion ), u_header
|
||||
end
|
||||
|
||||
# def delete
|
||||
|
||||
|
@ -215,19 +314,64 @@ class HTTPBadResponse < HTTPError; end
|
|||
# def options
|
||||
|
||||
|
||||
def get_response
|
||||
rep = get_reply
|
||||
rep = get_reply while ContinueCode === rep
|
||||
header = {}
|
||||
while true do
|
||||
line = @socket.readline
|
||||
break if line.empty?
|
||||
nm = /\A[^:]+/.match( line )[0].strip.downcase
|
||||
header[nm] = line
|
||||
end
|
||||
|
||||
rep['http-header'] = header
|
||||
reply_must rep, SuccessCode
|
||||
|
||||
rep
|
||||
end
|
||||
|
||||
def get_body( rep, dest )
|
||||
header = rep['http-header']
|
||||
if chunked? header then
|
||||
read_chunked( dest, header )
|
||||
else
|
||||
if clen = content_length( header ) then
|
||||
@socket.read clen, dest
|
||||
else
|
||||
###
|
||||
### "multipart/bytelenges" check should be done here ...
|
||||
###
|
||||
@socket.read_all dest
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def try_get_body( rep, dest )
|
||||
rep = get_reply while ContinueCode === rep
|
||||
return nil unless rep['body-exist']
|
||||
|
||||
get_body rep, dest
|
||||
end
|
||||
|
||||
|
||||
private
|
||||
|
||||
|
||||
def get_response( line, u_header )
|
||||
@socket.writeline line
|
||||
write_header u_header
|
||||
rep = get_reply
|
||||
header = read_header
|
||||
reply_must rep, SuccessCode
|
||||
|
||||
header
|
||||
def request( req, u_header )
|
||||
@socket.writeline req
|
||||
if u_header then
|
||||
header = @in_header.dup.update( u_header )
|
||||
else
|
||||
header = @in_header
|
||||
end
|
||||
header.each do |n,v|
|
||||
@socket.writeline n + ': ' + v
|
||||
end
|
||||
@socket.writeline ''
|
||||
end
|
||||
|
||||
|
||||
def get_reply
|
||||
str = @socket.readline
|
||||
unless /\AHTTP\/(\d+\.\d+)?\s+(\d\d\d)\s*(.*)\z/i === str then
|
||||
|
@ -237,20 +381,66 @@ class HTTPBadResponse < HTTPError; end
|
|||
status = $2
|
||||
discrip = $3
|
||||
|
||||
be = false
|
||||
klass = case status[0]
|
||||
when ?1 then
|
||||
case status[2]
|
||||
when ?0 then ContinueCode
|
||||
when ?1 then SuccessCode
|
||||
when ?1 then HTTPSuccessCode
|
||||
else UnknownCode
|
||||
end
|
||||
when ?2 then
|
||||
case status[2]
|
||||
when ?0 then be = true; HTTPSuccessCode
|
||||
when ?1 then be = false; HTTPSuccessCode
|
||||
when ?2 then be = true; HTTPSuccessCode
|
||||
when ?3 then be = true; HTTPSuccessCode
|
||||
when ?4 then be = false; HTTPNoContentCode
|
||||
when ?5 then be = false; HTTPResetContentCode
|
||||
when ?6 then be = true; HTTPPartialContentCode
|
||||
else UnknownCode
|
||||
end
|
||||
when ?3 then
|
||||
case status[2]
|
||||
when ?0 then be = true; HTTPMultipleChoiceCode
|
||||
when ?1 then be = true; HTTPMovedPermanentryCode
|
||||
when ?2 then be = true; HTTPMovedTemporarilyCode
|
||||
when ?3 then be = true; HTTPMovedPermanentryCode
|
||||
when ?4 then be = false; HTTPNotModifiedCode
|
||||
when ?5 then be = false; HTTPUseProxyCode
|
||||
else UnknownCode
|
||||
end
|
||||
when ?2 then SuccessCode
|
||||
when ?3 then RetryCode
|
||||
when ?4 then ServerBusyCode
|
||||
when ?5 then FatalErrorCode
|
||||
else UnknownCode
|
||||
end
|
||||
klass.new( status, discrip )
|
||||
code = klass.new( status, discrip )
|
||||
code['body-exist'] = be
|
||||
code
|
||||
end
|
||||
|
||||
def read_chunked( ret, header )
|
||||
line = nil
|
||||
len = nil
|
||||
total = 0
|
||||
|
||||
while true do
|
||||
line = @socket.readline
|
||||
unless /[0-9a-hA-H]+/ === line then
|
||||
raise HTTPBadResponse, "chunk size not given"
|
||||
end
|
||||
len = $&.hex
|
||||
break if len == 0
|
||||
@socket.read( len, ret ); total += len
|
||||
@socket.read 2 # \r\n
|
||||
end
|
||||
while true do
|
||||
line = @socket.readline
|
||||
break if line.empty?
|
||||
end
|
||||
|
||||
header.delete 'transfer-encoding'
|
||||
header[ 'content-length' ] = "Content-Length: #{total}"
|
||||
end
|
||||
|
||||
|
||||
|
@ -274,63 +464,6 @@ class HTTPBadResponse < HTTPError; end
|
|||
false
|
||||
end
|
||||
|
||||
|
||||
def read_header
|
||||
header = {}
|
||||
while true do
|
||||
line = @socket.readline
|
||||
break if line.empty?
|
||||
/\A[^:]+/ === line
|
||||
nm = $&
|
||||
nm.strip!
|
||||
nm.downcase!
|
||||
header[ nm ] = line
|
||||
end
|
||||
|
||||
header
|
||||
end
|
||||
|
||||
def write_header( user )
|
||||
if user then
|
||||
header = @in_header.dup.update user
|
||||
else
|
||||
header = @in_header
|
||||
end
|
||||
header.each do |n,v|
|
||||
@socket.writeline n + ': ' + v
|
||||
end
|
||||
@socket.writeline ''
|
||||
|
||||
if tmp = header['Connection'] then
|
||||
/close/i === tmp
|
||||
else
|
||||
false
|
||||
end
|
||||
end
|
||||
|
||||
def read_chunked_body( ret )
|
||||
line = nil
|
||||
len = nil
|
||||
total = 0
|
||||
|
||||
while true do
|
||||
line = @socket.readline
|
||||
unless /[0-9a-hA-H]+/ === line then
|
||||
raise HTTPBadResponse, "chunk size not given"
|
||||
end
|
||||
len = $&.hex
|
||||
break if len == 0
|
||||
@socket.read( len, ret ); total += len
|
||||
@socket.read 2 # \r\n
|
||||
end
|
||||
while true do
|
||||
line = @socket.readline
|
||||
break if line.empty?
|
||||
end
|
||||
|
||||
total
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
|
|
|
@ -216,66 +216,6 @@ Net::POP3
|
|||
APOPSession = APOP
|
||||
|
||||
|
||||
=begin
|
||||
|
||||
== Net::POP3Command
|
||||
|
||||
POP3 command class.
|
||||
|
||||
=== Super Class
|
||||
|
||||
Net::Command
|
||||
|
||||
=== Class Methods
|
||||
|
||||
: new( socket )
|
||||
This method creates new POP3Command object. 'socket' must be ProtocolSocket.
|
||||
|
||||
|
||||
=== Methods
|
||||
|
||||
: auth( account, password )
|
||||
This method do POP authorization (no RPOP)
|
||||
In case of failed authorization, raises Protocol::ProtocolError exception.
|
||||
|
||||
: list
|
||||
a list of mails which existing on server.
|
||||
The list is an array like "array[ number ] = size".
|
||||
|
||||
ex:
|
||||
|
||||
The list from server is
|
||||
|
||||
1 2452
|
||||
2 3355
|
||||
4 9842
|
||||
:
|
||||
|
||||
then, an array is
|
||||
|
||||
[ nil, 2452, 3355, nil, 9842, ... ]
|
||||
|
||||
: quit
|
||||
This method ends POP using 'QUIT' commmand.
|
||||
|
||||
: rset
|
||||
This method reset all changes done in current session,
|
||||
by sending 'RSET' command.
|
||||
|
||||
: top( num, lines = 0 )
|
||||
This method gets all mail header and 'lines' lines body
|
||||
by sending 'TOP' command. 'num' is mail number.
|
||||
|
||||
WARNING: the TOP command is 'Optional' in RFC1939 (POP3)
|
||||
|
||||
: retr( num : Integer )
|
||||
This method gets a mail by 'RETR' command. 'num' is mail number.
|
||||
|
||||
: dele( num : Integer )
|
||||
This method deletes a mail on server by 'DELE'.
|
||||
|
||||
=end
|
||||
|
||||
|
||||
class POP3Command < Command
|
||||
|
||||
|
@ -371,22 +311,6 @@ Net::Command
|
|||
end
|
||||
|
||||
|
||||
=begin
|
||||
|
||||
== APOPCommand
|
||||
|
||||
=== Super Class
|
||||
|
||||
POP3Command
|
||||
|
||||
=== Methods
|
||||
|
||||
: auth( account, password )
|
||||
This method do authorization by sending 'APOP' command.
|
||||
If server is not APOP server, this raises Net::ProtoAuthError exception.
|
||||
On other errors, raises Net::ProtocolError.
|
||||
|
||||
=end
|
||||
|
||||
class APOPCommand < POP3Command
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@ require 'socket'
|
|||
|
||||
module Net
|
||||
|
||||
Version = '1.1.7'
|
||||
Version = '1.1.9'
|
||||
|
||||
=begin
|
||||
|
||||
|
@ -219,27 +219,6 @@ Object
|
|||
Session = Protocol
|
||||
|
||||
|
||||
=begin
|
||||
|
||||
== Net::Command
|
||||
|
||||
=== Super Class
|
||||
|
||||
Object
|
||||
|
||||
=== Class Methods
|
||||
|
||||
: new( socket )
|
||||
This method create new Command object. 'socket' must be ProtocolSocket.
|
||||
This method is abstract class.
|
||||
|
||||
|
||||
=== Methods
|
||||
|
||||
: quit
|
||||
This method dispatch command which ends the protocol.
|
||||
|
||||
=end
|
||||
|
||||
class Command
|
||||
|
||||
|
@ -317,10 +296,26 @@ Object
|
|||
def initialize( cod, mes )
|
||||
@code = cod
|
||||
@msg = mes
|
||||
@data = nil
|
||||
end
|
||||
|
||||
attr_reader :code, :msg
|
||||
|
||||
def []( key )
|
||||
if @data then
|
||||
@data[key]
|
||||
else
|
||||
nil
|
||||
end
|
||||
end
|
||||
|
||||
def []=( key, val )
|
||||
unless h = @data then
|
||||
@data = h = {}
|
||||
end
|
||||
h[key] = val
|
||||
end
|
||||
|
||||
|
||||
def error!( sending )
|
||||
mes = <<MES
|
||||
|
@ -370,78 +365,6 @@ MES
|
|||
end
|
||||
|
||||
|
||||
=begin
|
||||
|
||||
== Net::ProtocolSocket
|
||||
|
||||
=== Super Class
|
||||
|
||||
Object
|
||||
|
||||
=== Class Methods
|
||||
|
||||
: new( address = 'localhost', port = nil )
|
||||
This create new ProtocolSocket object, and connect to server.
|
||||
|
||||
|
||||
=== Methods
|
||||
|
||||
: close
|
||||
This method closes socket.
|
||||
|
||||
: address, addr
|
||||
a FQDN address of server
|
||||
|
||||
: ip_address, ipaddr
|
||||
an IP address of server
|
||||
|
||||
: port
|
||||
connecting port number.
|
||||
|
||||
: closed?
|
||||
true if ProtocolSokcet have been closed already
|
||||
|
||||
|
||||
: read( length )
|
||||
This method read 'length' bytes and return the string.
|
||||
|
||||
: readuntil( target )
|
||||
This method read until find 'target'. Returns read string.
|
||||
|
||||
: readline
|
||||
read until "\r\n" and returns it without "\r\n".
|
||||
|
||||
: read_pendstr
|
||||
This method read until "\r\n.\r\n".
|
||||
At the same time, delete period at line head and final line ("\r\n.\r\n").
|
||||
|
||||
: read_pendlist
|
||||
: read_pendlist{|line| .... }
|
||||
This method read until "\r\n.\r\n". This method resembles to 'read_pendstr',
|
||||
but 'read_pendlist' don't check period at line head, and returns array which
|
||||
each element is one line.
|
||||
|
||||
When this method was called with block, evaluate it for each reading a line.
|
||||
|
||||
|
||||
: write( src )
|
||||
This method send 'src'. ProtocolSocket read strings from 'src' by 'each'
|
||||
iterator. This method returns written bytes.
|
||||
|
||||
: writebin( src )
|
||||
This method send 'src'. ProtocolSokcet read string from 'src' by 'each'
|
||||
iterator. This method returns written bytes.
|
||||
|
||||
: writeline( str )
|
||||
This method writes 'str'. There has not to be bare "\r" or "\n" in 'str'.
|
||||
|
||||
: write_pendstr( src )
|
||||
This method writes 'src' as a mail.
|
||||
ProtocolSocket reads strings from 'src' by 'each' iterator.
|
||||
This returns written bytes.
|
||||
|
||||
=end
|
||||
|
||||
|
||||
class WriteAdapter
|
||||
|
||||
|
@ -639,6 +562,13 @@ Object
|
|||
public
|
||||
|
||||
|
||||
def write( str )
|
||||
do_write_beg
|
||||
do_write_do str
|
||||
do_write_fin
|
||||
end
|
||||
|
||||
|
||||
def writeline( str )
|
||||
do_write_beg
|
||||
do_write_do str
|
||||
|
@ -647,10 +577,10 @@ Object
|
|||
end
|
||||
|
||||
|
||||
def writebin( src )
|
||||
def write_bin( src, block = nil )
|
||||
do_write_beg
|
||||
if iterator? then
|
||||
yield WriteAdapter.new( self, :do_write_do )
|
||||
if block then
|
||||
block.call WriteAdapter.new( self, :do_write_do )
|
||||
else
|
||||
src.each do |bin|
|
||||
do_write_do bin
|
||||
|
@ -660,18 +590,6 @@ Object
|
|||
end
|
||||
|
||||
|
||||
def write( src )
|
||||
do_write_beg
|
||||
if iterator? then
|
||||
yield WriteAdapter.new( self, :write_inner )
|
||||
else
|
||||
write_inner src
|
||||
end
|
||||
each_crlf_line2( :i_w )
|
||||
do_write_fin
|
||||
end
|
||||
|
||||
|
||||
def write_pendstr( src )
|
||||
@pipe << "writing text from #{src.type}\n" if pre = @pipe ; @pipe = nil
|
||||
|
||||
|
|
|
@ -74,15 +74,14 @@ Net::Protocol
|
|||
protocol_param :command_type, '::Net::SMTPCommand'
|
||||
|
||||
|
||||
def sendmail( mailsrc, fromaddr, toaddrs, &block )
|
||||
@command.mailfrom fromaddr
|
||||
@command.rcpt toaddrs
|
||||
@command.data
|
||||
@command.write_mail( mailsrc, &block )
|
||||
def sendmail( mailsrc, fromaddr, toaddrs )
|
||||
do_ready fromaddr, toaddrs
|
||||
@command.write_mail mailsrc
|
||||
end
|
||||
|
||||
def ready( fromaddr, toaddrs, &block )
|
||||
sendmail nil, fromaddr, toaddrs, &block
|
||||
do_ready fromaddr, toaddrs
|
||||
@command.write_mail( &block )
|
||||
end
|
||||
|
||||
|
||||
|
@ -92,6 +91,12 @@ Net::Protocol
|
|||
private
|
||||
|
||||
|
||||
def do_ready( fromaddr, toaddrs )
|
||||
@command.mailfrom fromaddr
|
||||
@command.rcpt toaddrs
|
||||
@command.data
|
||||
end
|
||||
|
||||
def do_start( helodom = ENV['HOSTNAME'] )
|
||||
unless helodom then
|
||||
raise ArgumentError, "cannot get hostname"
|
||||
|
@ -111,48 +116,6 @@ Net::Protocol
|
|||
SMTPSession = SMTP
|
||||
|
||||
|
||||
=begin
|
||||
|
||||
== Net::SMTPCommand
|
||||
|
||||
=== Super Class
|
||||
|
||||
Net::Command
|
||||
|
||||
=== Class Methods
|
||||
|
||||
: new( socket )
|
||||
This method creates new SMTPCommand object, and open SMTP.
|
||||
|
||||
|
||||
=== Methods
|
||||
|
||||
: helo( helo_domain )
|
||||
This method send "HELO" command and start SMTP.
|
||||
helo_domain is localhost's FQDN.
|
||||
|
||||
: mailfrom( from_addr )
|
||||
This method sends "MAIL FROM" command.
|
||||
from_addr is your mail address (xxxx@xxxx)
|
||||
|
||||
: rcpt( to_addrs )
|
||||
This method sends "RCPT TO" command.
|
||||
to_addrs is array of mail address (xxxx@xxxx) of destination.
|
||||
|
||||
: data
|
||||
This method sends "DATA" command.
|
||||
|
||||
: write_mail( mailsrc )
|
||||
: write_mail {|socket| ... }
|
||||
send 'mailsrc' as mail.
|
||||
SMTPCommand reads strings from 'mailsrc' by calling 'each' iterator.
|
||||
When iterator, SMTPCommand only stand by socket and pass it.
|
||||
(The socket will accepts only 'in_write' method in the block)
|
||||
|
||||
: quit
|
||||
This method sends "QUIT" command and ends SMTP session.
|
||||
|
||||
=end
|
||||
|
||||
class SMTPCommand < Command
|
||||
|
||||
|
@ -189,7 +152,7 @@ Net::Command
|
|||
end
|
||||
|
||||
|
||||
def write_mail( mailsrc, &block )
|
||||
def write_mail( mailsrc = nil, &block )
|
||||
@socket.write_pendstr mailsrc, &block
|
||||
check_reply SuccessCode
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue