mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* lib/net/protocol.rb, smtp.rb, pop.rb, http.rb: 1.1.24.
* lib/net/protocol.rb: modified each_crlf_line again. * lib/net/protocol.rb: do_write_beg,do_write_end -> writing{} do_write_do -> do_write * lib/net/http.rb: can make proxy connection by passing addresses to HTTP.new, start. * lib/net/http.rb: HTTP.new_implementation, old_implementation: can use 1.2 implementation of head, get, post, put. (see document) git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@789 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
ad203b06f4
commit
1261c7e055
2 changed files with 193 additions and 95 deletions
129
lib/net/http.rb
129
lib/net/http.rb
|
@ -13,12 +13,14 @@ You can freely distribute/modify this library.
|
||||||
|
|
||||||
== Class Methods
|
== Class Methods
|
||||||
|
|
||||||
: new( address = 'localhost', port = 80 )
|
: new( address = 'localhost', port = 80, proxy_addr = nil, proxy_port = nil )
|
||||||
creates a new Net::HTTP object.
|
creates a new Net::HTTP object.
|
||||||
|
if proxy_addr is given, this method is equals to
|
||||||
|
Net::HTTP::Proxy(proxy_addr,proxy_port).
|
||||||
|
|
||||||
: start( address = 'localhost', port = 80 )
|
: start( address = 'localhost', port = 80, proxy_addr = nil, proxy_port = nil )
|
||||||
: start( address = 'localhost', port = 80 ) {|http| .... }
|
: start( address = 'localhost', port = 80, proxy_addr = nil, proxy_port = nil ) {|http| .... }
|
||||||
equals to Net::HTTP.new( address, port ).start
|
is equals to Net::HTTP.new( address, port, proxy_addr, proxy_port ).start(&block)
|
||||||
|
|
||||||
: port
|
: port
|
||||||
HTTP default port, 80
|
HTTP default port, 80
|
||||||
|
@ -127,11 +129,8 @@ All "key" is case-insensitive.
|
||||||
|
|
||||||
== Methods
|
== Methods
|
||||||
|
|
||||||
: code
|
: body
|
||||||
HTTP result code. For example, '302'
|
the entity body. ("dest" argument for HTTP#get, post, put)
|
||||||
|
|
||||||
: message
|
|
||||||
HTTP result message. For example, 'Not Found'
|
|
||||||
|
|
||||||
: self[ key ]
|
: self[ key ]
|
||||||
returns header field for "key".
|
returns header field for "key".
|
||||||
|
@ -148,9 +147,11 @@ All "key" is case-insensitive.
|
||||||
: each {|name,value| .... }
|
: each {|name,value| .... }
|
||||||
iterate for each field name and value pair
|
iterate for each field name and value pair
|
||||||
|
|
||||||
: body
|
: code
|
||||||
"dest" argument for HTTP#get, post, put
|
HTTP result code. For example, '302'
|
||||||
|
|
||||||
|
: message
|
||||||
|
HTTP result message. For example, 'Not Found'
|
||||||
|
|
||||||
= class HTTPReadAdapter
|
= class HTTPReadAdapter
|
||||||
|
|
||||||
|
@ -169,6 +170,37 @@ All "key" is case-insensitive.
|
||||||
If this method is called twice, block is not called and
|
If this method is called twice, block is not called and
|
||||||
returns first "dest".
|
returns first "dest".
|
||||||
|
|
||||||
|
|
||||||
|
= http.rb version 1.2 features
|
||||||
|
|
||||||
|
You can use these 1.2 features by calling method
|
||||||
|
Net::HTTP.new_implementation. Or you want to use 1.1 feature,
|
||||||
|
call Net::HTTP.old_implementation.
|
||||||
|
|
||||||
|
Now old_impl is default and if new_impl was called then Net::HTTP
|
||||||
|
changes self into new implementation. In 1.2, new_impl is default
|
||||||
|
and if old_impl was called then changes self into old implementation.
|
||||||
|
|
||||||
|
== Warning!!!
|
||||||
|
|
||||||
|
You can call new_implementation/old_implementation any times
|
||||||
|
but CANNOT call both of them at the same time.
|
||||||
|
You must use one implementation in one application (process).
|
||||||
|
|
||||||
|
== Method
|
||||||
|
|
||||||
|
: get( path, u_header = nil )
|
||||||
|
: get( path, u_header = nil ) {|str| .... }
|
||||||
|
get document from "path" and returns HTTPResponse object.
|
||||||
|
|
||||||
|
: head( path, u_header = nil )
|
||||||
|
get only document header from "path" and returns HTTPResponse object.
|
||||||
|
|
||||||
|
: post( path, data, u_header = nil )
|
||||||
|
: post( path, data, u_header = nil ) {|str| .... }
|
||||||
|
post "data" to "path" entity and get document,
|
||||||
|
then returns HTTPResponse object.
|
||||||
|
|
||||||
=end
|
=end
|
||||||
|
|
||||||
require 'net/protocol'
|
require 'net/protocol'
|
||||||
|
@ -184,15 +216,73 @@ module Net
|
||||||
protocol_param :port, '80'
|
protocol_param :port, '80'
|
||||||
protocol_param :command_type, '::Net::HTTPCommand'
|
protocol_param :command_type, '::Net::HTTPCommand'
|
||||||
|
|
||||||
def HTTP.procdest( dest, block )
|
class << self
|
||||||
if block then
|
|
||||||
return ReadAdapter.new( block ), nil
|
def procdest( dest, block )
|
||||||
else
|
if block then
|
||||||
dest ||= ''
|
return ReadAdapter.new( block ), nil
|
||||||
return dest, dest
|
else
|
||||||
|
dest ||= ''
|
||||||
|
return dest, dest
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
alias orig_new new
|
||||||
|
|
||||||
|
def new( address = nil, port = nil, p_addr = nil, p_port = nil )
|
||||||
|
(p_addr ? self::Proxy(p_addr, p_port) : self).orig_new( address, port )
|
||||||
|
end
|
||||||
|
|
||||||
|
def start( address = nil, port = nil, p_addr = nil, p_port = nil, &block )
|
||||||
|
new( address, port, p_addr, p_port ).start( &block )
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@new_impl = false
|
||||||
|
|
||||||
|
def HTTP.new_implementation
|
||||||
|
return if @new_impl
|
||||||
|
@new_impl = true
|
||||||
|
module_eval %^
|
||||||
|
|
||||||
|
undef head
|
||||||
|
alias head head2
|
||||||
|
undef head2
|
||||||
|
|
||||||
|
alias old_get2 get2
|
||||||
|
undef get2
|
||||||
|
undef get
|
||||||
|
|
||||||
|
def get( path, u_header = nil, dest = nil, &block )
|
||||||
|
old_get2( path, u_header ) {|f| f.body( dest, &block ) }
|
||||||
|
end
|
||||||
|
|
||||||
|
alias old_post2 post2
|
||||||
|
undef post2
|
||||||
|
undef post
|
||||||
|
|
||||||
|
def post( path, data, u_header = nil, dest = nil, &block )
|
||||||
|
old_post2( path, data, u_header ) {|f| f.body( dest, &block ) }
|
||||||
|
end
|
||||||
|
|
||||||
|
alias old_put2 put2
|
||||||
|
undef put2
|
||||||
|
undef put
|
||||||
|
|
||||||
|
def put( path, src, u_header = nil )
|
||||||
|
old_put2( path, src, u_header ) {|f| f.body }
|
||||||
|
end
|
||||||
|
|
||||||
|
^
|
||||||
|
end
|
||||||
|
|
||||||
|
def HTTP.old_implementation
|
||||||
|
if @new_impl then
|
||||||
|
raise RuntimeError, "http.rb is already switched to new implementation"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
def get( path, u_header = nil, dest = nil, &block )
|
def get( path, u_header = nil, dest = nil, &block )
|
||||||
resp = get2( path, u_header ) {|f| dest = f.body( dest, &block ) }
|
resp = get2( path, u_header ) {|f| dest = f.body( dest, &block ) }
|
||||||
|
@ -237,10 +327,9 @@ module Net
|
||||||
|
|
||||||
# not tested because I could not setup apache (__;;;
|
# not tested because I could not setup apache (__;;;
|
||||||
def put( path, src, u_header = nil )
|
def put( path, src, u_header = nil )
|
||||||
ret = nil
|
resp = put2( path, src, u_header ) {|f| f.body }
|
||||||
resp = put2( path, src, u_header ) {|f| ret = f.body }
|
|
||||||
resp.value
|
resp.value
|
||||||
return resp, ret
|
return resp, resp.body
|
||||||
end
|
end
|
||||||
|
|
||||||
def put2( path, src, u_header = nil, &block )
|
def put2( path, src, u_header = nil, &block )
|
||||||
|
|
|
@ -64,7 +64,7 @@ module Net
|
||||||
|
|
||||||
class Protocol
|
class Protocol
|
||||||
|
|
||||||
Version = '1.1.23'
|
Version = '1.1.24'
|
||||||
|
|
||||||
|
|
||||||
class << self
|
class << self
|
||||||
|
@ -80,7 +80,8 @@ module Net
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def Proxy( p_addr, p_port )
|
def Proxy( p_addr, p_port = nil )
|
||||||
|
p_port ||= self.port
|
||||||
klass = Class.new( self )
|
klass = Class.new( self )
|
||||||
klass.module_eval %-
|
klass.module_eval %-
|
||||||
|
|
||||||
|
@ -109,7 +110,7 @@ module Net
|
||||||
def proxy?
|
def proxy?
|
||||||
false
|
false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
|
@ -587,44 +588,43 @@ module Net
|
||||||
|
|
||||||
|
|
||||||
def write( str )
|
def write( str )
|
||||||
do_write_beg
|
writing {
|
||||||
do_write_do str
|
do_write str
|
||||||
do_write_fin
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
def writeline( str )
|
def writeline( str )
|
||||||
do_write_beg
|
writing {
|
||||||
do_write_do str
|
do_write str
|
||||||
do_write_do "\r\n"
|
do_write "\r\n"
|
||||||
do_write_fin
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
def write_bin( src, block )
|
def write_bin( src, block )
|
||||||
do_write_beg
|
writing {
|
||||||
if block then
|
if block then
|
||||||
block.call WriteAdapter.new( self, :do_write_do )
|
block.call WriteAdapter.new( self, :do_write )
|
||||||
else
|
else
|
||||||
src.each do |bin|
|
src.each do |bin|
|
||||||
do_write_do bin
|
do_write bin
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
}
|
||||||
do_write_fin
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
def write_pendstr( src, block )
|
def write_pendstr( src, block )
|
||||||
@pipe << "writing text from #{src.type}\n" if @pipe; pipeoff
|
@pipe << "writing text from #{src.type}\n" if @pipe; pipeoff
|
||||||
|
|
||||||
do_write_beg
|
wsize = use_each_crlf_line {
|
||||||
if block then
|
if block then
|
||||||
block.call WriteAdapter.new( self, :write_pendstr_inner )
|
block.call WriteAdapter.new( self, :wpend_in )
|
||||||
else
|
else
|
||||||
write_pendstr_inner src
|
wpend_in src
|
||||||
end
|
end
|
||||||
do_write_do ".\r\n"
|
}
|
||||||
wsize = do_write_fin
|
|
||||||
|
|
||||||
@pipe << "wrote #{wsize} bytes text\n" if pipeon
|
@pipe << "wrote #{wsize} bytes text\n" if pipeon
|
||||||
wsize
|
wsize
|
||||||
|
@ -634,82 +634,102 @@ module Net
|
||||||
private
|
private
|
||||||
|
|
||||||
|
|
||||||
def write_inner( src )
|
def wpend_in( src )
|
||||||
each_crlf_line( src, :do_write_do )
|
line = nil
|
||||||
|
each_crlf_line( src ) do |line|
|
||||||
|
do_write '.' if line[0] == ?.
|
||||||
|
do_write line
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def use_each_crlf_line
|
||||||
|
writing {
|
||||||
|
@wbuf = ''
|
||||||
|
|
||||||
def write_pendstr_inner( src )
|
yield
|
||||||
each_crlf_line src, :i_w_pend
|
|
||||||
|
if not @wbuf.empty? then # un-terminated last line
|
||||||
|
if @wbuf[-1] == ?\r then
|
||||||
|
@wbuf.chop!
|
||||||
|
end
|
||||||
|
@wbuf.concat "\r\n"
|
||||||
|
do_write @wbuf
|
||||||
|
elsif @writtensize == 0 then # empty src
|
||||||
|
do_write "\r\n"
|
||||||
|
end
|
||||||
|
do_write ".\r\n"
|
||||||
|
|
||||||
|
@wbuf = nil
|
||||||
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
def i_w_pend( line )
|
def each_crlf_line( src )
|
||||||
do_write_do '.' if line[0] == ?.
|
|
||||||
do_write_do line
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
def each_crlf_line( src, mid )
|
|
||||||
buf = ''
|
|
||||||
str = m = nil
|
str = m = nil
|
||||||
|
beg = 0
|
||||||
|
|
||||||
adding( src, buf ) do
|
adding( src ) do
|
||||||
while true do
|
buf = @wbuf
|
||||||
m = /[^\r\n]*(\n|\r\n|\r)/.match( buf )
|
while buf.index( /\n|\r\n|\r/, beg ) do
|
||||||
break unless m
|
m = $~
|
||||||
|
if m.begin(0) == buf.size - 1 and buf[-1] == ?\r then
|
||||||
str = m[0]
|
|
||||||
if str.size == buf.size and buf[-1] == ?\r then
|
|
||||||
# "...\r" : can follow "\n..."
|
# "...\r" : can follow "\n..."
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
buf[ 0, str.size ] = ''
|
str = buf[ beg, m.begin(0) - beg ]
|
||||||
str.chop!
|
|
||||||
str.concat "\r\n"
|
str.concat "\r\n"
|
||||||
__send__ mid, str
|
yield str
|
||||||
|
beg = m.end(0)
|
||||||
end
|
end
|
||||||
end
|
@wbuf = buf[ beg, buf.size - beg ]
|
||||||
if not buf.empty? then # un-terminated last line
|
|
||||||
buf.concat "\r\n"
|
|
||||||
__send__ mid, buf
|
|
||||||
elsif not str then # empty src
|
|
||||||
__send__ mid, "\r\n"
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def adding( src, buf )
|
def adding( src )
|
||||||
i = nil
|
i = nil
|
||||||
|
|
||||||
case src
|
case src
|
||||||
when String
|
when String
|
||||||
0.step( src.size, 512 ) do |i|
|
0.step( src.size - 1, 2048 ) do |i|
|
||||||
buf << src[ i, 512 ]
|
@wbuf << src[i,2048]
|
||||||
yield
|
yield
|
||||||
end
|
end
|
||||||
|
|
||||||
when File
|
when File
|
||||||
while true do
|
while true do
|
||||||
i = src.read( 512 )
|
i = src.read( 2048 )
|
||||||
break unless i
|
break unless i
|
||||||
buf << i
|
i[0,0] = @wbuf
|
||||||
|
@wbuf = i
|
||||||
yield
|
yield
|
||||||
end
|
end
|
||||||
|
|
||||||
else
|
else
|
||||||
src.each do |bin|
|
src.each do |i|
|
||||||
buf << bin
|
@wbuf << i
|
||||||
yield if buf.size > 512
|
if @wbuf.size > 2048 then
|
||||||
|
yield
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
def do_write_beg
|
def writing
|
||||||
@writtensize = 0
|
@writtensize = 0
|
||||||
@sending = ''
|
@sending = ''
|
||||||
|
|
||||||
|
yield
|
||||||
|
|
||||||
|
if @pipe then
|
||||||
|
@pipe << 'write "'
|
||||||
|
@pipe << @sending
|
||||||
|
@pipe << "\"\n"
|
||||||
|
end
|
||||||
|
@socket.flush
|
||||||
|
@writtensize
|
||||||
end
|
end
|
||||||
|
|
||||||
def do_write_do( arg )
|
def do_write( arg )
|
||||||
if @pipe or @sending.size < 128 then
|
if @pipe or @sending.size < 128 then
|
||||||
@sending << Net.quote( arg )
|
@sending << Net.quote( arg )
|
||||||
else
|
else
|
||||||
|
@ -721,17 +741,6 @@ module Net
|
||||||
s
|
s
|
||||||
end
|
end
|
||||||
|
|
||||||
def do_write_fin
|
|
||||||
if @pipe then
|
|
||||||
@pipe << 'write "'
|
|
||||||
@pipe << @sending
|
|
||||||
@pipe << "\"\n"
|
|
||||||
end
|
|
||||||
|
|
||||||
@socket.flush
|
|
||||||
@writtensize
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
def pipeoff
|
def pipeoff
|
||||||
@prepipe = @pipe
|
@prepipe = @pipe
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue