* lib/net/http.rb: refine document.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@4273 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
aamine 2003-08-01 15:41:41 +00:00
parent dd15b0555b
commit b1139297c3

View File

@ -1,4 +1,6 @@
#
# = net/http.rb # = net/http.rb
#
#-- #--
# Copyright (c) 1999-2003 Yukihiro Matsumoto # Copyright (c) 1999-2003 Yukihiro Matsumoto
# Copyright (c) 1999-2003 Minero Aoki # Copyright (c) 1999-2003 Minero Aoki
@ -15,6 +17,7 @@
# #
# $Id$ # $Id$
#++ #++
#
# == What Is This Library? # == What Is This Library?
# #
# This library provides your program functions to access WWW # This library provides your program functions to access WWW
@ -145,7 +148,8 @@
# 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 multithread-safe. # This function is NOT multithread-safe.
#
require 'net/protocol' require 'net/protocol'
require 'uri' require 'uri'
@ -174,19 +178,42 @@ module Net
@@newimpl = true @@newimpl = true
# Turns on net/http 1.2 (ruby 1.8) features.
# Defaults to ON in ruby 1.8.
#
# I strongly recommend to call this method always.
#
# require 'net/http'
# Net::HTTP.version_1_2
#
def HTTP.version_1_2 def HTTP.version_1_2
@@newimpl = true @@newimpl = true
end end
# Turns on net/http 1.2 (ruby 1.8) features.
# Defaults to OFF in ruby 1.8.
def HTTP.version_1_1 def HTTP.version_1_1
@@newimpl = false @@newimpl = false
end end
def HTTP.is_version_1_2? # true if net/http is in version 1.2 mode.
# Defaults to true.
def HTTP.version_1_2?
@@newimpl @@newimpl
end end
def HTTP.setimplversion( obj ) # true if net/http is in version 1.1 compatible mode.
# Defaults to true.
def HTTP.version_1_1?
not @@newimpl
end
class << HTTP
alias is_version_1_1? version_1_1? #:nodoc:
alias is_version_1_2? version_1_2? #:nodoc:
end
def HTTP.setimplversion( obj ) #:nodoc:
f = @@newimpl f = @@newimpl
obj.instance_eval { @newimpl = f } obj.instance_eval { @newimpl = f }
end end
@ -256,14 +283,14 @@ module Net
end end
end end
def HTTP.get_by_path( addr, path, port = nil ) 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 ) 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|
@ -276,18 +303,12 @@ module Net
# HTTP session management # HTTP session management
# #
#
# The default port to use for HTTP requests; defaults to 80. # The default port to use for HTTP requests; defaults to 80.
#
def HTTP.default_port def HTTP.default_port
80 80
end end
# def HTTP.socket_type #:nodoc:
# The type of socket to use for HTTP connections.
# Defaults to +InternetMessageIO+
#
def HTTP.socket_type
InternetMessageIO InternetMessageIO
end end
@ -299,7 +320,7 @@ module Net
# 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+ object 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
@ -334,7 +355,7 @@ module Net
end end
def inspect def inspect
"#<#{self.class} #{@address}:#{@port} open=#{active?}>" "#<#{self.class} #{@address}:#{@port} open=#{started?}>"
end end
def set_debug_output( arg ) # :nodoc: def set_debug_output( arg ) # :nodoc:
@ -343,6 +364,7 @@ module Net
# The host name to connect to. # The host name to connect to.
attr_reader :address attr_reader :address
# The port number to connect to. # The port number to connect to.
attr_reader :port attr_reader :port
@ -351,7 +373,7 @@ module Net
# it raises a TimeoutError exception. # it raises a TimeoutError exception.
attr_accessor :open_timeout attr_accessor :open_timeout
# Seconds to wait until reading one block (by one read(1) call). # Seconds to wait until reading one block (by one read(2) call).
# If the HTTP object cannot open a conection in this many seconds, # If the HTTP object cannot open a conection in this many seconds,
# it raises a TimeoutError exception. # it raises a TimeoutError exception.
attr_reader :read_timeout attr_reader :read_timeout
@ -367,7 +389,7 @@ module Net
@started @started
end end
alias active? started? alias active? started? #:nodoc:
attr_accessor :close_on_empty_response attr_accessor :close_on_empty_response
@ -380,7 +402,7 @@ module Net
# When called with a block, returns the return value of the # When called with a block, returns the return value of the
# block; otherwise, returns self. # block; otherwise, returns self.
# #
def start # :yield: Net::HTTP object def start # :yield: +http+
raise IOError, 'HTTP session already opened' if @started raise IOError, 'HTTP session already opened' if @started
if block_given? if block_given?
begin begin
@ -499,8 +521,8 @@ module Net
self.class.proxy_pass self.class.proxy_pass
end end
alias proxyaddr proxy_address alias proxyaddr proxy_address #:nodoc:
alias proxyport proxy_port alias proxyport proxy_port #:nodoc:
private private
@ -518,7 +540,7 @@ module Net
path path
end end
module ProxyDelta module ProxyDelta #:nodoc:
private private
# with proxy # with proxy
@ -545,9 +567,9 @@ module Net
# Gets data from +path+ on the connected-to host. # Gets data from +path+ on the connected-to host.
# +header+ must be a Hash like { 'Accept' => '*/*', ... }. # +header+ must be a Hash like { 'Accept' => '*/*', ... }.
# #
# In version 1.1, this method returns a pair of objects, # In version 1.1 (ruby 1.6), this method returns a pair of objects,
# a Net::HTTPResponse object and the entity body string. # a Net::HTTPResponse object and the entity body string.
# In version 1.2, this method returns a Net::HTTPResponse # In version 1.2 (ruby 1.8), this method returns a Net::HTTPResponse
# object. # object.
# #
# If called with a block, yields each fragment of the # If called with a block, yields each fragment of the
@ -555,14 +577,8 @@ module Net
# the socket. Note that in this case, the returned response # the socket. Note that in this case, the returned response
# object will *not* contain a (meaningful) body. # object will *not* contain a (meaningful) body.
# #
# +dest+ is an alternative method of collecting the body. It # +dest+ argument is obsolete.
# must be an object responding to the "<<" operator (such as # It still works but you must not use it.
# a String or an Array). Each fragment of the entity body
# will be "<<"-ed in turn onto +dest+ if provided, and it will
# also become the body of the returned response object.
#
# You must *not* provide both +dest+ and a block; doing so
# will result in an ArgumentError.
# #
# In version 1.1, this method might raise an exception for # In version 1.1, this method might raise an exception for
# 3xx (redirect). In this case you can get a HTTPResponse object # 3xx (redirect). In this case you can get a HTTPResponse object
@ -573,7 +589,7 @@ module Net
# # version 1.1 (bundled with Ruby 1.6) # # version 1.1 (bundled with Ruby 1.6)
# response, body = http.get('/index.html') # response, body = http.get('/index.html')
# #
# # version 1.2 (bundled with Ruby 1.7 or later) # # version 1.2 (bundled with Ruby 1.8 or later)
# response = http.get('/index.html') # response = http.get('/index.html')
# #
# # using block # # using block
@ -582,6 +598,7 @@ module Net
# f.write str # f.write str
# 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|
@ -614,16 +631,16 @@ module Net
# #
def head( path, initheader = nil ) def head( path, initheader = nil )
res = request(Head.new(path, initheader)) res = request(Head.new(path, initheader))
@newimpl or res.value res.value unless @newimpl
res res
end end
# Posts +data+ (must be a String) to +path+. +header+ must be a Hash # Posts +data+ (must be a String) to +path+. +header+ must be a Hash
# like { 'Accept' => '*/*', ... }. # like { 'Accept' => '*/*', ... }.
# #
# In version 1.1, this method returns a pair of objects, a # In version 1.1 (ruby 1.6), this method returns a pair of objects, a
# Net::HTTPResponse object and an entity body string. # Net::HTTPResponse object and an entity body string.
# In version 1.2, this method returns a Net::HTTPReponse object. # In version 1.2 (ruby 1.8), this method returns a Net::HTTPReponse object.
# #
# If called with a block, yields each fragment of the # If called with a block, yields each fragment of the
# entity body in turn as a string as it are read from # entity body in turn as a string as it are read from
@ -656,7 +673,7 @@ module Net
# f.write str # f.write str
# end # end
# } # }
def post( path, data, initheader = nil, dest = nil, &block ) # :yield: +body+ 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
@ -670,7 +687,7 @@ module Net
res res
end end
def put( path, data, initheader = nil ) # :yield: +response+ 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 @newimpl or res.value
res res
@ -748,7 +765,7 @@ module Net
request Post.new(path, initheader), data, &block request Post.new(path, initheader), data, &block
end end
def request_put( path, data, initheader = nil, &block ) 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
@ -887,11 +904,11 @@ module Net
# #
module HTTPHeader module HTTPHeader
def size def size #:nodoc:
@header.size @header.size
end end
alias length size alias length size #: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"
@ -911,29 +928,34 @@ module Net
@header.fetch(key.downcase, *args, &block) @header.fetch(key.downcase, *args, &block)
end end
# See Hash#each # 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
def each_key( &block ) # Iterates for each header names.
def each_key( &block ) # :yield: +key+
@header.each_key(&block) @header.each_key(&block)
end end
def each_value( &block ) # Iterates for each header values.
def each_value( &block ) # :yield: +value+
@header.each_value(&block) @header.each_value(&block)
end end
# 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.
def key?( key ) def key?( key )
@header.key?(key.downcase) @header.key?(key.downcase)
end end
# Returns a Hash consist of header names and values.
def to_hash def to_hash
@header.dup @header.dup
end end
@ -1030,6 +1052,7 @@ module Net
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.
def range_length def range_length
r = self.content_range r = self.content_range
r and (r.end - r.begin) r and (r.end - r.begin)
@ -1100,7 +1123,7 @@ module Net
# #
# internal use only # internal use only
def exec( sock, ver, path, body ) def exec( sock, ver, path, body ) #:nodoc:
if body if body
check_body_permitted check_body_permitted
send_request_with_body sock, ver, path, body send_request_with_body sock, ver, path, body
@ -1117,7 +1140,7 @@ module Net
end end
def send_request_with_body( sock, ver, path, body ) def send_request_with_body( sock, ver, path, body )
@header['content-length'] = body.size.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']
@ -1190,8 +1213,10 @@ module Net
### Response ### Response
### ###
# HTTP exception class.
# You must use its subclasses.
module HTTPExceptions module HTTPExceptions
def initialize( msg, res ) def initialize( msg, res ) #:nodoc:
super msg super msg
@response = res @response = res
end end
@ -1274,17 +1299,17 @@ module Net
# 505 HTTPVersionNotSupported # 505 HTTPVersionNotSupported
# #
# xxx HTTPUnknownResponse # xxx HTTPUnknownResponse
#
class HTTPResponse class HTTPResponse
# predefine HTTPResponse class to allow inheritance # true if the reponse has body.
def HTTPResponse.body_permitted?
def self.body_permitted?
self::HAS_BODY self::HAS_BODY
end end
def self.exception_type def HTTPResponse.exception_type # :nodoc:
self::EXCEPTION_TYPE self::EXCEPTION_TYPE
end end
end end # redefined after
class HTTPUnknownResponse < HTTPResponse class HTTPUnknownResponse < HTTPResponse
HAS_BODY = true HAS_BODY = true
@ -1499,7 +1524,7 @@ module Net
class << self class << self
def read_new( sock ) def read_new( sock ) #:nodoc:
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|
@ -1546,7 +1571,7 @@ module Net
include HTTPHeader include HTTPHeader
def initialize( httpv, code, msg ) def initialize( httpv, code, msg ) #:nodoc:
@http_version = httpv @http_version = httpv
@code = code @code = code
@message = msg @message = msg
@ -1556,6 +1581,7 @@ module Net
@read = false @read = false
end end
# The HTTP version supported by the server.
attr_reader :http_version attr_reader :http_version
# HTTP result code string. For example, '302'. You can also # HTTP result code string. For example, '302'. You can also
@ -1565,7 +1591,7 @@ module Net
# HTTP result message. For example, 'Not Found'. # HTTP result message. For example, 'Not Found'.
attr_reader :message attr_reader :message
alias msg message # for backward compatibility alias msg message # :nodoc:
def inspect def inspect
"#<#{self.class} #{@code} readbody=#{@read}>" "#<#{self.class} #{@code} readbody=#{@read}>"
@ -1585,19 +1611,19 @@ module Net
# response <-> exception relationship # response <-> exception relationship
# #
def code_type def code_type #:nodoc:
self.class self.class
end end
def error! def error! #:nodoc:
raise error_type().new(@code + ' ' + @message.dump, self) raise error_type().new(@code + ' ' + @message.dump, self)
end end
def error_type def error_type #:nodoc:
self.class::EXCEPTION_TYPE self.class::EXCEPTION_TYPE
end end
def value def value #:nodoc:
error! unless HTTPSuccess === self error! unless HTTPSuccess === self
end end
@ -1605,12 +1631,12 @@ module Net
# header (for backward compatibility only; DO NOT USE) # header (for backward compatibility only; DO NOT USE)
# #
def response def response #:nodoc:
self self
end end
alias header response alias header response #:nodoc:
alias read_header response alias read_header response #:nodoc:
# #
# body # body
@ -1627,15 +1653,28 @@ module Net
end end
end end
# Gets entity body and either writes it into +dest+ using "<<" method. # Gets entity body. If the block given, yields it to +block+.
# or yields it to +block+. +dest+ and +block+ cannot both be provided;
# doing so results in an ArgumentError being raised. If neither is
# provided, the body is read into a String and this is returned.
# The body is provided in fragments, as it is read in from the socket. # The body is provided in fragments, as it is read in from the socket.
# #
# Calling this method a second or subsequent time will return the # Calling this method a second or subsequent time will return the
# original +dest+, +block+ (non-usefully), or String the body was # already read string.
# read into. #
# http.request_get('/index.html') {|res|
# puts res.read_body
# }
#
# http.request_get('/index.html') {|res|
# p res.read_body.object_id # 538149362
# p res.read_body.object_id # 538149362
# }
#
# # using iterator
# http.request_get('/index.html') {|res|
# res.read_body do |segment|
# print segment
# 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
@ -1655,8 +1694,25 @@ module Net
@body @body
end end
alias body read_body # Returns the entity body.
alias entity read_body #
# Calling this method a second or subsequent time will return the
# already read string.
#
# http.request_get('/index.html') {|res|
# puts res.body
# }
#
# http.request_get('/index.html') {|res|
# p res.body.object_id # 538149362
# p res.body.object_id # 538149362
# }
#
def body
read_body()
end
alias entity body #:nodoc:
private private
@ -1718,7 +1774,7 @@ module Net
class HTTP class HTTP
ProxyMod = ProxyDelta ProxyMod = ProxyDelta
end end
module NetPrivate module NetPrivate #:nodoc:
HTTPRequest = ::Net::HTTPRequest HTTPRequest = ::Net::HTTPRequest
end end