class NOMS::HttpClient::Real

Public Class Methods

new(delegator) click to toggle source
# File lib/noms/httpclient.rb, line 362
def initialize(delegator)
    @delegator = delegator
    @opt = @delegator.opt
    @opt['return-hash'] = true unless @opt.has_key? 'return-hash'
    self.dbg "Initialized with options: #{opt.inspect}"
end

Public Instance Methods

_xml_to_hash(rexml) click to toggle source
# File lib/noms/httpclient.rb, line 492
def _xml_to_hash(rexml)
    NOMS::XmlHash.new rexml.root
end
config_key() click to toggle source
# File lib/noms/httpclient.rb, line 369
def config_key
    @delegator.config_key
end
default_content_type() click to toggle source
# File lib/noms/httpclient.rb, line 373
def default_content_type
    @delegator.default_content_type
end
do_request(opt={}) click to toggle source
# File lib/noms/httpclient.rb, line 382
def do_request(opt={})
    method = [:GET, :PUT, :POST, :DELETE].find do |m|
        opt.has_key? m
    end
    if method == nil
      method = :GET
      opt[method] = ''
    end
    rel_uri = opt[method]
    opt[:redirect_limit] ||= 10
    if opt[:absolute]
      url = URI.parse(rel_uri)
    else
      url = URI.parse(myconfig 'url')
      unless opt[method] == ''
        url.path = rtrim(url.path) + '/' + ltrim(rel_uri) unless opt[:absolute]
      end
      url.query = opt[:query] if opt.has_key? :query
    end
    self.dbg("#{method.inspect} => #{url.to_s}")
    http = Net::HTTP.new(url.host, url.port)
    http.read_timeout = myconfig.has_key?('timeout') ? myconfig['timeout'] : 120
    http.use_ssl = true if url.scheme == 'https'
    if http.use_ssl?
        self.dbg("using SSL/TLS")
        if myconfig.has_key? 'verify-with-ca'
            http.verify_mode = OpenSSL::SSL::VERIFY_PEER
            http.ca_file = myconfig['verify-with-ca']
        else
            http.verify_mode = OpenSSL::SSL::VERIFY_NONE
        end
    else
        self.dbg("NOT using SSL/TLS")
    end
    reqclass = case method
               when :GET
                   Net::HTTP::Get
               when :PUT
                   Net::HTTP::Put
               when :POST
                   Net::HTTP::Post
               when :DELETE
                   Net::HTTP::Delete
               end
    request = reqclass.new(url.request_uri)
    self.dbg request.to_s
    if myconfig.has_key? 'username'
        self.dbg "will do basic authentication as #{myconfig['username']}"
        request.basic_auth(myconfig['username'], myconfig['password'])
    else
        self.dbg "no authentication"
    end
    if opt.has_key? :body
      content_type = opt[:content_type] || default_content_type
      request['Content-Type'] = content_type
      request.body = case content_type
                     when /json$/
                       opt[:body].to_json
                     when /xml$/
                       opt[:body].to_xml
                     else
                       opt[:body]
                     end
    end
    response = http.request(request)
    self.dbg response.to_s
    if response.is_a? Net::HTTPRedirection
        if opt[:redirect_limit] == 0
            raise "Error (#{self.class}) making #{config_key} request " +
              "(redirect limit exceeded): on #{response['location']}"
        end
        # TODO check if really absolute or make sure it is
        self.dbg "Redirect to #{response['location']}"
        do_request opt.merge({ :GET => response['location'],
                               :absolute => true,
                               :redirect_limit => opt[:redirect_limit] - 1
                               })
    end

    unless response.is_a? Net::HTTPSuccess
        raise "Error (#{self.class}) making #{config_key} request " +
            "(#{response.code}): " + error_body(response.body)
    end

    if response.body
        type = ignore_content_type ? default_content_type :
            (response.content_type || default_content_type)
        self.dbg "Response body is type #{type}"
        case type
        when /xml$/
           doc = REXML::Document.new response.body
           if @opt['return-hash']
               _xml_to_hash doc
           else
               doc
           end
        when /json$/
            # Ruby JSON doesn't like bare values in JSON, we'll try to wrap these as
            # one-element array
            bodytext = response.body
            bodytext = '[' + bodytext + ']' unless ['{', '['].include? response.body[0].chr
           JSON.parse(bodytext)
        else
           response.body
        end
    else
        true
    end
end
error_body(body_text, content_type=nil) click to toggle source
# File lib/noms/httpclient.rb, line 496
def error_body(body_text, content_type=nil)
    content_type ||= default_content_type
    begin
        extracted_message = case content_type
                            when /json$/
                              structure = JSON.parse(body_text)
                              structure['message']
                            when /xml$/
                              REXML::Document.new(body_text).root.elements["//message"].first.text
                    else
                      Hash.new
                    end
        ['message', 'error', 'error_message'].each do |key|
            return structure[key].to_s if structure.has_key? key
        end
        body_text.to_s
    rescue
        body_text.to_s
    end
end
ignore_content_type() click to toggle source
# File lib/noms/httpclient.rb, line 377
def ignore_content_type
    @delegator.ignore_content_type
end