1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00
* 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:
aamine 2001-07-03 18:13:13 +00:00
parent fc1f22d5a8
commit fa20d931bc
5 changed files with 160 additions and 122 deletions

View file

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

View file

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

View file

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

View file

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

View file

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