# File lib/ftw/agent.rb, line 278
  def execute(request)
    # TODO(sissel): Make redirection-following optional, but default.

    tries = 3
    begin
      connection, error = connect(request.headers["Host"], request.port,
                                  request.protocol == "https")
      if !error.nil?
        p :error => error
        raise error
      end
      response = request.execute(connection)
    rescue EOFError => e
      tries -= 1
      @logger.warn("Error while sending request, will retry.",
                   :tries_left => tries,
                   :exception => e)
      retry if tries > 0
    end

    redirects = 0
    # Follow redirects
    while response.redirect? and response.headers.include?("Location")
      # RFC2616 section 10.3.3 indicates HEAD redirects must not include a
      # body. Otherwise, the redirect response can have a body, so let's
      # throw it away.
      if request.method == "HEAD" 
        # Head requests have no body
        connection.release
      elsif response.content?
        # Throw away the body
        response.body = connection
        # read_body will consume the body and release this connection
        response.read_http_body { |chunk| }
      end

      # TODO(sissel): If this response has any cookies, store them in the
      # agent's cookie store

      redirects += 1
      if redirects > configuration[REDIRECTION_LIMIT]
        # TODO(sissel): include original a useful debugging information like
        # the trace of redirections, etc.
        raise TooManyRedirects.new("Redirect more than " \
            "#{configuration[REDIRECTION_LIMIT]} times, aborting.", response)
        # I don't like this api from FTW::Agent. I think 'get' and other methods
        # should return (object, error), and if there's an error 
      end

      @logger.debug("Redirecting", :location => response.headers["Location"])
      request.use_uri(response.headers["Location"])
      connection, error = connect(request.headers["Host"], request.port, request.protocol == "https")
      # TODO(sissel): Do better error handling than raising.
      if !error.nil?
        p :error => error
        raise error
      end
      response = request.execute(connection)
    end # while being redirected

    # RFC 2616 section 9.4, HEAD requests MUST NOT have a message body.
    if request.method != "HEAD"
      response.body = connection
    else
      connection.release
    end
   
    # TODO(sissel): If this response has any cookies, store them in the
    # agent's cookie store
    return response
  end