# 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