    # File lib/rbot/core/utils/httputil.rb, line 483
      def get_response(uri_or_s, options = {}, &block) # :yields: resp
        uri = uri_or_s.kind_of?(URI) ? uri_or_s : URI.parse(uri_or_s.to_s)
        opts = {
          :max_redir => @bot.config['http.max_redir'],
          :yield => :final,
          :cache => true,
          :method => :GET
        }.merge(options)

        resp = nil
        cached = nil

        req_class = case opts[:method].to_s.downcase.intern
                    when :head, "net::http::head""net::http::head"
                      opts[:max_redir] = -1
                      Net::HTTP::Head
                    when :get, "net::http::get""net::http::get"
                      Net::HTTP::Get
                    when :post, "net::http::post""net::http::post"
                      opts[:cache] = false
                      opts[:body] or raise 'post request w/o a body?'
                      warning "refusing to cache POST request" if options[:cache]
                      Net::HTTP::Post
                    else
                      warning "unsupported method #{opts[:method]}, doing GET"
                      Net::HTTP::Get
                    end

        if req_class != Net::HTTP::Get && opts[:range]
          warning "can't request ranges for #{req_class}"
          opts.delete(:range)
        end

        cache_key = "#{opts[:range]}|#{req_class}|#{uri.to_s}"

        if req_class != Net::HTTP::Get && req_class != Net::HTTP::Head
          if opts[:cache]
            warning "can't cache #{req_class.inspect} requests, working w/o cache"
            opts[:cache] = false
          end
        end

        debug "get_response(#{uri}, #{opts.inspect})"

        if opts[:cache] && cached = @cache[cache_key]
          debug "got cached"
          if !cached.expired?
            debug "using cached"
            cached.use
            return handle_response(uri, cached.response, opts, &block)
          end
        end

        headers = @headers.dup.merge(opts[:headers] || {})
        headers['Range'] = opts[:range] if opts[:range]
        headers['Authorization'] = opts[:auth_head] if opts[:auth_head]

        cached.setup_headers(headers) if cached && (req_class == Net::HTTP::Get)
        req = req_class.new(uri.request_uri, headers)
        if uri.user && uri.password
          req.basic_auth(uri.user, uri.password)
          opts[:auth_head] = req['Authorization']
        end
        req.body = opts[:body] if req_class == Net::HTTP::Post
        debug "prepared request: #{req.to_hash.inspect}"

        begin
        get_proxy(uri, opts).start do |http|
          http.request(req) do |resp|
            resp['x-rbot-location'] = uri.to_s
            if Net::HTTPNotModified === resp
              debug "not modified"
              begin
                cached.revalidate(resp)
              rescue Exception => e
                error e
              end
              debug "reusing cached"
              resp = cached.response
            elsif Net::HTTPServerError === resp || Net::HTTPClientError === resp
              debug "http error, deleting cached obj" if cached
              @cache.delete(cache_key)
            elsif opts[:cache]
              begin
                return handle_response(uri, resp, opts, &block)
              ensure
                if cached = CachedObject.maybe_new(resp) rescue nil
                  debug "storing to cache"
                  @cache[cache_key] = cached
                end
              end
              return ret
            end
            return handle_response(uri, resp, opts, &block)
          end
        end
        rescue Exception => e
          error e
          raise e.message
        end
      end