lib/httpclient.rb in httpclient-2.5.2 vs lib/httpclient.rb in httpclient-2.5.3
- old
+ new
@@ -324,10 +324,12 @@
# How many times get_content and post_content follows HTTP redirect.
# 10 by default.
attr_accessor :follow_redirect_count
# Base url of resources.
attr_accessor :base_url
+ # Defalut request header.
+ attr_accessor :default_header
# Set HTTP version as a String:: 'HTTP/1.0' or 'HTTP/1.1'
attr_proxy(:protocol_version, true)
# Connect timeout in sec.
attr_proxy(:connect_timeout, true)
@@ -367,32 +369,43 @@
# HTTPClient.new takes optional arguments as a Hash.
# * :proxy - proxy url string
# * :agent_name - User-Agent String
# * :from - from header String
# * :base_url - base URL of resources
+ # * :default_header - header Hash all HTTP requests should have
# * :force_basic_auth - flag for sending Authorization header w/o gettin 401 first
# User-Agent and From are embedded in HTTP request Header if given.
# From header is not set without setting it explicitly.
#
# proxy = 'http://myproxy:8080'
# agent_name = 'MyAgent/0.1'
# from = 'from@example.com'
# HTTPClient.new(proxy, agent_name, from)
#
- # After you set base_url, all resources you pass to get, post and other
+ # After you set :base_url, all resources you pass to get, post and other
# methods are recognized to be prefixed with base_url. Say base_url is
# 'https://api.example.com/v1, get('/users') is the same as
# get('https://api.example.com/v1/users') internally. You can also pass
# full URL from 'http://' even after setting base_url.
#
+ # :default_header is for providing default headers Hash that all HTTP
+ # requests should have, such as custom 'Authorization' header in API.
+ # You can override :default_header with :header Hash parameter in HTTP
+ # request methods.
+ #
+ # :force_basic_auth turns on/off the BasicAuth force flag. Generally
+ # HTTP client must send Authorization header after it gets 401 error
+ # from server from security reason. But in some situation (e.g. API
+ # client) you might want to send Authorization from the beginning.
def initialize(*args)
- proxy, agent_name, from, base_url, force_basic_auth =
- keyword_argument(args, :proxy, :agent_name, :from, :base_url, :force_basic_auth)
+ proxy, agent_name, from, base_url, default_header, force_basic_auth =
+ keyword_argument(args, :proxy, :agent_name, :from, :base_url, :default_header, :force_basic_auth)
@proxy = nil # assigned later.
@no_proxy = nil
@no_proxy_regexps = []
@base_url = base_url
+ @default_header = default_header || {}
@www_auth = WWWAuth.new
@proxy_auth = ProxyAuth.new
@www_auth.basic_auth.force_auth = @proxy_auth.basic_auth.force_auth = force_basic_auth
@request_filter = [@proxy_auth, @www_auth]
@debug_dev = nil
@@ -787,13 +800,10 @@
# chunked encoding (Transfer-Encoding: chunked in HTTP header) if IO does not
# respond to :size. Bear in mind that some server application does not support
# chunked request. At least cgi.rb does not support it.
def request(method, uri, *args, &block)
query, body, header, follow_redirect = keyword_argument(args, :query, :body, :header, :follow_redirect)
- if [:post, :put].include?(method)
- body ||= ''
- end
if method == :propfind
header ||= PROPFIND_DEFAULT_EXTHEADER
else
header ||= {}
end
@@ -946,11 +956,11 @@
proxy = no_proxy?(uri) ? nil : @proxy
while retry_count > 0
body.pos = pos if pos
req = create_request(method, uri, query, body, header)
begin
- protect_keep_alive_disconnected do
+ protect_keep_alive_disconnected(req) do
do_get_block(req, proxy, conn, &block)
end
res = conn.pop
break
rescue RetryableResponse
@@ -972,11 +982,11 @@
proxy = no_proxy?(uri) ? nil : @proxy
while retry_count > 0
body.pos = pos if pos
req = create_request(method, uri, query, body, header)
begin
- protect_keep_alive_disconnected do
+ protect_keep_alive_disconnected(req) do
do_get_stream(req, proxy, tconn)
end
break
rescue RetryableResponse
retry_count -= 1
@@ -1021,10 +1031,13 @@
retry_number = 0
while retry_number < @follow_redirect_count
body.pos = pos if pos
res = do_request(method, uri, query, body, header, &filtered_block)
if res.redirect?
+ if res.header['location'].empty?
+ raise BadResponseError.new("Missing Location header for redirect", res)
+ end
method = :get if res.see_other? # See RFC2616 10.3.4
uri = urify(@redirect_uri_callback.call(uri, res))
retry_number += 1
else
return res
@@ -1039,26 +1052,26 @@
else
raise BadResponseError.new("unexpected response: #{res.header.inspect}", res)
end
end
- def protect_keep_alive_disconnected
+ def protect_keep_alive_disconnected(req)
begin
yield
rescue KeepAliveDisconnected => e
if e.sess
@session_manager.invalidate(e.sess.dest)
end
- yield
+ yield if req.use_persistent_connection?
end
end
def create_request(method, uri, query, body, header)
method = method.to_s.upcase
if header.is_a?(Hash)
- header = header.to_a
+ header = @default_header.merge(header).to_a
else
- header = header.dup
+ header = @default_header.to_a + header.dup
end
boundary = nil
if body
_, content_type = header.find { |key, value|
key.downcase == 'content-type'