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'