summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/net/http.rb129
-rw-r--r--lib/net/protocol.rb157
2 files changed, 192 insertions, 94 deletions
diff --git a/lib/net/http.rb b/lib/net/http.rb
index 40f6238d502..c5612c8754e 100644
--- a/lib/net/http.rb
+++ b/lib/net/http.rb
@@ -13,12 +13,14 @@ You can freely distribute/modify this library.
== Class Methods
-: new( address = 'localhost', port = 80 )
+: new( address = 'localhost', port = 80, proxy_addr = nil, proxy_port = nil )
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 ) {|http| .... }
- equals to Net::HTTP.new( address, port ).start
+: start( address = 'localhost', port = 80, proxy_addr = nil, proxy_port = nil )
+: start( address = 'localhost', port = 80, proxy_addr = nil, proxy_port = nil ) {|http| .... }
+ is equals to Net::HTTP.new( address, port, proxy_addr, proxy_port ).start(&block)
: port
HTTP default port, 80
@@ -127,11 +129,8 @@ All "key" is case-insensitive.
== Methods
-: code
- HTTP result code. For example, '302'
-
-: message
- HTTP result message. For example, 'Not Found'
+: body
+ the entity body. ("dest" argument for HTTP#get, post, put)
: self[ key ]
returns header field for "key".
@@ -148,9 +147,11 @@ All "key" is case-insensitive.
: each {|name,value| .... }
iterate for each field name and value pair
-: body
- "dest" argument for HTTP#get, post, put
+: code
+ HTTP result code. For example, '302'
+: message
+ HTTP result message. For example, 'Not Found'
= class HTTPReadAdapter
@@ -169,6 +170,37 @@ All "key" is case-insensitive.
If this method is called twice, block is not called and
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
require 'net/protocol'
@@ -184,15 +216,73 @@ module Net
protocol_param :port, '80'
protocol_param :command_type, '::Net::HTTPCommand'
- def HTTP.procdest( dest, block )
- if block then
- return ReadAdapter.new( block ), nil
- else
- dest ||= ''
- return dest, dest
+ class << self
+
+ def procdest( dest, block )
+ if block then
+ return ReadAdapter.new( block ), nil
+ else
+ dest ||= ''
+ return dest, dest
+ 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
+
+ @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 )
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 (__;;;
def put( path, src, u_header = nil )
- ret = nil
- resp = put2( path, src, u_header ) {|f| ret = f.body }
+ resp = put2( path, src, u_header ) {|f| f.body }
resp.value
- return resp, ret
+ return resp, resp.body
end
def put2( path, src, u_header = nil, &block )
diff --git a/lib/net/protocol.rb b/lib/net/protocol.rb
index 25b41932f16..f234371a694 100644
--- a/lib/net/protocol.rb
+++ b/lib/net/protocol.rb
@@ -64,7 +64,7 @@ module Net
class Protocol
- Version = '1.1.23'
+ Version = '1.1.24'
class << self
@@ -80,7 +80,8 @@ module Net
end
end
- def Proxy( p_addr, p_port )
+ def Proxy( p_addr, p_port = nil )
+ p_port ||= self.port
klass = Class.new( self )
klass.module_eval %-
@@ -109,7 +110,7 @@ module Net
def proxy?
false
end
-
+
private
@@ -587,44 +588,43 @@ module Net
def write( str )
- do_write_beg
- do_write_do str
- do_write_fin
+ writing {
+ do_write str
+ }
end
def writeline( str )
- do_write_beg
- do_write_do str
- do_write_do "\r\n"
- do_write_fin
+ writing {
+ do_write str
+ do_write "\r\n"
+ }
end
def write_bin( src, block )
- do_write_beg
- if block then
- block.call WriteAdapter.new( self, :do_write_do )
- else
- src.each do |bin|
- do_write_do bin
+ writing {
+ if block then
+ block.call WriteAdapter.new( self, :do_write )
+ else
+ src.each do |bin|
+ do_write bin
+ end
end
- end
- do_write_fin
+ }
end
def write_pendstr( src, block )
@pipe << "writing text from #{src.type}\n" if @pipe; pipeoff
- do_write_beg
- if block then
- block.call WriteAdapter.new( self, :write_pendstr_inner )
- else
- write_pendstr_inner src
- end
- do_write_do ".\r\n"
- wsize = do_write_fin
+ wsize = use_each_crlf_line {
+ if block then
+ block.call WriteAdapter.new( self, :wpend_in )
+ else
+ wpend_in src
+ end
+ }
@pipe << "wrote #{wsize} bytes text\n" if pipeon
wsize
@@ -634,82 +634,102 @@ module Net
private
- def write_inner( src )
- each_crlf_line( src, :do_write_do )
+ def wpend_in( src )
+ line = nil
+ each_crlf_line( src ) do |line|
+ do_write '.' if line[0] == ?.
+ do_write line
+ end
end
+ def use_each_crlf_line
+ writing {
+ @wbuf = ''
- def write_pendstr_inner( src )
- each_crlf_line src, :i_w_pend
- end
+ yield
- def i_w_pend( line )
- do_write_do '.' if line[0] == ?.
- do_write_do line
- end
+ 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
- def each_crlf_line( src, mid )
- buf = ''
+ def each_crlf_line( src )
str = m = nil
+ beg = 0
- adding( src, buf ) do
- while true do
- m = /[^\r\n]*(\n|\r\n|\r)/.match( buf )
- break unless m
-
- str = m[0]
- if str.size == buf.size and buf[-1] == ?\r then
+ adding( src ) do
+ buf = @wbuf
+ while buf.index( /\n|\r\n|\r/, beg ) do
+ m = $~
+ if m.begin(0) == buf.size - 1 and buf[-1] == ?\r then
# "...\r" : can follow "\n..."
break
end
- buf[ 0, str.size ] = ''
- str.chop!
+ str = buf[ beg, m.begin(0) - beg ]
str.concat "\r\n"
- __send__ mid, str
+ yield str
+ beg = m.end(0)
end
- end
- 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"
+ @wbuf = buf[ beg, buf.size - beg ]
end
end
- def adding( src, buf )
+ def adding( src )
i = nil
case src
when String
- 0.step( src.size, 512 ) do |i|
- buf << src[ i, 512 ]
+ 0.step( src.size - 1, 2048 ) do |i|
+ @wbuf << src[i,2048]
yield
end
when File
while true do
- i = src.read( 512 )
+ i = src.read( 2048 )
break unless i
- buf << i
+ i[0,0] = @wbuf
+ @wbuf = i
yield
end
else
- src.each do |bin|
- buf << bin
- yield if buf.size > 512
+ src.each do |i|
+ @wbuf << i
+ if @wbuf.size > 2048 then
+ yield
+ end
end
end
end
- def do_write_beg
+ def writing
@writtensize = 0
@sending = ''
+
+ yield
+
+ if @pipe then
+ @pipe << 'write "'
+ @pipe << @sending
+ @pipe << "\"\n"
+ end
+ @socket.flush
+ @writtensize
end
- def do_write_do( arg )
+ def do_write( arg )
if @pipe or @sending.size < 128 then
@sending << Net.quote( arg )
else
@@ -721,17 +741,6 @@ module Net
s
end
- def do_write_fin
- if @pipe then
- @pipe << 'write "'
- @pipe << @sending
- @pipe << "\"\n"
- end
-
- @socket.flush
- @writtensize
- end
-
def pipeoff
@prepipe = @pipe