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: unify coding style.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@3070 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
aamine 2002-11-21 11:13:17 +00:00
parent 4a66fdcad3
commit 15911a95bf
2 changed files with 226 additions and 221 deletions

View file

@ -1,3 +1,7 @@
Thu Nov 21 20:17:08 2002 Minero Aoki <aamine@loveruby.net>
* lib/net/http.rb: unify coding style.
Thu Nov 21 20:04:06 2002 Minero Aoki <aamine@loveruby.net>
* lib/net/http.rb: should not overwrite Host: header.

View file

@ -4,31 +4,33 @@
Copyright (c) 1999-2002 Yukihiro Matsumoto
written & maintained by Minero Aoki <aamine@loveruby.net>
written & maintained by Minero Aoki <aamine@loveruby.net>.
This file is derived from "http-access.rb".
This program is free software. You can re-distribute and/or
modify this program under the same terms as Ruby itself,
modify this program under the same terms of ruby itself ---
Ruby Distribute License or GNU General Public License.
NOTE: You can find Japanese version of this document in
the doc/net directory of the standard ruby interpreter package.
NOTE: You can find Japanese version of this document here:
((<URL:http://www.ruby-lang.org/ja/man-1.6/?cmd=view;name=net%2Fhttp.rb>))
$Id$
== What is this module?
== What Is This Library?
This module provide your program the functions to access WWW
This library provides your program functions to access WWW
documents via HTTP, Hyper Text Transfer Protocol version 1.1.
For details of HTTP, refer [RFC2616]
((<URL:http://www.ietf.org/rfc/rfc2616.txt>)).
== Examples
=== Getting Document From Server
=== Getting Document From WWW Server
(formal version)
require 'net/http'
Net::HTTP.start( 'some.www.server', 80 ) {|http|
Net::HTTP.start('www.example.com', 80) {|http|
response = http.get('/index.html')
puts response.body
}
@ -36,52 +38,56 @@ For details of HTTP, refer [RFC2616]
(shorter version)
require 'net/http'
Net::HTTP.get_print 'some.www.server', '/index.html'
# or
Net::HTTP.get_print 'www.example.com', '/index.html'
or
require 'net/http'
require 'uri'
Net::HTTP.get_print URI.parse('http://www.example.com/index.html')
=== Posting Form Data
require 'net/http'
Net::HTTP.start( 'some.www.server', 80 ) {|http|
response = http.post('/cgi-bin/any.rhtml',
'querytype=subject&target=ruby')
Net::HTTP.start('some.www.server', 80) {|http|
response = http.post('/cgi-bin/search.rb', 'query=ruby')
}
=== Accessing via Proxy
Net::HTTP.Proxy() creates http proxy class. It has same
Net::HTTP.Proxy creates http proxy class. It has same
methods of Net::HTTP but its instances always connect to
proxy, instead of given host.
require 'net/http'
$proxy_addr = 'your.proxy.addr'
$proxy_port = 8080
proxy_addr = 'your.proxy.host'
proxy_port = 8080
:
Net::HTTP::Proxy($proxy_addr, $proxy_port).start('some.www.server') {|http|
Net::HTTP::Proxy(proxy_addr, proxy_port).start('www.example.com') {|http|
# always connect to your.proxy.addr:8080
:
}
Since Net::HTTP.Proxy() returns Net::HTTP itself when $proxy_addr is nil,
Since Net::HTTP.Proxy returns Net::HTTP itself when proxy_addr is nil,
there's no need to change code if there's proxy or not.
There are two additional parameters in Net::HTTP.Proxy() which allow to specify
proxy user name and password:
There are two additional parameters in Net::HTTP.Proxy which allow to
specify proxy user name and password:
Net::HTTP::Proxy(proxy_addr, proxy_port, proxy_name = nil, proxy_pass = nil)
Net::HTTP::Proxy(proxy_addr, proxy_port, proxy_user = nil, proxy_pass = nil)
You may use them to work with authorization-enabled proxies:
require 'net/http'
require 'uri'
proxy_info = URI.parse(ENV['http_proxy'])
proxy_name, proxy_pass = proxy_info.userinfo.split(":") if proxy_info.userinfo
Net::HTTP::Proxy($proxy_addr, $proxy_port, proxy_name, proxy_pass).start('some.www.server') {|http|
proxy_host = 'your.proxy.host'
proxy_port = 8080
uri = URI.parse(ENV['http_proxy'])
proxy_user, proxy_pass = uri.userinfo.split(/:/) if uri.userinfo
Net::HTTP::Proxy(proxy_host, proxy_port,
proxy_user, proxy_pass).start('www.example.com') {|http|
# always connect to your.proxy.addr:8080 using specified username and password
:
}
@ -90,18 +96,22 @@ You may use them to work with authorization-enabled proxies:
=== Following Redirection
require 'net/http'
require 'uri'
def fetch( uri_str, limit = 10 )
# You should choose better exception.
raise ArgumentError, 'http redirect too deep' if limit == 0
def read_uri( uri_str )
response = Net::HTTP.get_response(URI.parse(uri_str))
case response
when Net::HTTPSuccess then response
when Net::HTTPRedirection then read_uri(response['location'])
when Net::HTTPRedirection then fetch(response['location'], limit - 1)
else
response.error!
end
end
print read_uri('http://www.ruby-lang.org')
print fetch('http://www.ruby-lang.org')
Net::HTTPSuccess and Net::HTTPRedirection is a HTTPResponse class.
All HTTPResponse objects belong to its own response class which
@ -112,9 +122,9 @@ see section "HTTP Response Classes".
require 'net/http'
req = Net::HTTP::Get.new('/need-auth.cgi')
req.basic_auth 'account', 'password'
Net::HTTP.start( 'auth.some.domain' ) {|http|
Net::HTTP.start('www.example.com') {|http|
req = Net::HTTP::Get.new('/secret-page.html')
req.basic_auth 'account', 'password'
response = http.request(req)
print response.body
}
@ -193,7 +203,7 @@ allows you to use 1.2 features again.
Net::HTTP.version_1_2
Net::HTTP.start {|http3| ...(http3 has 1.2 features)... }
This function is not thread-safe.
This function is not multithread-safe.
== class Net::HTTP
@ -202,10 +212,11 @@ This function is not thread-safe.
: new( address, port = 80, proxy_addr = nil, proxy_port = nil )
creates a new Net::HTTP object.
If proxy_addr is given, creates an Net::HTTP object with proxy support.
This method does not open TCP connection.
: start( address, port = 80, proxy_addr = nil, proxy_port = nil )
creates a new Net::HTTP object and returns it
with opening HTTP session.
with opening TCP connection and HTTP session.
: start( address, port = 80, proxy_addr = nil, proxy_port = nil ) {|http| .... }
creates a new Net::HTTP object and gives it to the block.
@ -214,14 +225,14 @@ This function is not thread-safe.
This method returns the return value of the block.
: get_print( uri )
: get_print( address, path, port = 80 )
gets entity body from the target and output it to stdout.
: get_print( host, path, port = 80 )
gets entity body from the target and outputs it to the stdout.
Net::HTTP.get_print URI.parse('http://www.example.com')
: get( uri )
: get( address, path, port = 80 )
send GET request to the target and get a response.
: get( host, path, port = 80 )
send GET request to the target and gets a response.
This method returns a String.
print Net::HTTP.get(URI.parse('http://www.example.com'))
@ -236,44 +247,44 @@ This function is not thread-safe.
: Proxy( address, port = 80, username = nil, password = nil )
creates a HTTP proxy class.
Arguments are address/port of proxy host and username/password if authorization
on proxy server is required.
You can replace HTTP class with created proxy class.
Arguments are address/port of proxy host and username/password
if authorization on proxy server is required.
You can replace the HTTP class with created proxy class.
If ADDRESS is nil, this method returns self (Net::HTTP).
# example
proxy_class = Net::HTTP::Proxy( 'proxy.foo.org', 8080 )
# Example
proxy_class = Net::HTTP::Proxy('proxy.example.com', 8080)
:
proxy_class.start( 'www.ruby-lang.org' ) {|http|
proxy_class.start('www.ruby-lang.org') {|http|
# connecting proxy.foo.org:8080
:
}
: proxy_class?
If self is HTTP, false.
If self is a class which was created by HTTP::Proxy(), true.
return true if self is a class which was created by HTTP::Proxy.
: port
default HTTP port (80).
the default HTTP port number (80).
=== Instance Methods
: start
: start {|http| .... }
opens HTTP session.
opens TCP connection and HTTP session.
When this method is called with block, gives a HTTP object
to the block and closes the HTTP session after block call finished.
to the block and closes the TCP connection / HTTP session
after the block executed.
: started?
returns true if HTTP session is started.
: address
the address to connect
The host name to connect.
: port
the port number to connect
The port number to connect.
: open_timeout
: open_timeout=(n)
@ -288,7 +299,7 @@ This function is not thread-safe.
it raises TimeoutError exception.
: finish
finishes HTTP session.
finishes HTTP session and closes TCP connection.
If HTTP session had not started, raises an IOError.
: proxy?
@ -301,10 +312,10 @@ This function is not thread-safe.
port number of proxy host. If self does not use a proxy, nil.
: proxy_name
user name for accessing proxy. If self does not use a proxy, nil
user name for accessing proxy. If self does not use a proxy, nil.
: proxy_pass
user password for accessing proxy. If self does not use a proxy, nil
user password for accessing proxy. If self does not use a proxy, nil.
: get( path, header = nil )
: get( path, header = nil ) {|str| .... }
@ -325,18 +336,14 @@ This function is not thread-safe.
In version 1.2, this method never raises exception.
# 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)
response = http.get( '/index.html' )
# compatible in both version
response , = http.get( '/index.html' )
response.body
response = http.get('/index.html')
# using block
File.open( 'save.txt', 'w' ) {|f|
http.get( '/~foo/', nil ) do |str|
File.open('result.txt', 'w') {|f|
http.get('/~foo/') do |str|
f.write str
end
}
@ -353,14 +360,14 @@ This function is not thread-safe.
In version 1.2, this method never raises exception.
response = nil
Net::HTTP.start( 'some.www.server', 80 ) {|http|
response = http.head( '/index.html' )
Net::HTTP.start('some.www.server', 80) {|http|
response = http.head('/index.html')
}
p response['content-type']
: post( path, data, header = nil )
: post( path, data, header = nil ) {|str| .... }
posts DATA (must be String) to PATH. HEADER must be a Hash
posts DATA (must be a String) to PATH. HEADER must be a Hash
like { 'Accept' => '*/*', ... }.
In version 1.1, this method returns a pair of objects, a
@ -375,38 +382,35 @@ This function is not thread-safe.
In version 1.2, this method never raises exception.
# version 1.1
response, body = http.post( '/cgi-bin/search.rb', 'query=subject&target=ruby' )
response, body = http.post('/cgi-bin/search.rb', 'query=foo')
# version 1.2
response = http.post( '/cgi-bin/search.rb', 'query=subject&target=ruby' )
# compatible in both version
response , = http.post( '/cgi-bin/search.rb', 'query=subject&target=ruby' )
response = http.post('/cgi-bin/search.rb', 'query=foo')
# using block
File.open( 'save.html', 'w' ) {|f|
http.post( '/cgi-bin/search.rb',
'query=subject&target=ruby' ) do |str|
File.open('result.txt', 'w') {|f|
http.post('/cgi-bin/search.rb', 'query=foo') do |str|
f.write str
end
}
: request_get( path, header = nil )
: request_get( path, header = nil ) {|response| .... }
gets entity from PATH. This method returns a HTTPResponse object.
sends GET request to the PATH and get a response,
as a HTTPResponse object.
When called with block, keep connection while block is executed
and gives a HTTPResponse object to the block.
When called with block, gives a HTTPResponse object to the block
and close the TCP connection after the block is executed.
This method never raises Net::* exceptions.
# example
response = http.request_get( '/index.html' )
response = http.request_get('/index.html')
# The entity body is already read here.
p response['content-type']
puts response.body # body is already read
puts response.body
# using block
http.request_get( '/index.html' ) {|response|
http.request_get('/index.html') {|response|
p response['content-type']
response.read_body do |str| # read body now
print str
@ -415,7 +419,8 @@ This function is not thread-safe.
: request_post( path, data, header = nil )
: request_post( path, data, header = nil ) {|response| .... }
posts data to PATH. This method returns a HTTPResponse object.
sends POST request to the PATH and get a response,
as a HTTPResponse object.
When called with block, gives a HTTPResponse object to the block
before reading entity body, with keeping connection.
@ -423,12 +428,12 @@ This function is not thread-safe.
This method never raises Net::* exceptions.
# example
response = http.post2( '/cgi-bin/nice.rb', 'datadatadata...' )
response = http.request_post('/cgi-bin/nice.rb', 'datadatadata...')
p response.status
puts response.body # body is already read
# using block
http.post2( '/cgi-bin/nice.rb', 'datadatadata...' ) {|response|
http.request_post('/cgi-bin/nice.rb', 'datadatadata...') {|response|
p response.status
p response['content-type']
response.read_body do |str| # read body now
@ -436,10 +441,10 @@ This function is not thread-safe.
end
}
: request( request [, data] )
: request( request [, data] ) {|response| .... }
: request( request, data = nil )
: request( request, data = nil ) {|response| .... }
sends a HTTPRequest object REQUEST to the HTTP server.
This method also writes DATA string if REQUEST is a post/put request.
This method also sends DATA string if REQUEST is a post/put request.
Giving DATA for get/head request causes ArgumentError.
If called with block, this method passes a HTTPResponse object to
@ -459,18 +464,26 @@ You MUST use its subclass, Net::HTTP::Get, Post, Head.
=== Instance Methods
: self[ key ]
: self[key]
returns the header field corresponding to the case-insensitive key.
For example, a key of "Content-Type" might return "text/html"
: self[ key ] = val
: self[key] = val
sets the header field corresponding to the case-insensitive key.
: fetch( key, [, default] )
: fetch( key ) {|key| .... }
returns the header field corresponding to the case-insensitive key.
returns the default value if there's no header field named key.
: each {|name, val| .... }
iterates for each field name and value pair.
: basic_auth( account, password )
set Authorization: header for basic auth.
set Authorization: header for "Basic" authorization.
: proxy_basic_auth( account, password )
set Proxy-Authorization: header for "Basic" authorization.
: range
returns a Range object which represents Range: header field.
@ -493,18 +506,18 @@ All arguments named KEY is case-insensitive.
=== Instance Methods
: self[ key ]
: self[key]
returns the header field corresponding to the case-insensitive key.
For example, a key of "Content-Type" might return "text/html".
A key of "Content-Length" might do "2045".
More than one fields which has same names are joined with ','.
: self[ key ] = val
: self[key] = val
sets the header field corresponding to the case-insensitive key.
: fetch( key [,default] )
: fetch( key, [, default] )
: fetch( key ) {|key| .... }
returns the header field corresponding to the case-insensitive key.
returns the default value if there's no header field named key.
@ -602,7 +615,7 @@ module Net
end
def HTTP.get_response( arg1, arg2 = nil, arg3 = nil )
if arg2 then
if arg2
get_by_path(arg1, arg2, arg3)
else
get_by_uri(arg1)
@ -610,7 +623,7 @@ module Net
end
def HTTP.get_by_path( addr, path, port = nil )
new( addr, port || HTTP.default_port ).start {|http|
new(addr, port || HTTP.default_port).start {|http|
return http.request(Get.new(path))
}
end
@ -634,14 +647,14 @@ module Net
protocol_param :socket_type, '::Net::InternetMessageIO'
class << HTTP
def start( address, port = nil, p_addr = nil, p_port = nil, p_name = nil, p_pass = nil, &block )
new( address, port, p_addr, p_port, p_name, p_pass ).start( &block )
def start( address, port = nil, p_addr = nil, p_port = nil, p_user = nil, p_pass = nil, &block )
new(address, port, p_addr, p_port, p_user, p_pass).start(&block)
end
alias newobj new
def new( address, port = nil, p_addr = nil, p_port = nil, p_name = nil, p_pass = nil )
obj = Proxy(p_addr, p_port, p_name, p_pass ).newobj(address, port)
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)
setimplversion obj
obj
end
@ -677,13 +690,12 @@ module Net
@is_proxy_class = false
@proxy_addr = nil
@proxy_port = nil
@proxy_name = nil
@proxy_user = nil
@proxy_pass = nil
def HTTP.Proxy( p_addr, p_port = nil, p_name = nil, p_pass = nil )
p_addr or return self
def HTTP.Proxy( p_addr, p_port = nil, p_user = nil, p_pass = nil )
return self unless p_addr
p_port ||= port()
delta = ProxyDelta
proxyclass = Class.new(self)
proxyclass.module_eval {
@ -691,9 +703,9 @@ module Net
# with proxy
@is_proxy_class = true
@proxy_address = p_addr
@proxy_port = p_port
@proxy_name = p_name
@proxy_pass = p_pass
@proxy_port = p_port || default_port()
@proxy_user = p_user
@proxy_pass = p_pass
}
proxyclass
end
@ -705,7 +717,7 @@ module Net
attr_reader :proxy_address
attr_reader :proxy_port
attr_reader :proxy_name
attr_reader :proxy_user
attr_reader :proxy_pass
end
@ -721,12 +733,20 @@ module Net
self.class.proxy_port
end
def proxy_user
self.class.proxy_user
end
def proxy_pass
self.class.proxy_pass
end
alias proxyaddr proxy_address
alias proxyport proxy_port
private
# no proxy
# without proxy
def conn_address
address
@ -735,16 +755,10 @@ module Net
def conn_port
port
end
# Empty, void
def authorization(header)
return header
end
def edit_path( path )
path
end
module ProxyDelta
private
@ -752,24 +766,16 @@ module Net
# with proxy
def conn_address
proxy_address
proxy_address()
end
def conn_port
proxy_port
proxy_port()
end
def edit_path( path )
'http://' + addr_port() + path
end
def authorization(header)
if self.class.proxy_name then
header = Hash.new unless header
header['Proxy-Authorization'] = "Basic " + ["#{self.class.proxy_name}:#{self.class.proxy_pass}"].pack('m').strip
end
return header
end
end
@ -781,11 +787,11 @@ module Net
def get( path, initheader = nil, dest = nil, &block )
res = nil
initheader = authorization(initheader)
request( Get.new(path,initheader) ) {|res|
res.read_body dest, &block
request(Get.new(path, initheader)) {|r|
r.read_body dest, &block
res = r
}
unless @newimpl then
unless @newimpl
res.value
return res, res.body
end
@ -794,19 +800,18 @@ module Net
end
def head( path, initheader = nil )
initheader = authorization(initheader)
res = request( Head.new(path,initheader) )
res = request(Head.new(path, initheader))
@newimpl or res.value
res
end
def post( path, data, initheader = nil, dest = nil, &block )
res = nil
initheader = authorization(initheader)
request( Post.new(path,initheader), data ) {|res|
res.read_body dest, &block
request(Post.new(path, initheader), data) {|r|
r.read_body dest, &block
res = r
}
unless @newimpl then
unless @newimpl
res.value
return res, res.body
end
@ -815,31 +820,26 @@ module Net
end
def put( path, data, initheader = nil )
initheader = authorization(initheader)
res = request( Put.new(path,initheader), data )
res = request(Put.new(path, initheader), data)
@newimpl or res.value
res
end
def request_get( path, initheader = nil, &block )
initheader = authorization(initheader)
request Get.new(path,initheader), &block
request Get.new(path, initheader), &block
end
def request_head( path, initheader = nil, &block )
initheader = authorization(initheader)
request Head.new(path,initheader), &block
request Head.new(path, initheader), &block
end
def request_post( path, data, initheader = nil, &block )
initheader = authorization(initheader)
request Post.new(path,initheader), data, &block
request Post.new(path, initheader), data, &block
end
def request_put( path, data, initheader = nil, &block )
initheader = authorization(initheader)
request Put.new(path,initheader), data, &block
request Put.new(path, initheader), data, &block
end
alias get2 request_get
@ -849,20 +849,21 @@ module Net
def send_request( name, path, body = nil, header = nil )
header = authorization(header)
r = HTTPGenericRequest.new( name, (body ? true : false), true,
path, header )
r = HTTPGenericRequest.new(name,(body ? true : false),true,path,header)
request r, body
end
def request( req, body = nil, &block )
unless started? then
unless started?
start {
req['connection'] = 'close'
return request(req, body, &block)
}
end
if proxy_user()
req.proxy_basic_auth proxy_user(), proxy_pass()
end
begin_transport req
req.exec @socket, @curr_http_version, edit_path(req.path), body
@ -880,27 +881,27 @@ module Net
private
def begin_transport( req )
if @socket.closed? then
if @socket.closed?
reconn_socket
end
if @seems_1_0_server then
if @seems_1_0_server
req['connection'] = 'close'
end
if not req.response_body_permitted? and @close_on_empty_response then
if not req.response_body_permitted? and @close_on_empty_response
req['connection'] = 'close'
end
req['host'] ||= addr_port()
req['host'] = addr_port()
end
def end_transport( req, res )
@curr_http_version = res.http_version
if not res.body and @close_on_empty_response then
if not res.body and @close_on_empty_response
D 'Conn close'
@socket.close
elsif keep_alive? req, res then
elsif keep_alive? req, res
D 'Conn keep-alive'
if @socket.closed? then
if @socket.closed?
D 'Conn (but seems 1.0 server)'
@seems_1_0_server = true
end
@ -935,7 +936,7 @@ module Net
end
def D( msg )
if @debug_output then
if @debug_output
@debug_output << msg
@debug_output << "\n"
end
@ -959,37 +960,37 @@ module Net
alias length size
def []( key )
@header[ key.downcase ]
@header[key.downcase]
end
def []=( key, val )
@header[ key.downcase ] = val
@header[key.downcase] = val
end
def fetch( key, *args, &block )
@header.fetch(key.downcase, *args, &block)
end
def each_header( &block )
@header.each( &block )
@header.each(&block)
end
alias each each_header
def each_key( &block )
@header.each_key( &block )
@header.each_key(&block)
end
def each_value( &block )
@header.each_value( &block )
@header.each_value(&block)
end
def delete( key )
@header.delete key.downcase
end
def fetch(*args)
@header.fetch(*args)
@header.delete(key.downcase)
end
def key?( key )
@header.key? key.downcase
@header.key?(key.downcase)
end
def to_hash
@ -1003,12 +1004,12 @@ module Net
end
def canonical( k )
k.split('-').collect {|i| i.capitalize }.join('-')
k.split(/-/).map {|i| i.capitalize }.join('-')
end
def range
s = @header['range'] or return nil
s.split(',').collect {|spec|
s.split(/,/).map {|spec|
m = /bytes\s*=\s*(\d+)?\s*-\s*(\d+)?/i.match(spec) or
raise HTTPHeaderSyntaxError, "wrong Range: #{spec}"
d1 = m[1].to_i
@ -1031,11 +1032,11 @@ module Net
when Range
first = r.first
last = r.last
if r.exclude_end? then
if r.exclude_end?
last -= 1
end
if last == -1 then
if last == -1
s = first > 0 ? "#{first}-" : "-#{-first}"
else
first >= 0 or raise HTTPHeaderSyntaxError, 'range.first is negative'
@ -1077,10 +1078,19 @@ module Net
r and r.length
end
def basic_auth( acc, pass )
@header['authorization'] = 'Basic ' + ["#{acc}:#{pass}"].pack('m').strip
def basic_auth( account, password )
@header['authorization'] = basic_encode(account, password)
end
def proxy_basic_auth( account, password )
header['proxy-authorization'] = basic_encode(account, password)
end
def basic_encode( account, password )
'Basic ' + ["#{account}:#{password}"].pack('m').strip
end
private :basic_encode
end
@ -1098,16 +1108,14 @@ module Net
@response_has_body = resbody
@path = path
@header = tmp = {}
@header = {}
return unless initheader
initheader.each do |k,v|
key = k.downcase
if tmp.key? key then
$stderr.puts "WARNING: duplicated HTTP header: #{k}" if $VERBOSE
end
tmp[ key ] = v.strip
$stderr.puts "net/http: WARNING: duplicated HTTP header: #{k}" if @header.key?(key) and $VERBOSE
@header[key] = v.strip
end
tmp['accept'] ||= '*/*'
@header['accept'] ||= '*/*'
end
attr_reader :method
@ -1133,8 +1141,8 @@ module Net
# internal use only
def exec( sock, ver, path, body )
if body then
check_body_premitted
if body
check_body_permitted
send_request_with_body sock, ver, path, body
else
request sock, ver, path
@ -1143,29 +1151,22 @@ module Net
private
def check_body_premitted
def check_body_permitted
request_body_permitted? or
raise ArgumentError, 'HTTP request body is not premitted'
raise ArgumentError, 'HTTP request body is not permitted'
end
def send_request_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['content-length'] = body.size.to_s
@header.delete 'transfer-encoding'
unless @header['content-type'] then
$stderr.puts 'Content-Type did not set; using application/x-www-form-urlencoded' if $VERBOSE
unless @header['content-type']
$stderr.puts 'net/http: WARNING: Content-Type did not set; using application/x-www-form-urlencoded' if $VERBOSE
@header['content-type'] = 'application/x-www-form-urlencoded'
end
request sock, ver, path
sock.write data
sock.write body
end
def request( sock, ver, path )
@ -1455,7 +1456,7 @@ module Net
httpv, code, msg = read_status_line(sock)
res = response_class(code).new(httpv, code, msg)
each_response_header(sock) do |k,v|
if res.key? k then
if res.key? k
res[k] << ', ' << v
else
res[k] = v
@ -1481,11 +1482,9 @@ module Net
end
def each_response_header( sock )
while true do
line = sock.readuntil( "\n", true ) # ignore EOF
line.sub!( /\s+\z/, '' ) # don't use chop!
while true
line = sock.readuntil("\n", true).sub(/\s+\z/, '')
break if line.empty?
m = /\A([^:]+):\s*/.match(line) or
raise HTTPBadResponse, 'wrong header line format'
yield m[1], m.post_match
@ -1533,7 +1532,7 @@ module Net
end
def value
HTTPSuccess === self or error!
error! unless HTTPSuccess === self
end
#
@ -1555,21 +1554,23 @@ module Net
def reading_body( sock, reqmethodallowbody )
@socket = sock
@body_exist = reqmethodallowbody && self.class.body_permitted?
yield
self.body
@socket = nil
begin
yield
self.body # ensure to read body
ensure
@socket = nil
end
end
def read_body( dest = nil, &block )
if @read then
(dest or block) and
raise IOError, "#{self.class}\#read_body called twice"
if @read
raise IOError, "#{self.class}\#read_body called twice" if dest or block
return @body
end
to = procdest(dest, block)
stream_check
if @body_exist then
if @body_exist
read_body_0 to
@body = to
else
@ -1586,15 +1587,15 @@ module Net
private
def read_body_0( dest )
if chunked? then
if chunked?
read_chunked dest
else
clen = content_length
if clen then
clen = content_length()
if clen
@socket.read clen, dest, true # ignore EOF
else
clen = range_length
if clen then
clen = range_length()
if clen
@socket.read clen, dest
else
@socket.read_all dest
@ -1607,28 +1608,28 @@ module Net
len = nil
total = 0
while true do
while true
line = @socket.readline
m = /[0-9a-fA-F]+/.match(line)
m or raise HTTPBadResponse, "wrong chunk size line: #{line}"
len = m[0].hex
hexlen = line.slice(/[0-9a-fA-F]+/) or
raise HTTPBadResponse, "wrong chunk size line: #{line}"
len = hexlen.hex
break if len == 0
@socket.read len, dest; total += len
@socket.read 2 # \r\n
end
until @socket.readline.empty? do
until @socket.readline.empty?
# none
end
end
def stream_check
@socket.closed? and raise IOError, 'try to read body out of block'
raise IOError, 'try to read body out of block' if @socket.closed?
end
def procdest( dest, block )
(dest and block) and
raise ArgumentError, 'both of arg and block are given for HTTP method'
if block then
raise ArgumentError, 'both of arg and block are given for HTTP method'\
if dest and block
if block
ReadAdapter.new(block)
else
dest || ''