mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
aamine
* lib/net/http.rb: new method HTTP#request_by_name (test) * lib/net/http.rb: new class HTTPGenericRequest git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@1564 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
fc1f22d5a8
commit
fa20d931bc
5 changed files with 160 additions and 122 deletions
|
@ -1,3 +1,9 @@
|
||||||
|
Wed Jul 4 03:17:31 2001 Minero Aoki <aamine@loveruby.net>
|
||||||
|
|
||||||
|
* lib/net/http.rb: new method HTTP#request_by_name (test)
|
||||||
|
|
||||||
|
* lib/net/http.rb: new class HTTPGenericRequest
|
||||||
|
|
||||||
Tue Jul 3 23:58:29 2001 Akinori MUSHA <knu@iDaemons.org>
|
Tue Jul 3 23:58:29 2001 Akinori MUSHA <knu@iDaemons.org>
|
||||||
|
|
||||||
* lib/mkmf.rb: distclean should remove mkmf.log as well.
|
* lib/mkmf.rb: distclean should remove mkmf.log as well.
|
||||||
|
|
268
lib/net/http.rb
268
lib/net/http.rb
|
@ -1,6 +1,6 @@
|
||||||
=begin
|
=begin
|
||||||
|
|
||||||
= net/http.rb version 1.2.1
|
= net/http.rb version 1.2.2
|
||||||
|
|
||||||
Copyright (c) 1999-2001 Yukihiro Matsumoto
|
Copyright (c) 1999-2001 Yukihiro Matsumoto
|
||||||
|
|
||||||
|
@ -565,7 +565,7 @@ module Net
|
||||||
|
|
||||||
public
|
public
|
||||||
|
|
||||||
def self.def_http_method( nm, hasdest, hasdata )
|
def self.define_http_method_interface( nm, hasdest, hasdata )
|
||||||
name = nm.id2name.downcase
|
name = nm.id2name.downcase
|
||||||
cname = nm.id2name
|
cname = nm.id2name
|
||||||
lineno = __LINE__ + 2
|
lineno = __LINE__ + 2
|
||||||
|
@ -596,25 +596,32 @@ module Net
|
||||||
module_eval src, __FILE__, lineno
|
module_eval src, __FILE__, lineno
|
||||||
end
|
end
|
||||||
|
|
||||||
def_http_method :Get, true, false
|
define_http_method_interface :Get, true, false
|
||||||
def_http_method :Head, false, false
|
define_http_method_interface :Head, false, false
|
||||||
def_http_method :Post, true, true
|
define_http_method_interface :Post, true, true
|
||||||
def_http_method :Put, false, true
|
define_http_method_interface :Put, false, true
|
||||||
|
|
||||||
def request( req, *args )
|
def request( req, body = nil )
|
||||||
common_oper( req ) {
|
connecting( req ) {
|
||||||
req.__send__( :exec,
|
req.__send__( :exec,
|
||||||
@socket, @curr_http_version, edit_path(req.path), *args )
|
@socket, @curr_http_version, edit_path(req.path), body )
|
||||||
yield req.response if block_given?
|
yield req.response if block_given?
|
||||||
}
|
}
|
||||||
req.response
|
req.response
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def request_by_name( name, path, header, body = nil )
|
||||||
|
r = ::Net::NetPrivate::HTTPGenericRequest.new(
|
||||||
|
name, body ? true : false, true,
|
||||||
|
path, header )
|
||||||
|
request r, body
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
|
|
||||||
def common_oper( req )
|
def connecting( req )
|
||||||
req['connection'] ||= 'keep-alive'
|
req['connection'] ||= 'keep-alive'
|
||||||
if not @socket then
|
if not @socket then
|
||||||
start
|
start
|
||||||
|
@ -644,8 +651,6 @@ module Net
|
||||||
D 'Conn close'
|
D 'Conn close'
|
||||||
@socket.close
|
@socket.close
|
||||||
end
|
end
|
||||||
|
|
||||||
req.response
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def keep_alive?( req, res )
|
def keep_alive?( req, res )
|
||||||
|
@ -836,9 +841,9 @@ module Net
|
||||||
|
|
||||||
d1 = m[1].to_i
|
d1 = m[1].to_i
|
||||||
d2 = m[2].to_i
|
d2 = m[2].to_i
|
||||||
if m[1] and m[2] then arr.push d1..d2
|
if m[1] and m[2] then arr.push( d1..d2 )
|
||||||
elsif m[1] then arr.push d1..-1
|
elsif m[1] then arr.push( d1..-1 )
|
||||||
elsif m[2] then arr.push -d2..-1
|
elsif m[2] then arr.push( -d2..-1 )
|
||||||
else
|
else
|
||||||
raise HTTPHeaderSyntaxError, 'range is not specified'
|
raise HTTPHeaderSyntaxError, 'range is not specified'
|
||||||
end
|
end
|
||||||
|
@ -915,21 +920,22 @@ module Net
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
###
|
###
|
||||||
### request
|
### request
|
||||||
###
|
###
|
||||||
|
|
||||||
net_private {
|
class HTTPGenericRequest
|
||||||
|
|
||||||
class HTTPRequest
|
|
||||||
|
|
||||||
include ::Net::NetPrivate::HTTPHeader
|
include ::Net::NetPrivate::HTTPHeader
|
||||||
|
|
||||||
def initialize( path, uhead = nil )
|
def initialize( m, reqbody, resbody, path, uhead = nil )
|
||||||
|
@method = m
|
||||||
|
@request_has_body = reqbody
|
||||||
|
@response_has_body = resbody
|
||||||
@path = path
|
@path = path
|
||||||
|
@response = nil
|
||||||
|
|
||||||
@header = tmp = {}
|
@header = tmp = {}
|
||||||
return unless uhead
|
return unless uhead
|
||||||
uhead.each do |k,v|
|
uhead.each do |k,v|
|
||||||
|
@ -940,11 +946,9 @@ module Net
|
||||||
tmp[ key ] = v.strip
|
tmp[ key ] = v.strip
|
||||||
end
|
end
|
||||||
tmp['accept'] ||= '*/*'
|
tmp['accept'] ||= '*/*'
|
||||||
|
|
||||||
@socket = nil
|
|
||||||
@response = nil
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
attr_reader :method
|
||||||
attr_reader :path
|
attr_reader :path
|
||||||
attr_reader :response
|
attr_reader :response
|
||||||
|
|
||||||
|
@ -952,10 +956,16 @@ module Net
|
||||||
"\#<#{type}>"
|
"\#<#{type}>"
|
||||||
end
|
end
|
||||||
|
|
||||||
def body_exist?
|
def request_body_permitted?
|
||||||
type::HAS_BODY
|
@request_has_body
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def response_body_permitted?
|
||||||
|
@response_has_body
|
||||||
|
end
|
||||||
|
|
||||||
|
alias body_exist? response_body_permitted?
|
||||||
|
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
|
@ -963,108 +973,87 @@ module Net
|
||||||
# write
|
# write
|
||||||
#
|
#
|
||||||
|
|
||||||
def exec( sock, ver, path )
|
def exec( sock, ver, path, body, &block )
|
||||||
ready( sock ) {
|
if body then
|
||||||
request ver, path
|
check_body_premitted
|
||||||
}
|
check_arg_b body, block
|
||||||
@response
|
sendreq_with_body sock, ver, path, body, &block
|
||||||
end
|
else
|
||||||
|
check_arg_n body
|
||||||
def ready( sock )
|
sendreq_no_body sock, ver, path
|
||||||
@response = nil
|
|
||||||
@socket = sock
|
|
||||||
yield
|
|
||||||
@response = get_response
|
|
||||||
@socket = nil
|
|
||||||
end
|
|
||||||
|
|
||||||
def request( ver, path )
|
|
||||||
@socket.writeline sprintf('%s %s HTTP/%s', type::METHOD, path, ver)
|
|
||||||
canonical_each do |k,v|
|
|
||||||
@socket.writeline k + ': ' + v
|
|
||||||
end
|
end
|
||||||
@socket.writeline ''
|
@response = r = get_response( sock )
|
||||||
|
r
|
||||||
|
end
|
||||||
|
|
||||||
|
def check_body_premitted
|
||||||
|
request_body_permitted? or
|
||||||
|
raise ArgumentError, 'HTTP request body is not premitted'
|
||||||
|
end
|
||||||
|
|
||||||
|
def check_arg_b( data, block )
|
||||||
|
if data and block then
|
||||||
|
raise ArgumentError, 'both of data and block given'
|
||||||
|
end
|
||||||
|
unless data or block then
|
||||||
|
raise ArgumentError, 'str or block required'
|
||||||
|
end
|
||||||
|
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 )
|
||||||
|
if block_given? then
|
||||||
|
ac = Accumulator.new
|
||||||
|
yield ac # must be yield, DO NOT USE block.call
|
||||||
|
data = ac.terminate
|
||||||
|
else
|
||||||
|
data = body
|
||||||
|
end
|
||||||
|
@header['content-length'] = data.size.to_s
|
||||||
|
@header.delete 'transfer-encoding'
|
||||||
|
|
||||||
|
request sock, ver, path
|
||||||
|
sock.write data
|
||||||
|
end
|
||||||
|
|
||||||
|
def request( sock, ver, path )
|
||||||
|
sock.writeline sprintf('%s %s HTTP/%s', @method, path, ver)
|
||||||
|
canonical_each do |k,v|
|
||||||
|
sock.writeline k + ': ' + v
|
||||||
|
end
|
||||||
|
sock.writeline ''
|
||||||
end
|
end
|
||||||
|
|
||||||
#
|
#
|
||||||
# read
|
# read
|
||||||
#
|
#
|
||||||
|
|
||||||
def get_response
|
def get_response( sock )
|
||||||
begin
|
begin
|
||||||
resp = read_response
|
resp = ::Net::NetPrivate::HTTPResponse.new_from_socket(sock,
|
||||||
|
response_body_permitted?)
|
||||||
end while ContinueCode === resp
|
end while ContinueCode === resp
|
||||||
resp
|
resp
|
||||||
end
|
end
|
||||||
|
|
||||||
def read_response
|
|
||||||
resp = get_resline
|
|
||||||
|
|
||||||
while true do
|
|
||||||
line = @socket.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]
|
|
||||||
line = m.post_match
|
|
||||||
if resp.key? nm then
|
|
||||||
resp[nm] << ', ' << line
|
|
||||||
else
|
|
||||||
resp[nm] = line
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
resp
|
|
||||||
end
|
|
||||||
|
|
||||||
def get_resline
|
|
||||||
str = @socket.readline
|
|
||||||
m = /\AHTTP(?:\/(\d+\.\d+))?\s+(\d\d\d)\s*(.*)\z/i.match( str )
|
|
||||||
m or raise HTTPBadResponse, "wrong status line: #{str}"
|
|
||||||
httpver = m[1]
|
|
||||||
status = m[2]
|
|
||||||
discrip = m[3]
|
|
||||||
|
|
||||||
::Net::NetPrivate::HTTPResponse.new(
|
|
||||||
status, discrip, @socket, type::HAS_BODY, httpver )
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
class HTTPRequestWithBody < HTTPRequest
|
class HTTPRequest < HTTPGenericRequest
|
||||||
|
|
||||||
private
|
def initialize( path, uhead = nil )
|
||||||
|
super type::METHOD,
|
||||||
def exec( sock, ver, path, str = nil )
|
type::REQUEST_HAS_BODY,
|
||||||
check_arg str, block_given?
|
type::RESPONSE_HAS_BODY,
|
||||||
|
path, uhead
|
||||||
if block_given? then
|
|
||||||
ac = Accumulator.new
|
|
||||||
yield ac # must be yield, DO NOT USE block.call
|
|
||||||
data = ac.terminate
|
|
||||||
else
|
|
||||||
data = str
|
|
||||||
end
|
|
||||||
@header['content-length'] = data.size.to_s
|
|
||||||
@header.delete 'transfer-encoding'
|
|
||||||
|
|
||||||
ready( sock ) {
|
|
||||||
request ver, path
|
|
||||||
@socket.write data
|
|
||||||
}
|
|
||||||
@response
|
|
||||||
end
|
|
||||||
|
|
||||||
def check_arg( data, blkp )
|
|
||||||
if data and blkp then
|
|
||||||
raise ArgumentError, 'both of data and block given'
|
|
||||||
end
|
|
||||||
unless data or blkp then
|
|
||||||
raise ArgumentError, 'str or block required'
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
@ -1099,23 +1088,27 @@ module Net
|
||||||
class HTTP
|
class HTTP
|
||||||
|
|
||||||
class Get < ::Net::NetPrivate::HTTPRequest
|
class Get < ::Net::NetPrivate::HTTPRequest
|
||||||
HAS_BODY = true
|
|
||||||
METHOD = 'GET'
|
METHOD = 'GET'
|
||||||
|
REQUEST_HAS_BODY = false
|
||||||
|
RESPONSE_HAS_BODY = true
|
||||||
end
|
end
|
||||||
|
|
||||||
class Head < ::Net::NetPrivate::HTTPRequest
|
class Head < ::Net::NetPrivate::HTTPRequest
|
||||||
HAS_BODY = false
|
|
||||||
METHOD = 'HEAD'
|
METHOD = 'HEAD'
|
||||||
|
REQUEST_HAS_BODY = false
|
||||||
|
RESPONSE_HAS_BODY = false
|
||||||
end
|
end
|
||||||
|
|
||||||
class Post < ::Net::NetPrivate::HTTPRequestWithBody
|
class Post < ::Net::NetPrivate::HTTPRequest
|
||||||
HAS_BODY = true
|
|
||||||
METHOD = 'POST'
|
METHOD = 'POST'
|
||||||
|
REQUEST_HAS_BODY = true
|
||||||
|
RESPONSE_HAS_BODY = true
|
||||||
end
|
end
|
||||||
|
|
||||||
class Put < ::Net::NetPrivate::HTTPRequestWithBody
|
class Put < ::Net::NetPrivate::HTTPRequest
|
||||||
HAS_BODY = true
|
|
||||||
METHOD = 'PUT'
|
METHOD = 'PUT'
|
||||||
|
REQUEST_HAS_BODY = true
|
||||||
|
RESPONSE_HAS_BODY = true
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
@ -1184,6 +1177,45 @@ module Net
|
||||||
'505' => HTTPVersionNotSupported
|
'505' => HTTPVersionNotSupported
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class << self
|
||||||
|
|
||||||
|
def new_from_socket( sock, hasbody )
|
||||||
|
resp = readnew( sock, hasbody )
|
||||||
|
|
||||||
|
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]
|
||||||
|
line = m.post_match
|
||||||
|
if resp.key? nm then
|
||||||
|
resp[nm] << ', ' << line
|
||||||
|
else
|
||||||
|
resp[nm] = 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 )
|
def initialize( stat, msg, sock, be, hv )
|
||||||
code = CODE_TO_OBJ[stat] ||
|
code = CODE_TO_OBJ[stat] ||
|
||||||
CODE_CLASS_TO_OBJ[stat[0,1]] ||
|
CODE_CLASS_TO_OBJ[stat[0,1]] ||
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
=begin
|
=begin
|
||||||
|
|
||||||
= net/pop.rb version 1.2.1
|
= net/pop.rb version 1.2.2
|
||||||
|
|
||||||
Copyright (c) 1999-2001 Yukihiro Matsumoto
|
Copyright (c) 1999-2001 Yukihiro Matsumoto
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
=begin
|
=begin
|
||||||
|
|
||||||
= net/protocol.rb version 1.2.1
|
= net/protocol.rb version 1.2.2
|
||||||
|
|
||||||
Copyright (c) 1999-2001 Yukihiro Matsumoto
|
Copyright (c) 1999-2001 Yukihiro Matsumoto
|
||||||
|
|
||||||
|
@ -32,7 +32,7 @@ module Net
|
||||||
|
|
||||||
class Protocol
|
class Protocol
|
||||||
|
|
||||||
Version = '1.2.1'
|
Version = '1.2.2'
|
||||||
|
|
||||||
class << self
|
class << self
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
=begin
|
=begin
|
||||||
|
|
||||||
= net/smtp.rb version 1.2.1
|
= net/smtp.rb version 1.2.2
|
||||||
|
|
||||||
Copyright (c) 1999-2001 Yukihiro Matsumoto
|
Copyright (c) 1999-2001 Yukihiro Matsumoto
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue