mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* lib/net/http.rb (GenericRequest#initialize): check if path begins with '/'.
* lib/net/http.rb: def m( arg ) -> def m(arg) git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@5344 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
d993e38f18
commit
ef70baa40a
2 changed files with 142 additions and 152 deletions
|
@ -1,3 +1,10 @@
|
||||||
|
Mon Dec 29 20:08:17 2003 Minero Aoki <aamine@loveruby.net>
|
||||||
|
|
||||||
|
* lib/net/http.rb (GenericRequest#initialize): check if path
|
||||||
|
begins with '/'.
|
||||||
|
|
||||||
|
* lib/net/http.rb: def m( arg ) -> def m(arg)
|
||||||
|
|
||||||
Mon Dec 29 12:51:02 2003 Dave Thomas <dave@pragprog.com>
|
Mon Dec 29 12:51:02 2003 Dave Thomas <dave@pragprog.com>
|
||||||
|
|
||||||
* eval.c: Add RDoc for Kernel global functions.
|
* eval.c: Add RDoc for Kernel global functions.
|
||||||
|
|
287
lib/net/http.rb
287
lib/net/http.rb
|
@ -160,13 +160,13 @@ module Net # :nodoc:
|
||||||
# allows you to use 1.2 features again.
|
# allows you to use 1.2 features again.
|
||||||
#
|
#
|
||||||
# # example
|
# # example
|
||||||
# Net::HTTP.start { |http1| ...(http1 has 1.2 features)... }
|
# Net::HTTP.start {|http1| ...(http1 has 1.2 features)... }
|
||||||
#
|
#
|
||||||
# Net::HTTP.version_1_1
|
# Net::HTTP.version_1_1
|
||||||
# Net::HTTP.start { |http2| ...(http2 has 1.1 features)... }
|
# Net::HTTP.start {|http2| ...(http2 has 1.1 features)... }
|
||||||
#
|
#
|
||||||
# Net::HTTP.version_1_2
|
# Net::HTTP.version_1_2
|
||||||
# Net::HTTP.start { |http3| ...(http3 has 1.2 features)... }
|
# Net::HTTP.start {|http3| ...(http3 has 1.2 features)... }
|
||||||
#
|
#
|
||||||
# This function is NOT thread-safe.
|
# This function is NOT thread-safe.
|
||||||
#
|
#
|
||||||
|
@ -213,7 +213,7 @@ module Net # :nodoc:
|
||||||
alias is_version_1_2? version_1_2? #:nodoc:
|
alias is_version_1_2? version_1_2? #:nodoc:
|
||||||
end
|
end
|
||||||
|
|
||||||
def HTTP.setimplversion( obj ) #:nodoc:
|
def HTTP.setimplversion(obj) #:nodoc:
|
||||||
f = @@newimpl
|
f = @@newimpl
|
||||||
obj.instance_eval { @newimpl = f }
|
obj.instance_eval { @newimpl = f }
|
||||||
end
|
end
|
||||||
|
@ -234,7 +234,7 @@ module Net # :nodoc:
|
||||||
#
|
#
|
||||||
# Net::HTTP.get_print('www.example.com', '/index.html')
|
# Net::HTTP.get_print('www.example.com', '/index.html')
|
||||||
#
|
#
|
||||||
def HTTP.get_print( arg1, arg2 = nil, port = nil )
|
def HTTP.get_print(arg1, arg2 = nil, port = nil)
|
||||||
if arg2
|
if arg2
|
||||||
addr, path = arg1, arg2
|
addr, path = arg1, arg2
|
||||||
else
|
else
|
||||||
|
@ -259,7 +259,7 @@ module Net # :nodoc:
|
||||||
#
|
#
|
||||||
# print Net::HTTP.get('www.example.com', '/index.html')
|
# print Net::HTTP.get('www.example.com', '/index.html')
|
||||||
#
|
#
|
||||||
def HTTP.get( arg1, arg2 = nil, arg3 = nil )
|
def HTTP.get(arg1, arg2 = nil, arg3 = nil)
|
||||||
get_response(arg1,arg2,arg3).body
|
get_response(arg1,arg2,arg3).body
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -275,7 +275,7 @@ module Net # :nodoc:
|
||||||
# res = Net::HTTP.get_response('www.example.com', '/index.html')
|
# res = Net::HTTP.get_response('www.example.com', '/index.html')
|
||||||
# print res.body
|
# print res.body
|
||||||
#
|
#
|
||||||
def HTTP.get_response( arg1, arg2 = nil, arg3 = nil )
|
def HTTP.get_response(arg1, arg2 = nil, arg3 = nil)
|
||||||
if arg2
|
if arg2
|
||||||
get_by_path(arg1, arg2, arg3)
|
get_by_path(arg1, arg2, arg3)
|
||||||
else
|
else
|
||||||
|
@ -283,14 +283,14 @@ module Net # :nodoc:
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def HTTP.get_by_path( addr, path, port = nil ) #:nodoc:
|
def HTTP.get_by_path(addr, path, port = nil) #:nodoc:
|
||||||
new(addr, port || HTTP.default_port).start {|http|
|
new(addr, port || HTTP.default_port).start {|http|
|
||||||
return http.request(Get.new(path))
|
return http.request(Get.new(path))
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
private_class_method :get_by_path
|
private_class_method :get_by_path
|
||||||
|
|
||||||
def HTTP.get_by_uri( uri ) #:nodoc:
|
def HTTP.get_by_uri(uri) #:nodoc:
|
||||||
# Should we allow this?
|
# Should we allow this?
|
||||||
# uri = URI.parse(uri) unless uri.respond_to?(:host)
|
# uri = URI.parse(uri) unless uri.respond_to?(:host)
|
||||||
new(uri.host, uri.port).start {|http|
|
new(uri.host, uri.port).start {|http|
|
||||||
|
@ -320,7 +320,7 @@ module Net # :nodoc:
|
||||||
# is the return value of the block. If no block is given, the
|
# is the return value of the block. If no block is given, the
|
||||||
# return value of this method is the newly created Net::HTTP object
|
# return value of this method is the newly created Net::HTTP object
|
||||||
# itself, and the caller is responsible for closing it upon completion.
|
# itself, and the caller is responsible for closing it upon completion.
|
||||||
def start( address, port = nil, p_addr = nil, p_port = nil, p_user = nil, p_pass = nil, &block ) # :yield: +http+
|
def start(address, port = nil, p_addr = nil, p_port = nil, p_user = nil, p_pass = nil, &block) # :yield: +http+
|
||||||
new(address, port, p_addr, p_port, p_user, p_pass).start(&block)
|
new(address, port, p_addr, p_port, p_user, p_pass).start(&block)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -329,7 +329,7 @@ module Net # :nodoc:
|
||||||
# Creates a new Net::HTTP object.
|
# Creates a new Net::HTTP object.
|
||||||
# If +proxy_addr+ is given, creates an Net::HTTP object with proxy support.
|
# If +proxy_addr+ is given, creates an Net::HTTP object with proxy support.
|
||||||
# This method does not open the TCP connection.
|
# This method does not open the TCP connection.
|
||||||
def new( address, port = nil, p_addr = nil, p_port = nil, p_user = nil, p_pass = nil )
|
def new(address, port = nil, p_addr = nil, p_port = nil, p_user = nil, p_pass = nil)
|
||||||
obj = Proxy(p_addr, p_port, p_user, p_pass).newobj(address, port)
|
obj = Proxy(p_addr, p_port, p_user, p_pass).newobj(address, port)
|
||||||
setimplversion obj
|
setimplversion obj
|
||||||
obj
|
obj
|
||||||
|
@ -338,9 +338,9 @@ module Net # :nodoc:
|
||||||
|
|
||||||
# Creates a new Net::HTTP object for the specified +address+.
|
# Creates a new Net::HTTP object for the specified +address+.
|
||||||
# This method does not open the TCP connection.
|
# This method does not open the TCP connection.
|
||||||
def initialize( address, port = nil )
|
def initialize(address, port = nil)
|
||||||
@address = address
|
@address = address
|
||||||
@port = port || HTTP.default_port
|
@port = (port || HTTP.default_port)
|
||||||
|
|
||||||
@curr_http_version = HTTPVersion
|
@curr_http_version = HTTPVersion
|
||||||
@seems_1_0_server = false
|
@seems_1_0_server = false
|
||||||
|
@ -367,7 +367,7 @@ module Net # :nodoc:
|
||||||
# http.set_debug_output $stderr
|
# http.set_debug_output $stderr
|
||||||
# http.start { .... }
|
# http.start { .... }
|
||||||
#
|
#
|
||||||
def set_debug_output( output )
|
def set_debug_output(output)
|
||||||
warn 'Net::HTTP#set_debug_output called after HTTP started' if started?
|
warn 'Net::HTTP#set_debug_output called after HTTP started' if started?
|
||||||
@debug_output = output
|
@debug_output = output
|
||||||
end
|
end
|
||||||
|
@ -389,7 +389,7 @@ module Net # :nodoc:
|
||||||
attr_reader :read_timeout
|
attr_reader :read_timeout
|
||||||
|
|
||||||
# Setter for the read_timeout attribute.
|
# Setter for the read_timeout attribute.
|
||||||
def read_timeout=( sec )
|
def read_timeout=(sec)
|
||||||
@socket.read_timeout = sec if @socket
|
@socket.read_timeout = sec if @socket
|
||||||
@read_timeout = sec
|
@read_timeout = sec
|
||||||
end
|
end
|
||||||
|
@ -481,9 +481,8 @@ module Net # :nodoc:
|
||||||
# :
|
# :
|
||||||
# }
|
# }
|
||||||
#
|
#
|
||||||
def HTTP.Proxy( p_addr, p_port = nil, p_user = nil, p_pass = nil )
|
def HTTP.Proxy(p_addr, p_port = nil, p_user = nil, p_pass = nil)
|
||||||
return self unless p_addr
|
return self unless p_addr
|
||||||
|
|
||||||
delta = ProxyDelta
|
delta = ProxyDelta
|
||||||
proxyclass = Class.new(self)
|
proxyclass = Class.new(self)
|
||||||
proxyclass.module_eval {
|
proxyclass.module_eval {
|
||||||
|
@ -550,15 +549,13 @@ module Net # :nodoc:
|
||||||
port
|
port
|
||||||
end
|
end
|
||||||
|
|
||||||
def edit_path( path )
|
def edit_path(path)
|
||||||
path
|
path
|
||||||
end
|
end
|
||||||
|
|
||||||
module ProxyDelta #:nodoc: internal use only
|
module ProxyDelta #:nodoc: internal use only
|
||||||
private
|
private
|
||||||
|
|
||||||
# with proxy
|
|
||||||
|
|
||||||
def conn_address
|
def conn_address
|
||||||
proxy_address()
|
proxy_address()
|
||||||
end
|
end
|
||||||
|
@ -567,7 +564,7 @@ module Net # :nodoc:
|
||||||
proxy_port()
|
proxy_port()
|
||||||
end
|
end
|
||||||
|
|
||||||
def edit_path( path )
|
def edit_path(path)
|
||||||
'http://' + addr_port() + path
|
'http://' + addr_port() + path
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -613,7 +610,7 @@ module Net # :nodoc:
|
||||||
# end
|
# end
|
||||||
# }
|
# }
|
||||||
#
|
#
|
||||||
def get( path, initheader = nil, dest = nil, &block ) # :yield: +body_segment+
|
def get(path, initheader = nil, dest = nil, &block) # :yield: +body_segment+
|
||||||
res = nil
|
res = nil
|
||||||
request(Get.new(path, initheader)) {|r|
|
request(Get.new(path, initheader)) {|r|
|
||||||
r.read_body dest, &block
|
r.read_body dest, &block
|
||||||
|
@ -643,7 +640,7 @@ module Net # :nodoc:
|
||||||
# }
|
# }
|
||||||
# p response['content-type']
|
# p response['content-type']
|
||||||
#
|
#
|
||||||
def head( path, initheader = nil )
|
def head(path, initheader = nil)
|
||||||
res = request(Head.new(path, initheader))
|
res = request(Head.new(path, initheader))
|
||||||
res.value unless @newimpl
|
res.value unless @newimpl
|
||||||
res
|
res
|
||||||
|
@ -687,7 +684,8 @@ module Net # :nodoc:
|
||||||
# f.write str
|
# f.write str
|
||||||
# end
|
# end
|
||||||
# }
|
# }
|
||||||
def post( path, data, initheader = nil, dest = nil, &block ) # :yield: +body_segment+
|
#
|
||||||
|
def post(path, data, initheader = nil, dest = nil, &block) # :yield: +body_segment+
|
||||||
res = nil
|
res = nil
|
||||||
request(Post.new(path, initheader), data) {|r|
|
request(Post.new(path, initheader), data) {|r|
|
||||||
r.read_body dest, &block
|
r.read_body dest, &block
|
||||||
|
@ -701,9 +699,9 @@ module Net # :nodoc:
|
||||||
res
|
res
|
||||||
end
|
end
|
||||||
|
|
||||||
def put( path, data, initheader = nil ) #:nodoc:
|
def put(path, data, initheader = nil) #:nodoc:
|
||||||
res = request(Put.new(path, initheader), data)
|
res = request(Put.new(path, initheader), data)
|
||||||
@newimpl or res.value
|
res.value unless @newimpl
|
||||||
res
|
res
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -732,8 +730,8 @@ module Net # :nodoc:
|
||||||
# end
|
# end
|
||||||
# }
|
# }
|
||||||
#
|
#
|
||||||
def request_get( path, initheader = nil, &block ) # :yield: +response+
|
def request_get(path, initheader = nil, &block) # :yield: +response+
|
||||||
request Get.new(path, initheader), &block
|
request(Get.new(path, initheader), &block)
|
||||||
end
|
end
|
||||||
|
|
||||||
# Sends a HEAD request to the +path+ and gets a response,
|
# Sends a HEAD request to the +path+ and gets a response,
|
||||||
|
@ -746,8 +744,8 @@ module Net # :nodoc:
|
||||||
# response = http.request_head('/index.html')
|
# response = http.request_head('/index.html')
|
||||||
# p response['content-type']
|
# p response['content-type']
|
||||||
#
|
#
|
||||||
def request_head( path, initheader = nil, &block )
|
def request_head(path, initheader = nil, &block)
|
||||||
request Head.new(path, initheader), &block
|
request(Head.new(path, initheader), &block)
|
||||||
end
|
end
|
||||||
|
|
||||||
# Sends a POST request to the +path+ and gets a response,
|
# Sends a POST request to the +path+ and gets a response,
|
||||||
|
@ -775,11 +773,12 @@ module Net # :nodoc:
|
||||||
# print str
|
# print str
|
||||||
# end
|
# end
|
||||||
# }
|
# }
|
||||||
def request_post( path, data, initheader = nil, &block ) # :yield: +response+
|
#
|
||||||
|
def request_post(path, data, initheader = nil, &block) # :yield: +response+
|
||||||
request Post.new(path, initheader), data, &block
|
request Post.new(path, initheader), data, &block
|
||||||
end
|
end
|
||||||
|
|
||||||
def request_put( path, data, initheader = nil, &block ) #:nodoc:
|
def request_put(path, data, initheader = nil, &block) #:nodoc:
|
||||||
request Put.new(path, initheader), data, &block
|
request Put.new(path, initheader), data, &block
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -799,7 +798,7 @@ module Net # :nodoc:
|
||||||
# response = http.send_request('GET', '/index.html')
|
# response = http.send_request('GET', '/index.html')
|
||||||
# puts response.body
|
# puts response.body
|
||||||
#
|
#
|
||||||
def send_request( name, path, data = nil, header = nil )
|
def send_request(name, path, data = nil, header = nil)
|
||||||
r = HTTPGenericRequest.new(name,(data ? true : false),true,path,header)
|
r = HTTPGenericRequest.new(name,(data ? true : false),true,path,header)
|
||||||
request r, data
|
request r, data
|
||||||
end
|
end
|
||||||
|
@ -816,7 +815,8 @@ module Net # :nodoc:
|
||||||
# Returns a HTTPResponse object.
|
# Returns a HTTPResponse object.
|
||||||
#
|
#
|
||||||
# This method never raises Net::* exceptions.
|
# This method never raises Net::* exceptions.
|
||||||
def request( req, body = nil, &block ) # :yield: +response+
|
#
|
||||||
|
def request(req, body = nil, &block) # :yield: +response+
|
||||||
unless started?
|
unless started?
|
||||||
start {
|
start {
|
||||||
req['connection'] = 'close'
|
req['connection'] = 'close'
|
||||||
|
@ -826,15 +826,15 @@ module Net # :nodoc:
|
||||||
if proxy_user()
|
if proxy_user()
|
||||||
req.proxy_basic_auth proxy_user(), proxy_pass()
|
req.proxy_basic_auth proxy_user(), proxy_pass()
|
||||||
end
|
end
|
||||||
|
|
||||||
begin_transport req
|
begin_transport req
|
||||||
req.exec @socket, @curr_http_version, edit_path(req.path), body
|
req.exec @socket, @curr_http_version, edit_path(req.path), body
|
||||||
begin
|
begin
|
||||||
res = HTTPResponse.read_new(@socket)
|
res = HTTPResponse.read_new(@socket)
|
||||||
end while HTTPContinue === res
|
end while HTTPContinue === res
|
||||||
res.reading_body(@socket, req.response_body_permitted?) {
|
res.reading_body(@socket, req.response_body_permitted?) {
|
||||||
yield res if block_given?
|
yield res if block_given?
|
||||||
}
|
}
|
||||||
end_transport req, res
|
end_transport req, res
|
||||||
|
|
||||||
res
|
res
|
||||||
|
@ -842,7 +842,7 @@ module Net # :nodoc:
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def begin_transport( req )
|
def begin_transport(req)
|
||||||
if @socket.closed?
|
if @socket.closed?
|
||||||
@socket.reopen @open_timeout
|
@socket.reopen @open_timeout
|
||||||
on_connect
|
on_connect
|
||||||
|
@ -856,13 +856,12 @@ module Net # :nodoc:
|
||||||
req['host'] = addr_port()
|
req['host'] = addr_port()
|
||||||
end
|
end
|
||||||
|
|
||||||
def end_transport( req, res )
|
def end_transport(req, res)
|
||||||
@curr_http_version = res.http_version
|
@curr_http_version = res.http_version
|
||||||
|
|
||||||
if not res.body and @close_on_empty_response
|
if not res.body and @close_on_empty_response
|
||||||
D 'Conn close'
|
D 'Conn close'
|
||||||
@socket.close
|
@socket.close
|
||||||
elsif keep_alive? req, res
|
elsif keep_alive?(req, res)
|
||||||
D 'Conn keep-alive'
|
D 'Conn keep-alive'
|
||||||
if @socket.closed?
|
if @socket.closed?
|
||||||
D 'Conn (but seems 1.0 server)'
|
D 'Conn (but seems 1.0 server)'
|
||||||
|
@ -874,17 +873,14 @@ module Net # :nodoc:
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def keep_alive?( req, res )
|
def keep_alive?(req, res)
|
||||||
/close/i === req['connection'].to_s and return false
|
return false if /close/i =~ req['connection'].to_s
|
||||||
@seems_1_0_server and return false
|
return false if @seems_1_0_server
|
||||||
|
return true if /keep-alive/i =~ res['connection'].to_s
|
||||||
/keep-alive/i === res['connection'].to_s and return true
|
return false if /close/i =~ res['connection'].to_s
|
||||||
/close/i === res['connection'].to_s and return false
|
return true if /keep-alive/i =~ res['proxy-connection'].to_s
|
||||||
/keep-alive/i === res['proxy-connection'].to_s and return true
|
return false if /close/i =~ res['proxy-connection'].to_s
|
||||||
/close/i === res['proxy-connection'].to_s and return false
|
(@curr_http_version == '1.1')
|
||||||
|
|
||||||
@curr_http_version == '1.1' and return true
|
|
||||||
false
|
|
||||||
end
|
end
|
||||||
|
|
||||||
#
|
#
|
||||||
|
@ -897,11 +893,10 @@ module Net # :nodoc:
|
||||||
address + (port == HTTP.default_port ? '' : ":#{port}")
|
address + (port == HTTP.default_port ? '' : ":#{port}")
|
||||||
end
|
end
|
||||||
|
|
||||||
def D( msg )
|
def D(msg)
|
||||||
if @debug_output
|
return unless @debug_output
|
||||||
@debug_output << msg
|
@debug_output << msg
|
||||||
@debug_output << "\n"
|
@debug_output << "\n"
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
@ -926,46 +921,46 @@ module Net # :nodoc:
|
||||||
|
|
||||||
# Returns the header field corresponding to the case-insensitive key.
|
# Returns the header field corresponding to the case-insensitive key.
|
||||||
# For example, a key of "Content-Type" might return "text/html"
|
# For example, a key of "Content-Type" might return "text/html"
|
||||||
def []( key )
|
def [](key)
|
||||||
@header[key.downcase]
|
@header[key.downcase]
|
||||||
end
|
end
|
||||||
|
|
||||||
# Sets the header field corresponding to the case-insensitive key.
|
# Sets the header field corresponding to the case-insensitive key.
|
||||||
def []=( key, val )
|
def []=(key, val)
|
||||||
@header[key.downcase] = val
|
@header[key.downcase] = val
|
||||||
end
|
end
|
||||||
|
|
||||||
# Returns the header field corresponding to the case-insensitive key.
|
# Returns the header field corresponding to the case-insensitive key.
|
||||||
# Returns the default value +args+, or the result of the block, or nil,
|
# Returns the default value +args+, or the result of the block, or nil,
|
||||||
# if there's no header field named key. See Hash#fetch
|
# if there's no header field named key. See Hash#fetch
|
||||||
def fetch( key, *args, &block ) # :yield: +key+
|
def fetch(key, *args, &block) #:yield: +key+
|
||||||
@header.fetch(key.downcase, *args, &block)
|
@header.fetch(key.downcase, *args, &block)
|
||||||
end
|
end
|
||||||
|
|
||||||
# Iterates for each header names and values.
|
# Iterates for each header names and values.
|
||||||
def each_header( &block ) # :yield: +key+, +value+
|
def each_header(&block) #:yield: +key+, +value+
|
||||||
@header.each(&block)
|
@header.each(&block)
|
||||||
end
|
end
|
||||||
|
|
||||||
alias each each_header
|
alias each each_header
|
||||||
|
|
||||||
# Iterates for each header names.
|
# Iterates for each header names.
|
||||||
def each_key( &block ) # :yield: +key+
|
def each_key(&block) #:yield: +key+
|
||||||
@header.each_key(&block)
|
@header.each_key(&block)
|
||||||
end
|
end
|
||||||
|
|
||||||
# Iterates for each header values.
|
# Iterates for each header values.
|
||||||
def each_value( &block ) # :yield: +value+
|
def each_value(&block) #:yield: +value+
|
||||||
@header.each_value(&block)
|
@header.each_value(&block)
|
||||||
end
|
end
|
||||||
|
|
||||||
# Removes a header field.
|
# Removes a header field.
|
||||||
def delete( key )
|
def delete(key)
|
||||||
@header.delete(key.downcase)
|
@header.delete(key.downcase)
|
||||||
end
|
end
|
||||||
|
|
||||||
# true if +key+ header exists.
|
# true if +key+ header exists.
|
||||||
def key?( key )
|
def key?(key)
|
||||||
@header.key?(key.downcase)
|
@header.key?(key.downcase)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -974,18 +969,19 @@ module Net # :nodoc:
|
||||||
@header.dup
|
@header.dup
|
||||||
end
|
end
|
||||||
|
|
||||||
# As for #each_header, except the keys are provided in
|
# As for #each_header, except the keys are provided in capitalized form.
|
||||||
# canonical form, which is to say, capitalized.
|
def each_capitalized
|
||||||
def canonical_each
|
|
||||||
@header.each do |k,v|
|
@header.each do |k,v|
|
||||||
yield canonical(k), v
|
yield capitalize(k), v
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def canonical( k )
|
alias canonical_each each_capitalized
|
||||||
|
|
||||||
|
def capitalize(k)
|
||||||
k.split(/-/).map {|i| i.capitalize }.join('-')
|
k.split(/-/).map {|i| i.capitalize }.join('-')
|
||||||
end
|
end
|
||||||
private :canonical
|
private :capitalize
|
||||||
|
|
||||||
# Returns a Range object which represents Range: header field,
|
# Returns a Range object which represents Range: header field,
|
||||||
# or +nil+ if there is no such header.
|
# or +nil+ if there is no such header.
|
||||||
|
@ -1007,32 +1003,27 @@ module Net # :nodoc:
|
||||||
|
|
||||||
# Set Range: header from Range (arg r) or beginning index and
|
# Set Range: header from Range (arg r) or beginning index and
|
||||||
# length from it (arg i&len).
|
# length from it (arg i&len).
|
||||||
def range=( r, fin = nil )
|
def range=(r, fin = nil)
|
||||||
r = (r ... r + fin) if fin
|
r = (r ... r + fin) if fin
|
||||||
|
|
||||||
case r
|
case r
|
||||||
when Numeric
|
when Numeric
|
||||||
s = r > 0 ? "0-#{r - 1}" : "-#{-r}"
|
rangestr = (r > 0 ? "0-#{r.to_i - 1}" : "-#{-r.to_i}")
|
||||||
when Range
|
when Range
|
||||||
first = r.first
|
first = r.first
|
||||||
last = r.last
|
last = r.last
|
||||||
if r.exclude_end?
|
last -= 1 if r.exclude_end?
|
||||||
last -= 1
|
|
||||||
end
|
|
||||||
|
|
||||||
if last == -1
|
if last == -1
|
||||||
s = first > 0 ? "#{first}-" : "-#{-first}"
|
rangestr = (first > 0 ? "#{first}-" : "-#{-first}")
|
||||||
else
|
else
|
||||||
first >= 0 or raise HTTPHeaderSyntaxError, 'range.first is negative'
|
raise HTTPHeaderSyntaxError, 'range.first is negative' if first < 0
|
||||||
last > 0 or raise HTTPHeaderSyntaxError, 'range.last is negative'
|
raise HTTPHeaderSyntaxError, 'range.last is negative' if last < 0
|
||||||
first < last or raise HTTPHeaderSyntaxError, 'must be .first < .last'
|
raise HTTPHeaderSyntaxError, 'must be .first < .last' if first > last
|
||||||
s = "#{first}-#{last}"
|
rangestr = "#{first}-#{last}"
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
raise TypeError, 'Range/Integer is required'
|
raise TypeError, 'Range/Integer is required'
|
||||||
end
|
end
|
||||||
|
@header['range'] = "bytes=#{rangestr}"
|
||||||
@header['range'] = "bytes=#{s}"
|
|
||||||
r
|
r
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -1041,10 +1032,9 @@ module Net # :nodoc:
|
||||||
# Returns an Integer object which represents the Content-Length: header field
|
# Returns an Integer object which represents the Content-Length: header field
|
||||||
# or +nil+ if that field is not provided.
|
# or +nil+ if that field is not provided.
|
||||||
def content_length
|
def content_length
|
||||||
s = @header['content-length'] or return nil
|
len = @header['content-length'].to_s.slice(/\d+/) or
|
||||||
m = /\d+/.match(s) or
|
raise HTTPHeaderSyntaxError, 'wrong Content-Length format'
|
||||||
raise HTTPHeaderSyntaxError, 'wrong Content-Length format'
|
len.to_i
|
||||||
m[0].to_i
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# Returns "true" if the "transfer-encoding" header is present and
|
# Returns "true" if the "transfer-encoding" header is present and
|
||||||
|
@ -1052,37 +1042,37 @@ module Net # :nodoc:
|
||||||
# the content to be sent in "chunks" without at the outset
|
# the content to be sent in "chunks" without at the outset
|
||||||
# stating the entire content length.
|
# stating the entire content length.
|
||||||
def chunked?
|
def chunked?
|
||||||
s = @header['transfer-encoding']
|
field = @header['transfer-encoding'] or return false
|
||||||
(s and /(?:\A|[^\-\w])chunked(?:[^\-\w]|\z)/i === s) ? true : false
|
(/(?:\A|[^\-\w])chunked(?:[^\-\w]|\z)/i =~ field) ? true : false
|
||||||
end
|
end
|
||||||
|
|
||||||
# Returns a Range object which represents Content-Range: header field.
|
# Returns a Range object which represents Content-Range: header field.
|
||||||
# This indicates, for a partial entity body, where this fragment
|
# This indicates, for a partial entity body, where this fragment
|
||||||
# fits inside the full entity body, as range of byte offsets.
|
# fits inside the full entity body, as range of byte offsets.
|
||||||
def content_range
|
def content_range
|
||||||
s = @header['content-range'] or return nil
|
return nil unless @header['content-range']
|
||||||
m = %r<bytes\s+(\d+)-(\d+)/(?:\d+|\*)>i.match(s) or
|
m = %r<bytes\s+(\d+)-(\d+)/(\d+|\*)>i.match(@header['content-range']) or
|
||||||
raise HTTPHeaderSyntaxError, 'wrong Content-Range format'
|
raise HTTPHeaderSyntaxError, 'wrong Content-Range format'
|
||||||
m[1].to_i .. m[2].to_i + 1
|
m[1].to_i .. m[2].to_i + 1
|
||||||
end
|
end
|
||||||
|
|
||||||
# The length of the range represented in Range: header.
|
# The length of the range represented in Range: header.
|
||||||
def range_length
|
def range_length
|
||||||
r = self.content_range
|
r = content_range() or return nil
|
||||||
r and (r.end - r.begin)
|
r.end - r.begin
|
||||||
end
|
end
|
||||||
|
|
||||||
# Set the Authorization: header for "Basic" authorization.
|
# Set the Authorization: header for "Basic" authorization.
|
||||||
def basic_auth( account, password )
|
def basic_auth(account, password)
|
||||||
@header['authorization'] = basic_encode(account, password)
|
@header['authorization'] = basic_encode(account, password)
|
||||||
end
|
end
|
||||||
|
|
||||||
# Set Proxy-Authorization: header for "Basic" authorization.
|
# Set Proxy-Authorization: header for "Basic" authorization.
|
||||||
def proxy_basic_auth( account, password )
|
def proxy_basic_auth(account, password)
|
||||||
@header['proxy-authorization'] = basic_encode(account, password)
|
@header['proxy-authorization'] = basic_encode(account, password)
|
||||||
end
|
end
|
||||||
|
|
||||||
def basic_encode( account, password )
|
def basic_encode(account, password)
|
||||||
'Basic ' + ["#{account}:#{password}"].pack('m').strip
|
'Basic ' + ["#{account}:#{password}"].pack('m').strip
|
||||||
end
|
end
|
||||||
private :basic_encode
|
private :basic_encode
|
||||||
|
@ -1099,17 +1089,18 @@ module Net # :nodoc:
|
||||||
|
|
||||||
include HTTPHeader
|
include HTTPHeader
|
||||||
|
|
||||||
def initialize( m, reqbody, resbody, path, initheader = nil )
|
def initialize(m, reqbody, resbody, path, initheader = nil)
|
||||||
@method = m
|
@method = m
|
||||||
@request_has_body = reqbody
|
@request_has_body = reqbody
|
||||||
@response_has_body = resbody
|
@response_has_body = resbody
|
||||||
|
raise ArgumentError, "invalid request path: #{path.inspect}" unless %r<\A/> =~ path
|
||||||
@path = path
|
@path = path
|
||||||
|
|
||||||
@header = {}
|
@header = {}
|
||||||
return unless initheader
|
return unless initheader
|
||||||
initheader.each do |k,v|
|
initheader.each do |k,v|
|
||||||
key = k.downcase
|
key = k.downcase
|
||||||
$stderr.puts "net/http: warning: duplicated HTTP header: #{k}" if @header.key?(key) and $VERBOSE
|
warn "net/http: warning: duplicated HTTP header: #{k}" if @header.key?(key) and $VERBOSE
|
||||||
@header[key] = v.strip
|
@header[key] = v.strip
|
||||||
end
|
end
|
||||||
@header['accept'] ||= '*/*'
|
@header['accept'] ||= '*/*'
|
||||||
|
@ -1136,9 +1127,10 @@ module Net # :nodoc:
|
||||||
# write
|
# write
|
||||||
#
|
#
|
||||||
|
|
||||||
def exec( sock, ver, path, body ) #:nodoc: internal use only
|
def exec(sock, ver, path, body) #:nodoc: internal use only
|
||||||
if body
|
if body
|
||||||
check_body_permitted
|
raise ArgumentError, 'HTTP request body is not permitted' \
|
||||||
|
unless request_body_permitted?
|
||||||
send_request_with_body sock, ver, path, body
|
send_request_with_body sock, ver, path, body
|
||||||
else
|
else
|
||||||
request sock, ver, path
|
request sock, ver, path
|
||||||
|
@ -1147,27 +1139,20 @@ module Net # :nodoc:
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def check_body_permitted
|
def send_request_with_body(sock, ver, path, body)
|
||||||
request_body_permitted? or
|
|
||||||
raise ArgumentError, 'HTTP request body is not permitted'
|
|
||||||
end
|
|
||||||
|
|
||||||
def send_request_with_body( sock, ver, path, body )
|
|
||||||
@header['content-length'] = body.length.to_s
|
@header['content-length'] = body.length.to_s
|
||||||
@header.delete 'transfer-encoding'
|
@header.delete 'transfer-encoding'
|
||||||
|
|
||||||
unless @header['content-type']
|
unless @header['content-type']
|
||||||
$stderr.puts 'net/http: warning: Content-Type did not set; using application/x-www-form-urlencoded' if $VERBOSE
|
warn 'net/http: warning: Content-Type did not set; using application/x-www-form-urlencoded' if $VERBOSE
|
||||||
@header['content-type'] = 'application/x-www-form-urlencoded'
|
@header['content-type'] = 'application/x-www-form-urlencoded'
|
||||||
end
|
end
|
||||||
|
|
||||||
request sock, ver, path
|
request sock, ver, path
|
||||||
sock.write body
|
sock.write body
|
||||||
end
|
end
|
||||||
|
|
||||||
def request( sock, ver, path )
|
def request(sock, ver, path)
|
||||||
buf = "#{@method} #{path} HTTP/#{ver}\r\n"
|
buf = "#{@method} #{path} HTTP/#{ver}\r\n"
|
||||||
canonical_each do |k,v|
|
each_capitalized do |k,v|
|
||||||
buf << k + ': ' + v + "\r\n"
|
buf << k + ': ' + v + "\r\n"
|
||||||
end
|
end
|
||||||
buf << "\r\n"
|
buf << "\r\n"
|
||||||
|
@ -1184,7 +1169,7 @@ module Net # :nodoc:
|
||||||
class HTTPRequest < HTTPGenericRequest
|
class HTTPRequest < HTTPGenericRequest
|
||||||
|
|
||||||
# Creates HTTP request object.
|
# Creates HTTP request object.
|
||||||
def initialize( path, initheader = nil )
|
def initialize(path, initheader = nil)
|
||||||
super self.class::METHOD,
|
super self.class::METHOD,
|
||||||
self.class::REQUEST_HAS_BODY,
|
self.class::REQUEST_HAS_BODY,
|
||||||
self.class::RESPONSE_HAS_BODY,
|
self.class::RESPONSE_HAS_BODY,
|
||||||
|
@ -1229,7 +1214,7 @@ module Net # :nodoc:
|
||||||
# HTTP exception class.
|
# HTTP exception class.
|
||||||
# You must use its subclasses.
|
# You must use its subclasses.
|
||||||
module HTTPExceptions
|
module HTTPExceptions
|
||||||
def initialize( msg, res ) #:nodoc:
|
def initialize(msg, res) #:nodoc:
|
||||||
super msg
|
super msg
|
||||||
@response = res
|
@response = res
|
||||||
end
|
end
|
||||||
|
@ -1541,11 +1526,11 @@ module Net # :nodoc:
|
||||||
|
|
||||||
class << self
|
class << self
|
||||||
|
|
||||||
def read_new( sock ) #:nodoc: internal use only
|
def read_new(sock) #:nodoc: internal use only
|
||||||
httpv, code, msg = read_status_line(sock)
|
httpv, code, msg = read_status_line(sock)
|
||||||
res = response_class(code).new(httpv, code, msg)
|
res = response_class(code).new(httpv, code, msg)
|
||||||
each_response_header(sock) do |k,v|
|
each_response_header(sock) do |k,v|
|
||||||
if res.key? k
|
if res.key?(k)
|
||||||
res[k] << ', ' << v
|
res[k] << ', ' << v
|
||||||
else
|
else
|
||||||
res[k] = v
|
res[k] = v
|
||||||
|
@ -1557,25 +1542,25 @@ module Net # :nodoc:
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def read_status_line( sock )
|
def read_status_line(sock)
|
||||||
str = sock.readline
|
str = sock.readline
|
||||||
m = /\AHTTP(?:\/(\d+\.\d+))?\s+(\d\d\d)\s*(.*)\z/in.match(str) or
|
m = /\AHTTP(?:\/(\d+\.\d+))?\s+(\d\d\d)\s*(.*)\z/in.match(str) or
|
||||||
raise HTTPBadResponse, "wrong status line: #{str.dump}"
|
raise HTTPBadResponse, "wrong status line: #{str.dump}"
|
||||||
m.to_a[1,3]
|
m.captures
|
||||||
end
|
end
|
||||||
|
|
||||||
def response_class( code )
|
def response_class(code)
|
||||||
CODE_TO_OBJ[code] or
|
CODE_TO_OBJ[code] or
|
||||||
CODE_CLASS_TO_OBJ[code[0,1]] or
|
CODE_CLASS_TO_OBJ[code[0,1]] or
|
||||||
HTTPUnknownResponse
|
HTTPUnknownResponse
|
||||||
end
|
end
|
||||||
|
|
||||||
def each_response_header( sock )
|
def each_response_header(sock)
|
||||||
while true
|
while true
|
||||||
line = sock.readuntil("\n", true).sub(/\s+\z/, '')
|
line = sock.readuntil("\n", true).sub(/\s+\z/, '')
|
||||||
break if line.empty?
|
break if line.empty?
|
||||||
m = /\A([^:]+):\s*/.match(line) or
|
m = /\A([^:]+):\s*/.match(line) or
|
||||||
raise HTTPBadResponse, 'wrong header line format'
|
raise HTTPBadResponse, 'wrong header line format'
|
||||||
yield m[1], m.post_match
|
yield m[1], m.post_match
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -1588,7 +1573,7 @@ module Net # :nodoc:
|
||||||
|
|
||||||
include HTTPHeader
|
include HTTPHeader
|
||||||
|
|
||||||
def initialize( httpv, code, msg ) #:nodoc: internal use only
|
def initialize(httpv, code, msg) #:nodoc: internal use only
|
||||||
@http_version = httpv
|
@http_version = httpv
|
||||||
@code = code
|
@code = code
|
||||||
@message = msg
|
@message = msg
|
||||||
|
@ -1660,7 +1645,7 @@ module Net # :nodoc:
|
||||||
# body
|
# body
|
||||||
#
|
#
|
||||||
|
|
||||||
def reading_body( sock, reqmethodallowbody ) #:nodoc: internal use only
|
def reading_body(sock, reqmethodallowbody) #:nodoc: internal use only
|
||||||
@socket = sock
|
@socket = sock
|
||||||
@body_exist = reqmethodallowbody && self.class.body_permitted?
|
@body_exist = reqmethodallowbody && self.class.body_permitted?
|
||||||
begin
|
begin
|
||||||
|
@ -1693,12 +1678,11 @@ module Net # :nodoc:
|
||||||
# end
|
# end
|
||||||
# }
|
# }
|
||||||
#
|
#
|
||||||
def read_body( dest = nil, &block )
|
def read_body(dest = nil, &block)
|
||||||
if @read
|
if @read
|
||||||
raise IOError, "#{self.class}\#read_body called twice" if dest or block
|
raise IOError, "#{self.class}\#read_body called twice" if dest or block
|
||||||
return @body
|
return @body
|
||||||
end
|
end
|
||||||
|
|
||||||
to = procdest(dest, block)
|
to = procdest(dest, block)
|
||||||
stream_check
|
stream_check
|
||||||
if @body_exist
|
if @body_exist
|
||||||
|
@ -1734,32 +1718,31 @@ module Net # :nodoc:
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def read_body_0( dest )
|
def read_body_0(dest)
|
||||||
if chunked?
|
if chunked?
|
||||||
read_chunked dest
|
read_chunked dest
|
||||||
else
|
return
|
||||||
clen = content_length()
|
|
||||||
if clen
|
|
||||||
@socket.read clen, dest, true # ignore EOF
|
|
||||||
else
|
|
||||||
clen = range_length()
|
|
||||||
if clen
|
|
||||||
@socket.read clen, dest
|
|
||||||
else
|
|
||||||
@socket.read_all dest
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
clen = content_length()
|
||||||
|
if clen
|
||||||
|
@socket.read clen, dest, true # ignore EOF
|
||||||
|
return
|
||||||
|
end
|
||||||
|
clen = range_length()
|
||||||
|
if clen
|
||||||
|
@socket.read clen, dest
|
||||||
|
return
|
||||||
|
end
|
||||||
|
@socket.read_all dest
|
||||||
end
|
end
|
||||||
|
|
||||||
def read_chunked( dest )
|
def read_chunked(dest)
|
||||||
len = nil
|
len = nil
|
||||||
total = 0
|
total = 0
|
||||||
|
|
||||||
while true
|
while true
|
||||||
line = @socket.readline
|
line = @socket.readline
|
||||||
hexlen = line.slice(/[0-9a-fA-F]+/) or
|
hexlen = line.slice(/[0-9a-fA-F]+/) or
|
||||||
raise HTTPBadResponse, "wrong chunk size line: #{line}"
|
raise HTTPBadResponse, "wrong chunk size line: #{line}"
|
||||||
len = hexlen.hex
|
len = hexlen.hex
|
||||||
break if len == 0
|
break if len == 0
|
||||||
@socket.read len, dest; total += len
|
@socket.read len, dest; total += len
|
||||||
|
@ -1774,9 +1757,9 @@ module Net # :nodoc:
|
||||||
raise IOError, 'try to read body out of block' if @socket.closed?
|
raise IOError, 'try to read body out of block' if @socket.closed?
|
||||||
end
|
end
|
||||||
|
|
||||||
def procdest( dest, block )
|
def procdest(dest, block)
|
||||||
raise ArgumentError, 'both of arg and block are given for HTTP method'\
|
raise ArgumentError, 'both of arg and block are given for HTTP method' \
|
||||||
if dest and block
|
if dest and block
|
||||||
if block
|
if block
|
||||||
ReadAdapter.new(block)
|
ReadAdapter.new(block)
|
||||||
else
|
else
|
||||||
|
|
Loading…
Add table
Reference in a new issue