fetch (OpenID::StandardFetcher)

    # File lib/openid/fetchers.rb, line 181
        def fetch(url, body=nil, headers=nil, redirect_limit=REDIRECT_LIMIT)
          unparsed_url = url.dup
          url = URI::parse(url)
          if url.nil?
            raise FetchingError, "Invalid URL: #{unparsed_url}"
          end

          headers ||= {}
          headers['User-agent'] ||= USER_AGENT
          headers['Range'] ||= "0-#{MAX_RESPONSE_KB*1024}"

          begin
            conn = make_connection(url)
            response = nil

            response = conn.start {
              # Check the certificate against the URL's hostname
              if supports_ssl?(conn) and conn.use_ssl?
                conn.post_connection_check(url.host)
              end

              if body.nil?
                conn.request_get(url.request_uri, headers)
              else
                headers["Content-type"] ||= "application/x-www-form-urlencoded"
                conn.request_post(url.request_uri, body, headers)
              end
            }
          rescue RuntimeError => why
            raise why
          rescue OpenSSL::SSL::SSLError => why
            raise SSLFetchingError, "Error connecting to SSL URL #{url}: #{why}"
          rescue FetchingError => why
            raise why
          rescue Exception => why
            # Things we've caught here include a Timeout::Error, which descends
            # from SignalException.
            raise FetchingError, "Error fetching #{url}: #{why}"
          end

          case response
          when Net::HTTPRedirection
            if redirect_limit <= 0
              raise HTTPRedirectLimitReached.new(
                "Too many redirects, not fetching #{response['location']}")
            end
            begin
              return fetch(response['location'], body, headers, redirect_limit - 1)
            rescue HTTPRedirectLimitReached => e
              raise e
            rescue FetchingError => why
              raise FetchingError, "Error encountered in redirect from #{url}: #{why}"
            end
          else
            return HTTPResponse._from_net_response(response, unparsed_url)
          end
        end