lib/rufus/verbs/endpoint.rb in rufus-verbs-0.10 vs lib/rufus/verbs/endpoint.rb in rufus-verbs-1.0.0
- old
+ new
@@ -1,8 +1,7 @@
-#
#--
-# Copyright (c) 2008, John Mettraux, jmettraux@gmail.com
+# Copyright (c) 2008-2010, John Mettraux, jmettraux@gmail.com
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
@@ -18,22 +17,15 @@
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
#
-# (MIT license)
+# Made in Japan.
#++
-#
-#
-# John Mettraux
-#
-# Made in Japan
-#
-# 2008/01/11
-#
+require 'cgi'
require 'uri'
require 'yaml' # for StringIO (at least for now)
require 'net/http'
require 'zlib'
@@ -44,604 +36,606 @@
module Rufus
module Verbs
- USER_AGENT = "Ruby rufus-verbs #{VERSION}"
+ USER_AGENT = "Ruby rufus-verbs #{VERSION}"
+ #
+ # An EndPoint can be used to share common options among a set of
+ # requests.
+ #
+ # ep = EndPoint.new(
+ # :host => "restful.server",
+ # :port => 7080,
+ # :resource => "inventory/tools")
+ #
+ # res = ep.get :id => 1
+ # # still a silver bullet ?
+ #
+ # res = ep.get :id => 0
+ # # where did the hammer go ?
+ #
+ # When a request gets prepared, the option values will be looked up
+ # in (1) its local (request) options, then (2) in the EndPoint options.
+ #
+ class EndPoint
+
+ include CookieMixin
+ include DigestAuthMixin
+ include VerboseMixin
+
#
- # An EndPoint can be used to share common options among a set of
- # requests.
+ # The endpoint initialization opts (Hash instance)
#
- # ep = EndPoint.new(
- # :host => "restful.server",
- # :port => 7080,
- # :resource => "inventory/tools")
- #
- # res = ep.get :id => 1
- # # still a silver bullet ?
- #
- # res = ep.get :id => 0
- # # where did the hammer go ?
- #
- # When a request gets prepared, the option values will be looked up
- # in (1) its local (request) options, then (2) in the EndPoint options.
- #
- class EndPoint
+ attr_reader :opts
- include CookieMixin
- include DigestAuthMixin
- include VerboseMixin
+ def initialize (opts)
- #
- # The endpoint initialization opts (Hash instance)
- #
- attr_reader :opts
+ @opts = opts
- def initialize (opts)
+ compute_target @opts
- @opts = opts
+ @opts[:http_basic_authentication] =
+ opts[:http_basic_authentication] || opts[:hba]
- compute_target @opts
+ @opts[:user_agent] ||= USER_AGENT
- @opts[:http_basic_authentication] =
- opts[:http_basic_authentication] || opts[:hba]
+ @opts[:proxy] ||= ENV['HTTP_PROXY']
- @opts[:user_agent] ||= USER_AGENT
+ prepare_cookie_jar
+ end
- @opts[:proxy] ||= ENV['HTTP_PROXY']
+ def get (*args)
- prepare_cookie_jar
- end
+ request :get, args
+ end
- def get (*args)
+ def post (*args, &block)
- request :get, args
- end
+ request :post, args, &block
+ end
- def post (*args, &block)
+ def put (*args, &block)
- request :post, args, &block
- end
+ request :put, args, &block
+ end
- def put (*args, &block)
+ def delete (*args)
- request :put, args, &block
- end
+ request :delete, args
+ end
- def delete (*args)
+ def head (*args)
- request :delete, args
- end
+ request :head, args
+ end
- def head (*args)
+ def options (*args)
- request :head, args
- end
+ request :options, args
+ end
- def options (*args)
+ #
+ # This is the method called by the module methods verbs.
+ #
+ # For example,
+ #
+ # RufusVerbs.get(args)
+ #
+ # calls
+ #
+ # RufusVerbs::EndPoint.request(:get, args)
+ #
+ def self.request (method, args, &block)
- request :options, args
- end
+ opts = extract_opts args
- #
- # This is the method called by the module methods verbs.
- #
- # For example,
- #
- # RufusVerbs.get(args)
- #
- # calls
- #
- # RufusVerbs::EndPoint.request(:get, args)
- #
- def self.request (method, args, &block)
+ EndPoint.new(opts).request(method, opts, &block)
+ end
- opts = extract_opts args
+ #
+ # The instance methods get, post, put and delete ultimately calls
+ # this request() method. All the work is done here.
+ #
+ def request (method, args, &block)
- EndPoint.new(opts).request(method, opts, &block)
- end
+ # prepare request
- #
- # The instance methods get, post, put and delete ultimately calls
- # this request() method. All the work is done here.
- #
- def request (method, args, &block)
+ opts = EndPoint.extract_opts args
- # prepare request
+ compute_target opts
- opts = EndPoint.extract_opts args
+ req = create_request method, opts
- compute_target opts
+ add_payload(req, opts, &block) if method == :post or method == :put
- req = create_request method, opts
+ add_authentication(req, opts)
- add_payload(req, opts, &block) if method == :post or method == :put
+ add_conditional_headers(req, opts) if method == :get
- add_authentication(req, opts)
+ mention_cookies(req, opts)
+ # if the :cookies option is disabled (the default)
+ # will have no effect
- add_conditional_headers(req, opts) if method == :get
+ vlog_request opts, req
- mention_cookies(req, opts)
- # if the :cookies option is disabled (the default)
- # will have no effect
+ return req if o(opts, :dry_run) == true
- vlog_request opts, req
+ # trigger request
- return req if o(opts, :dry_run) == true
+ http = prepare_http opts
- # trigger request
+ vlog_http opts, http
- http = prepare_http opts
+ res = nil
- vlog_http opts, http
+ http.start do
+ res = http.request req
+ end
- res = nil
+ # handle response
- http.start do
- res = http.request req
- end
+ class << res
+ attr_accessor :request
+ end
+ res.request = req
- # handle response
+ vlog_response opts, res
- class << res
- attr_accessor :request
- end
- res.request = req
+ register_cookies res, opts
+ # if the :cookies option is disabled (the default)
+ # will have no effect
- vlog_response opts, res
+ return res if o(opts, :raw_response)
- register_cookies res, opts
- # if the :cookies option is disabled (the default)
- # will have no effect
+ check_authentication_info res, opts
+ # used in case of :digest_authentication
+ # will have no effect else
- return res if o(opts, :raw_response)
+ res = handle_response method, res, opts
- check_authentication_info res, opts
- # used in case of :digest_authentication
- # will have no effect else
+ return parse_options(res) if method == :options
- res = handle_response method, res, opts
+ return res.body if o(opts, :body)
- return parse_options(res) if method == :options
+ res
+ end
- return res.body if o(opts, :body)
+ private
- res
- end
+ #
+ # Manages various args formats :
+ #
+ # uri
+ # [ uri ]
+ # [ uri, opts ]
+ # opts
+ #
+ def self.extract_opts (args)
- private
+ opts = {}
- #
- # Manages various args formats :
- #
- # uri
- # [ uri ]
- # [ uri, opts ]
- # opts
- #
- def self.extract_opts (args)
+ args = [ args ] unless args.is_a?(Array)
- opts = {}
+ opts = args.last \
+ if args.last.is_a?(Hash)
- args = [ args ] unless args.is_a?(Array)
+ opts[:uri] = args.first \
+ if args.first.is_a?(String) or args.first.is_a?(URI)
- opts = args.last \
- if args.last.is_a?(Hash)
+ opts
+ end
- opts[:uri] = args.first \
- if args.first.is_a?(String) or args.first.is_a?(URI)
+ #
+ # Returns the value from the [request] opts or from the
+ # [endpoint] @opts.
+ #
+ def o (opts, key)
- opts
- end
+ keys = Array key
+ keys.each { |k| (v = opts[k]; return v if v != nil) }
+ keys.each { |k| (v = @opts[k]; return v if v != nil) }
+ nil
+ end
- #
- # Returns the value from the [request] opts or from the
- # [endpoint] @opts.
- #
- def o (opts, key)
+ #
+ # Returns scheme, host, port, path, query
+ #
+ def compute_target (opts)
- keys = Array key
- keys.each { |k| (v = opts[k]; return v if v != nil) }
- keys.each { |k| (v = @opts[k]; return v if v != nil) }
- nil
- end
+ u = opts[:uri] || opts[:u]
- #
- # Returns scheme, host, port, path, query
- #
- def compute_target (opts)
+ r = if opts[:host]
- u = opts[:uri] || opts[:u]
+ [ opts[:scheme] || 'http',
+ opts[:host],
+ opts[:port] || 80,
+ opts[:path] || '/',
+ opts[:query] || opts[:params] ]
- r = if opts[:host]
+ elsif u
- [ opts[:scheme] || 'http',
- opts[:host],
- opts[:port] || 80,
- opts[:path] || '/',
- opts[:query] || opts[:params] ]
+ u = URI.parse u.to_s unless u.is_a?(URI)
+ [ u.scheme,
+ u.host,
+ u.port,
+ u.path,
+ query_to_h(u.query) ]
+ else
- elsif u
+ []
+ end
- u = URI.parse u.to_s unless u.is_a?(URI)
- [ u.scheme,
- u.host,
- u.port,
- u.path,
- query_to_h(u.query) ]
- else
+ opts[:scheme] = r[0] || @opts[:scheme]
+ opts[:host] = r[1] || @opts[:host]
+ opts[:port] = r[2] || @opts[:port]
+ opts[:path] = r[3] || @opts[:path]
- []
- end
+ opts[:query] =
+ r[4] ||
+ opts[:params] || opts[:query] ||
+ @opts[:query] || @opts[:params] ||
+ {}
- opts[:scheme] = r[0] || @opts[:scheme]
- opts[:host] = r[1] || @opts[:host]
- opts[:port] = r[2] || @opts[:port]
- opts[:path] = r[3] || @opts[:path]
+ opts.delete :path if opts[:path] == ''
- opts[:query] =
- r[4] ||
- opts[:params] || opts[:query] ||
- @opts[:query] || @opts[:params] ||
- {}
+ opts[:c_uri] = [
+ opts[:scheme],
+ opts[:host],
+ opts[:port],
+ opts[:path],
+ opts[:query] ].inspect
+ #
+ # can be used for conditional gets
- opts.delete :path if opts[:path] == ""
+ r
+ end
- opts[:c_uri] = [
- opts[:scheme],
- opts[:host],
- opts[:port],
- opts[:path],
- opts[:query] ].inspect
- #
- # can be used for conditional gets
+ #
+ # Creates the Net::HTTP request instance.
+ #
+ # If :fake_put is set, will use Net::HTTP::Post
+ # and make sure the query string contains '_method=put' (or
+ # '_method=delete').
+ #
+ # This call will also advertise this rufus-verbs as
+ # 'accepting the gzip encoding' (in case of GET).
+ #
+ def create_request (method, opts)
- r
- end
+ if (o(opts, :fake_put) and
+ (method == :put or method == :delete))
- #
- # Creates the Net::HTTP request instance.
- #
- # If :fake_put is set, will use Net::HTTP::Post
- # and make sure the query string contains '_method=put' (or
- # '_method=delete').
- #
- # This call will also advertise this rufus-verbs as
- # 'accepting the gzip encoding' (in case of GET).
- #
- def create_request (method, opts)
+ opts[:query][:_method] = method.to_s
+ method = :post
+ end
- if (o(opts, :fake_put) and
- (method == :put or method == :delete))
+ path = compute_path opts
- opts[:query][:_method] = method.to_s
- method = :post
- end
+ r = eval("Net::HTTP::#{method.to_s.capitalize}").new path
- path = compute_path opts
+ r['User-Agent'] = o(opts, :user_agent)
+ # potentially overriden by opts[:headers]
- r = eval("Net::HTTP::#{method.to_s.capitalize}").new path
+ h = opts[:headers] || opts[:h]
+ h.each { |k, v| r[k] = v } if h
- r['User-Agent'] = o(opts, :user_agent)
- # potentially overriden by opts[:headers]
+ r['Accept-Encoding'] = 'gzip' \
+ if method == :get and not o(opts, :nozip)
- h = opts[:headers] || opts[:h]
- h.each { |k, v| r[k] = v } if h
+ r
+ end
- r['Accept-Encoding'] = 'gzip' \
- if method == :get and not o(opts, :nozip)
+ #
+ # If @user and @pass are set, will activate basic authentication.
+ # Else if the @auth option is set, will assume it contains a Proc
+ # and will call it (with the request as a parameter).
+ #
+ # This comment is too much... Just read the code...
+ #
+ def add_authentication (req, opts)
- r
- end
+ b = o(opts, :http_basic_authentication)
+ d = o(opts, :digest_authentication)
+ o = o(opts, :auth)
- #
- # If @user and @pass are set, will activate basic authentication.
- # Else if the @auth option is set, will assume it contains a Proc
- # and will call it (with the request as a parameter).
- #
- # This comment is too much... Just read the code...
- #
- def add_authentication (req, opts)
+ if b and b != false
- b = o(opts, :http_basic_authentication)
- d = o(opts, :digest_authentication)
- o = o(opts, :auth)
+ req.basic_auth b[0], b[1]
- if b and b != false
+ elsif d and d != false
- req.basic_auth b[0], b[1]
+ digest_auth req, opts
- elsif d and d != false
+ elsif o and o != false
- digest_auth req, opts
+ o.call req
+ end
+ end
- elsif o and o != false
+ #
+ # In that base class, it's empty.
+ # It's implemented in ConditionalEndPoint.
+ #
+ # Only called for a GET.
+ #
+ def add_conditional_headers (req, opts)
- o.call req
- end
- end
+ # nada
+ end
- #
- # In that base class, it's empty.
- # It's implemented in ConditionalEndPoint.
- #
- # Only called for a GET.
- #
- def add_conditional_headers (req, opts)
+ #
+ # Prepares a Net::HTTP instance, with potentially some
+ # https settings.
+ #
+ def prepare_http (opts)
- # nada
- end
+ compute_proxy opts
- #
- # Prepares a Net::HTTP instance, with potentially some
- # https settings.
- #
- def prepare_http (opts)
+ http = Net::HTTP.new(
+ opts[:host], opts[:port],
+ opts[:proxy_host], opts[:proxy_port],
+ opts[:proxy_user], opts[:proxy_pass])
- compute_proxy opts
+ set_timeout http, opts
- http = Net::HTTP.new(
- opts[:host], opts[:port],
- opts[:proxy_host], opts[:proxy_port],
- opts[:proxy_user], opts[:proxy_pass])
+ return http unless opts[:scheme].to_s == 'https'
- set_timeout http, opts
+ require 'net/https'
- return http unless opts[:scheme] == 'https'
+ http.use_ssl = true
+ http.enable_post_connection_check = true \
+ if http.respond_to?(:enable_post_connection_check=)
- require 'net/https'
+ http.verify_mode = if o(opts, :ssl_verify_peer)
+ OpenSSL::SSL::VERIFY_PEER
+ else
+ OpenSSL::SSL::VERIFY_NONE
+ end
- http.use_ssl = true
- http.enable_post_connection_check = true
+ store = OpenSSL::X509::Store.new
+ store.set_default_paths
+ http.cert_store = store
- http.verify_mode = if o(opts, :ssl_verify_peer)
- OpenSSL::SSL::VERIFY_PEER
- else
- OpenSSL::SSL::VERIFY_NONE
- end
+ http
+ end
- store = OpenSSL::X509::Store.new
- store.set_default_paths
- http.cert_store = store
+ #
+ # Sets both the open_timeout and the read_timeout for the http
+ # instance
+ #
+ def set_timeout (http, opts)
- http
- end
+ to = o(opts, :timeout) || o(opts, :to)
+ to = to.to_i
- #
- # Sets both the open_timeout and the read_timeout for the http
- # instance
- #
- def set_timeout (http, opts)
+ return if to == 0
- to = o(opts, :timeout) || o(opts, :to)
- to = to.to_i
+ http.open_timeout = to
+ http.read_timeout = to
+ end
- return if to == 0
+ #
+ # Makes sure the request opts hold the proxy information.
+ #
+ # If the option :proxy is set to false, no proxy will be used.
+ #
+ def compute_proxy (opts)
- http.open_timeout = to
- http.read_timeout = to
- end
+ p = o(opts, :proxy)
- #
- # Makes sure the request opts hold the proxy information.
- #
- # If the option :proxy is set to false, no proxy will be used.
- #
- def compute_proxy (opts)
+ return unless p
- p = o(opts, :proxy)
+ u = URI.parse p.to_s
- return unless p
+ raise "not an HTTP[S] proxy '#{u.host}'" \
+ unless u.scheme.match(/^http/)
- u = URI.parse p.to_s
+ opts[:proxy_host] = u.host
+ opts[:proxy_port] = u.port
+ opts[:proxy_user] = u.user
+ opts[:proxy_pass] = u.password
+ end
- raise "not an HTTP[S] proxy '#{u.host}'" \
- unless u.scheme.match(/^http/)
+ #
+ # Determines the full path of the request (path_info and
+ # query_string).
+ #
+ # For example :
+ #
+ # /items/4?style=whatever&maxcount=12
+ #
+ def compute_path (opts)
- opts[:proxy_host] = u.host
- opts[:proxy_port] = u.port
- opts[:proxy_user] = u.user
- opts[:proxy_pass] = u.password
- end
+ b = o(opts, :base)
+ r = o(opts, [ :res, :resource ])
+ i = o(opts, :id)
- #
- # Determines the full path of the request (path_info and
- # query_string).
- #
- # For example :
- #
- # /items/4?style=whatever&maxcount=12
- #
- def compute_path (opts)
+ path = o(opts, :path)
- b = o(opts, :base)
- r = o(opts, [ :res, :resource ])
- i = o(opts, :id)
+ if b or r or i
+ path = b ? "/#{b}" : ''
+ path += "/#{r}" if r
+ path += "/#{i}" if i
+ end
- path = o(opts, :path)
+ path = path[1..-1] if path[0..1] == '//'
- if b or r or i
- path = ""
- path = "/#{b}" if b
- path += "/#{r}" if r
- path += "/#{i}" if i
- end
+ query = opts[:query] || opts[:params]
- path = path[1..-1] if path[0..1] == '//'
+ return path if not query or query.size < 1
- query = opts[:query] || opts[:params]
+ path + '?' + h_to_query(query, opts)
+ end
- return path if not query or query.size < 1
+ #
+ # "a=A&b=B" -> { "a" => "A", "b" => "B" }
+ #
+ def query_to_h (q)
- path + '?' + h_to_query(query, opts)
- end
+ return nil unless q
- #
- # "a=A&b=B" -> { "a" => "A", "b" => "B" }
- #
- def query_to_h (q)
+ q.split('&').inject({}) do |r, e|
+ s = e.split('=')
+ r[s[0]] = s[1]
+ r
+ end
+ end
- return nil unless q
+ #
+ # { "a" => "A", "b" => "B" } -> "a=A&b=B"
+ #
+ def h_to_query (h, opts)
- q.split("&").inject({}) do |r, e|
- s = e.split("=")
- r[s[0]] = s[1]
- r
- end
- end
+ h.entries.collect { |k, v|
+ unless o(opts, :no_escape)
+ #k = URI.escape k.to_s
+ #v = URI.escape v.to_s
+ k = CGI.escape(k.to_s)
+ v = CGI.escape(v.to_s)
+ end
+ "#{k}=#{v}"
+ }.join('&')
+ end
- #
- # { "a" => "A", "b" => "B" } -> "a=A&b=B"
- #
- def h_to_query (h, opts)
+ #
+ # Fills the request body (with the content of :d or :fd).
+ #
+ def add_payload (req, opts, &block)
- h.entries.collect { |k, v|
- unless o(opts, :no_escape)
- k = URI.escape k.to_s
- v = URI.escape v.to_s
- end
- "#{k}=#{v}"
- }.join("&")
- end
+ d = opts[:d] || opts[:data]
+ fd = opts[:fd] || opts[:form_data]
- #
- # Fills the request body (with the content of :d or :fd).
- #
- def add_payload (req, opts, &block)
+ if d
+ req.body = d
+ elsif fd
+ sep = opts[:fd_sep] #|| nil
+ req.set_form_data fd, sep
+ elsif block
+ req.body = block.call req
+ else
+ req.body = ''
+ end
+ end
- d = opts[:d] || opts[:data]
- fd = opts[:fd] || opts[:form_data]
+ #
+ # Handles the server response.
+ # Eventually follows redirections.
+ #
+ # Once the final response has been hit, will make sure
+ # it's decompressed.
+ #
+ def handle_response (method, res, opts)
- if d
- req.body = d
- elsif fd
- sep = opts[:fd_sep] #|| nil
- req.set_form_data fd, sep
- elsif block
- req.body = block.call req
- else
- req.body = ""
- end
- end
+ nored = o(opts, [ :no_redirections, :noredir ])
- #
- # Handles the server response.
- # Eventually follows redirections.
- #
- # Once the final response has been hit, will make sure
- # it's decompressed.
- #
- def handle_response (method, res, opts)
+ #if res.is_a?(Net::HTTPRedirection)
+ if [ 301, 302, 303, 307 ].include?(res.code.to_i) and (nored != true)
- nored = o(opts, [ :no_redirections, :noredir ])
+ maxr = o(opts, :max_redirections)
- #if res.is_a?(Net::HTTPRedirection)
- if [ 301, 303, 307 ].include?(res.code.to_i) and (nored != true)
+ if maxr
+ maxr = maxr - 1
+ raise 'too many redirections' if maxr == -1
+ opts[:max_redirections] = maxr
+ end
- maxr = o(opts, :max_redirections)
+ location = res['Location']
- if maxr
- maxr = maxr - 1
- raise "too many redirections" if maxr == -1
- opts[:max_redirections] = maxr
- end
+ prev_host = [ opts[:scheme], opts[:host] ]
- location = res['Location']
+ if location.match /^http/
+ u = URI::parse location
+ opts[:scheme] = u.scheme
+ opts[:host] = u.host
+ opts[:port] = u.port
+ opts[:path] = u.path
+ opts[:query] = u.query
+ else
+ opts[:path], opts[:query] = location.split "?"
+ end
- prev_host = [ opts[:scheme], opts[:host] ]
+ if (authentication_is_on?(opts) and
+ [ opts[:scheme], opts[:host] ] != prev_host)
- if location.match /^http/
- u = URI::parse location
- opts[:scheme] = u.scheme
- opts[:host] = u.host
- opts[:port] = u.port
- opts[:path] = u.path
- opts[:query] = u.query
- else
- opts[:path], opts[:query] = location.split "?"
- end
+ raise(
+ "getting redirected to #{location} while " +
+ "authentication is on. Stopping.")
+ end
- if (authentication_is_on?(opts) and
- [ opts[:scheme], opts[:host] ] != prev_host)
+ opts[:query] = query_to_h opts[:query]
- raise(
- "getting redirected to #{location} while " +
- "authentication is on. Stopping.")
- end
+ return request(method, opts)
+ #
+ # following the redirection
+ end
- opts[:query] = query_to_h opts[:query]
+ decompress res
- return request(method, opts)
- #
- # following the redirection
- end
+ res
+ end
- decompress res
+ #
+ # Returns an array of symbols, like for example
+ #
+ # [ :get, :post ]
+ #
+ # obtained by parsing the 'Allow' response header.
+ #
+ # This method is used to provide the result of an OPTIONS
+ # HTTP method.
+ #
+ def parse_options (res)
- res
- end
+ s = res['Allow']
- #
- # Returns an array of symbols, like for example
- #
- # [ :get, :post ]
- #
- # obtained by parsing the 'Allow' response header.
- #
- # This method is used to provide the result of an OPTIONS
- # HTTP method.
- #
- def parse_options (res)
+ return [] unless s
- s = res['Allow']
+ s.split(',').collect do |m|
+ m.strip.downcase.to_sym
+ end
+ end
- return [] unless s
+ #
+ # Returns true if the current request has authentication
+ # going on.
+ #
+ def authentication_is_on? (opts)
- s.split(",").collect do |m|
- m.strip.downcase.to_sym
- end
- end
+ (o(opts, [ :http_basic_authentication, :hba, :auth ]) != nil)
+ end
- #
- # Returns true if the current request has authentication
- # going on.
- #
- def authentication_is_on? (opts)
+ #
+ # Inflates the response body if necessary.
+ #
+ def decompress (res)
- (o(opts, [ :http_basic_authentication, :hba, :auth ]) != nil)
- end
+ if res['content-encoding'] == 'gzip'
- #
- # Inflates the response body if necessary.
- #
- def decompress (res)
+ class << res
- if res['content-encoding'] == 'gzip'
+ attr_accessor :deflated_body
- class << res
+ alias :old_body :body
- attr_accessor :deflated_body
+ def body
+ @deflated_body || old_body
+ end
+ end
+ #
+ # reopened the response to add
+ # a 'deflated_body' attr and let the the body
+ # method point to it
- alias :old_body :body
+ # now deflate...
- def body
- @deflated_body || old_body
- end
- end
- #
- # reopened the response to add
- # a 'deflated_body' attr and let the the body
- # method point to it
-
- # now deflate...
-
- io = StringIO.new res.body
- gz = Zlib::GzipReader.new io
- res.deflated_body = gz.read
- gz.close
- end
- end
+ io = StringIO.new res.body
+ gz = Zlib::GzipReader.new io
+ res.deflated_body = gz.read
+ gz.close
+ end
end
+ end
end
end