class Savon::Response

Constants

CRLF
WSP

Attributes

globals[R]
http[R]
http_error[R]
locals[R]
soap_fault[R]

Public Class Methods

new(http, globals, locals) click to toggle source
# File lib/savon/response.rb, line 11
def initialize(http, globals, locals)
  @http    = http
  @globals = globals
  @locals  = locals
  @attachments = []
  @xml     = ''
  @has_parsed_body = false

  build_soap_and_http_errors!
  raise_soap_and_http_errors! if @globals[:raise_errors]
end

Public Instance Methods

attachments() click to toggle source
# File lib/savon/response.rb, line 88
def attachments
  if multipart?
    parse_body unless @has_parsed_body
    @attachments
  else
    []
  end
end
body() click to toggle source
# File lib/savon/response.rb, line 42
def body
  find('Body')
end
Also aliased as: to_hash
doc() click to toggle source
# File lib/savon/response.rb, line 73
def doc
  @doc ||= Nokogiri.XML(xml)
end
find(*path) click to toggle source
# File lib/savon/response.rb, line 81
def find(*path)
  envelope = nori.find(full_hash, 'Envelope')
  raise_invalid_response_error! unless envelope.is_a?(Hash)

  nori.find(envelope, *path)
end
full_hash() click to toggle source
# File lib/savon/response.rb, line 57
def full_hash
  @full_hash ||= nori.parse(xml)
end
header() click to toggle source
# File lib/savon/response.rb, line 38
def header
  find('Header')
end
http_error?() click to toggle source
# File lib/savon/response.rb, line 34
def http_error?
  HTTPError.present? @http
end
multipart?() click to toggle source
# File lib/savon/response.rb, line 97
def multipart?
  !(http.headers['content-type'] =~ /^multipart/im).nil?
end
soap_fault?() click to toggle source
# File lib/savon/response.rb, line 30
def soap_fault?
  SOAPFault.present?(@http, xml)
end
success?() click to toggle source
# File lib/savon/response.rb, line 25
def success?
  !soap_fault? && !http_error?
end
Also aliased as: successful?
successful?()
Alias for: success?
to_array(*path) click to toggle source
# File lib/savon/response.rb, line 48
def to_array(*path)
  result = path.inject body do |memo, key|
    return [] if memo[key].nil?
    memo[key]
  end

  result.kind_of?(Array) ? result.compact : [result].compact
end
to_hash()
Alias for: body
to_s()
Alias for: xml
to_xml()
Alias for: xml
xml() click to toggle source
# File lib/savon/response.rb, line 61
def xml
  if multipart?
    parse_body unless @has_parsed_body
    @xml
  else
    @http.body
  end
end
Also aliased as: to_xml, to_s
xpath(path, namespaces = nil) click to toggle source
# File lib/savon/response.rb, line 77
def xpath(path, namespaces = nil)
  doc.xpath(path, namespaces || xml_namespaces)
end

Private Instance Methods

boundary() click to toggle source
# File lib/savon/response.rb, line 103
def boundary
  return unless multipart?
  Mail::Field.new('content-type', http.headers['content-type']).parameters['boundary']
end
build_soap_and_http_errors!() click to toggle source
# File lib/savon/response.rb, line 126
def build_soap_and_http_errors!
  @soap_fault = SOAPFault.new(@http, nori, xml) if soap_fault?
  @http_error = HTTPError.new(@http) if http_error?
end
nori() click to toggle source
# File lib/savon/response.rb, line 144
def nori
  return @nori if @nori

  nori_options = {
    :delete_namespace_attributes => @globals[:delete_namespace_attributes],
    :strip_namespaces            => @globals[:strip_namespaces],
    :convert_tags_to             => @globals[:convert_response_tags_to],
    :convert_attributes_to       => @globals[:convert_attributes_to],
    :advanced_typecasting        => @locals[:advanced_typecasting],
    :parser                      => @locals[:response_parser]
  }

  non_nil_nori_options = nori_options.reject { |_, value| value.nil? }
  @nori = Nori.new(non_nil_nori_options)
end
parse_body() click to toggle source
# File lib/savon/response.rb, line 108
def parse_body
  http.body.force_encoding Encoding::ASCII_8BIT
  parts = http.body.split(/(?:\A|\r\n)--#{Regexp.escape(boundary)}(?=(?:--)?\s*$)/)
  parts[1..-1].to_a.each_with_index do |part, index|
    header_part, body_part = part.lstrip.split(/#{CRLF}#{CRLF}|#{CRLF}#{WSP}*#{CRLF}(?!#{WSP})/m, 2)
    section = Mail::Part.new(
      body: body_part
    )
    section.header = header_part
    if index == 0
      @xml = section.body.to_s
    else
      @attachments << section
    end
  end
  @has_parsed_body = true
end
raise_invalid_response_error!() click to toggle source
# File lib/savon/response.rb, line 136
def raise_invalid_response_error!
  raise InvalidResponseError, "Unable to parse response body:\n" + xml.inspect
end
raise_soap_and_http_errors!() click to toggle source
# File lib/savon/response.rb, line 131
def raise_soap_and_http_errors!
  raise soap_fault if soap_fault?
  raise http_error if http_error?
end
xml_namespaces() click to toggle source
# File lib/savon/response.rb, line 140
def xml_namespaces
  @xml_namespaces ||= doc.collect_namespaces
end