lib/httpclient.rb in httpclient-2.5.1 vs lib/httpclient.rb in httpclient-2.5.2
- old
+ new
@@ -322,10 +322,12 @@
# HTTPClient::WWWAuth:: WWW authentication handler.
attr_reader :www_auth
# 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
# 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)
@@ -360,31 +362,40 @@
# Default User-Agent header
DEFAULT_AGENT_NAME = 'HTTPClient/1.0'
# Creates a HTTPClient instance which manages sessions, cookies, etc.
#
- # HTTPClient.new takes 3 optional arguments for proxy url string,
- # User-Agent String and From header String. User-Agent and From are embedded
- # in HTTP request Header if given. No User-Agent and From header added
- # without setting it explicitly.
+ # 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
+ # * :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)
#
- # You can use a keyword argument style Hash. Keys are :proxy, :agent_name
- # and :from.
+ # 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.
#
- # HTTPClient.new(:agent_name => 'MyAgent/0.1')
def initialize(*args)
- proxy, agent_name, from = keyword_argument(args, :proxy, :agent_name, :from)
+ proxy, agent_name, from, base_url, force_basic_auth =
+ keyword_argument(args, :proxy, :agent_name, :from, :base_url, :force_basic_auth)
@proxy = nil # assigned later.
@no_proxy = nil
@no_proxy_regexps = []
+ @base_url = base_url
@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
@redirect_uri_callback = method(:default_redirect_uri_callback)
@test_loopback_response = []
@session_manager = SessionManager.new(self)
@@ -507,18 +518,18 @@
# clnt.set_auth('http://www.example.com/foo/', 'foo_user', 'passwd')
# clnt.set_auth('http://www.example.com/bar/', 'bar_user', 'passwd')
#
# Calling this method resets all existing sessions.
def set_auth(domain, user, passwd)
- uri = urify(domain)
+ uri = to_resource_url(domain)
@www_auth.set_auth(uri, user, passwd)
reset_all
end
# Deprecated. Use set_auth instead.
def set_basic_auth(domain, user, passwd)
- uri = urify(domain)
+ uri = to_resource_url(domain)
@www_auth.basic_auth.set(uri, user, passwd)
reset_all
end
# Sets credential for Proxy authentication.
@@ -529,10 +540,18 @@
def set_proxy_auth(user, passwd)
@proxy_auth.set_auth(user, passwd)
reset_all
end
+ # Turn 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 force_basic_auth=(force_basic_auth)
+ @www_auth.basic_auth.force_auth = @proxy_auth.basic_auth.force_auth = force_basic_auth
+ end
+
# Sets the filename where non-volatile Cookies be saved by calling
# save_cookie_store.
# This method tries to load and managing Cookies from the specified file.
#
# Calling this method resets all existing sessions.
@@ -776,11 +795,11 @@
if method == :propfind
header ||= PROPFIND_DEFAULT_EXTHEADER
else
header ||= {}
end
- uri = urify(uri)
+ uri = to_resource_url(uri)
if block
if block.arity == 1
filtered_block = proc { |res, str|
block.call(str)
}
@@ -796,19 +815,17 @@
end
# Sends HEAD request in async style. See request_async for arguments.
# It immediately returns a HTTPClient::Connection instance as a result.
def head_async(uri, *args)
- query, header = keyword_argument(args, :query, :header)
- request_async(:head, uri, query, nil, header || {})
+ request_async2(:head, uri, argument_to_hash(args, :query, :header))
end
# Sends GET request in async style. See request_async for arguments.
# It immediately returns a HTTPClient::Connection instance as a result.
def get_async(uri, *args)
- query, header = keyword_argument(args, :query, :header)
- request_async(:get, uri, query, nil, header || {})
+ request_async2(:get, uri, argument_to_hash(args, :query, :header))
end
# Sends POST request in async style. See request_async for arguments.
# It immediately returns a HTTPClient::Connection instance as a result.
def post_async(uri, *args)
@@ -864,11 +881,11 @@
# Sends a request in async style. request method creates new Thread for
# HTTP connection and returns a HTTPClient::Connection instance immediately.
#
# Arguments definition is the same as request.
def request_async(method, uri, query = nil, body = nil, header = {})
- uri = urify(uri)
+ uri = to_resource_url(uri)
do_request_async(method, uri, query, body, header)
end
# new method that has same signature as 'request'
def request_async2(method, uri, *args)
@@ -879,18 +896,18 @@
if method == :propfind
header ||= PROPFIND_DEFAULT_EXTHEADER
else
header ||= {}
end
- uri = urify(uri)
+ uri = to_resource_url(uri)
do_request_async(method, uri, query, body, header)
end
# Resets internal session for the given URL. Keep-alive connection for the
# site (host-port pair) is disconnected if exists.
def reset(uri)
- uri = urify(uri)
+ uri = to_resource_url(uri)
@session_manager.reset(uri)
end
# Resets all of internal sessions. Keep-alive connections are disconnected.
def reset_all
@@ -963,12 +980,12 @@
break
rescue RetryableResponse
retry_count -= 1
end
end
- rescue Exception
- conn.push $!
+ rescue Exception => e
+ conn.push e
end
}
conn.async_thread = t
conn
end
@@ -990,11 +1007,11 @@
def getenv(name)
ENV[name.downcase] || ENV[name.upcase]
end
def follow_redirect(method, uri, query, body, header, &block)
- uri = urify(uri)
+ uri = to_resource_url(uri)
if block
filtered_block = proc { |r, str|
block.call(str) if r.ok?
}
end
@@ -1198,7 +1215,16 @@
@debug_dev << res
end
def set_encoding(str, encoding)
str.force_encoding(encoding) if encoding
+ end
+
+ def to_resource_url(uri)
+ u = urify(uri)
+ if @base_url && u.scheme.nil? && u.host.nil?
+ urify(@base_url + uri)
+ else
+ u
+ end
end
end