Class: WSDL::Response

Inherits:
Object
  • Object
show all
Defined in:
lib/wsdl/response.rb,
lib/wsdl/response/fault.rb,
lib/wsdl/response/parser.rb,
lib/wsdl/response/fault_parser.rb,
lib/wsdl/response/type_coercer.rb,
lib/wsdl/response/security_context.rb

Overview

Represents a SOAP response from an operation call.

This class wraps the raw HTTP response and provides methods for parsing and accessing the SOAP envelope contents. When schema information is available, response values are automatically converted to appropriate Ruby types and arrays are handled consistently based on the schema's maxOccurs definitions.

Examples:

Accessing the response body

response = operation.invoke
puts response.body[:get_user_response][:user][:name]

Working with the raw response

response = operation.invoke
puts response.raw  # Raw XML string

Using XPath queries

response = operation.invoke
users = response.xpath('//ns:User', 'ns' => 'http://example.com/users')
users.each { |user| puts user.text }

Type conversions (with schema)

response = operation.invoke
response.body[:order][:id]       # => 123 (Integer, not "123")
response.body[:order][:total]    # => BigDecimal("99.99")
response.body[:order][:shipped]  # => true (Boolean, not "true")
response.body[:order][:items]    # => [{ name: "Widget" }] (always Array)

Verifying signature

response = operation.invoke
if response.security.signature_present?
  if response.security.valid?
    puts "Response is signed and valid"
    puts "Signed elements: #{response.security.signed_elements}"
  else
    puts "Signature verification failed: #{response.security.errors}"
  end
end

Strict verification (signature + timestamp)

begin
  response.security.verify!
rescue WSDL::SecurityError => e
  puts "Security verification failed: #{e.message}"
end

Defined Under Namespace

Classes: Fault, FaultParser, Parser, SecurityContext, TypeCoercer

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(http_response:, output_body_parts: nil, output_header_parts: nil, verification: Security::ResponseVerification::Options.default) ⇒ Response

Creates a new Response instance.

Parameters:

  • the HTTP response metadata (status code, headers, body)

  • (defaults to: nil)

    optional schema elements describing the expected body structure for type-aware parsing

  • (defaults to: nil)

    optional schema elements describing the expected header structure for type-aware parsing

  • (defaults to: Security::ResponseVerification::Options.default)

    response verification options for signature and timestamp validation



66
67
68
69
70
71
72
73
# File 'lib/wsdl/response.rb', line 66

def initialize(http_response:, output_body_parts: nil, output_header_parts: nil,
               verification: Security::ResponseVerification::Options.default)
  @raw_response = (http_response.body || '').freeze
  @http_response = http_response
  @output_body_parts = output_body_parts
  @output_header_parts = output_header_parts
  @verification = verification
end

Instance Attribute Details

#codeString? (readonly)

Returns the fault code (faultcode in 1.1, Code/Value in 1.2).

Returns:

  • the fault code (faultcode in 1.1, Code/Value in 1.2)



53
54
55
56
57
58
59
60
61
62
# File 'lib/wsdl/response/fault.rb', line 53

Fault = Data.define(:code, :subcodes, :reason, :detail, :node, :role) {
  # Returns a human-readable summary of the fault.
  #
  # @return [String] fault summary
  def to_s
    message = "(#{code}) #{reason}"
    message << " [role: #{role}]" if role
    message
  end
}

#detailHash? (readonly)

Returns parsed fault detail children, or nil if absent.

Returns:

  • parsed fault detail children, or nil if absent



53
54
55
56
57
58
59
60
61
62
# File 'lib/wsdl/response/fault.rb', line 53

Fault = Data.define(:code, :subcodes, :reason, :detail, :node, :role) {
  # Returns a human-readable summary of the fault.
  #
  # @return [String] fault summary
  def to_s
    message = "(#{code}) #{reason}"
    message << " [role: #{role}]" if role
    message
  end
}

#nodeString? (readonly)

Returns URI of the SOAP node that generated the fault (SOAP 1.2 only).

Returns:

  • URI of the SOAP node that generated the fault (SOAP 1.2 only)



53
54
55
56
57
58
59
60
61
62
# File 'lib/wsdl/response/fault.rb', line 53

Fault = Data.define(:code, :subcodes, :reason, :detail, :node, :role) {
  # Returns a human-readable summary of the fault.
  #
  # @return [String] fault summary
  def to_s
    message = "(#{code}) #{reason}"
    message << " [role: #{role}]" if role
    message
  end
}

#reasonString? (readonly)

Returns the fault reason (faultstring in 1.1, Reason/Text in 1.2).

Returns:

  • the fault reason (faultstring in 1.1, Reason/Text in 1.2)



53
54
55
56
57
58
59
60
61
62
# File 'lib/wsdl/response/fault.rb', line 53

Fault = Data.define(:code, :subcodes, :reason, :detail, :node, :role) {
  # Returns a human-readable summary of the fault.
  #
  # @return [String] fault summary
  def to_s
    message = "(#{code}) #{reason}"
    message << " [role: #{role}]" if role
    message
  end
}

#roleString? (readonly)

Returns role/actor (faultactor in 1.1, Role in 1.2).

Returns:

  • role/actor (faultactor in 1.1, Role in 1.2)



53
54
55
56
57
58
59
60
61
62
# File 'lib/wsdl/response/fault.rb', line 53

Fault = Data.define(:code, :subcodes, :reason, :detail, :node, :role) {
  # Returns a human-readable summary of the fault.
  #
  # @return [String] fault summary
  def to_s
    message = "(#{code}) #{reason}"
    message << " [role: #{role}]" if role
    message
  end
}

#subcodesArray<String> (readonly)

Returns nested subcodes (SOAP 1.2 only, empty for 1.1).

Returns:

  • nested subcodes (SOAP 1.2 only, empty for 1.1)



53
54
55
56
57
58
59
60
61
62
# File 'lib/wsdl/response/fault.rb', line 53

Fault = Data.define(:code, :subcodes, :reason, :detail, :node, :role) {
  # Returns a human-readable summary of the fault.
  #
  # @return [String] fault summary
  def to_s
    message = "(#{code}) #{reason}"
    message << " [role: #{role}]" if role
    message
  end
}

Instance Method Details

#bodyHash

Returns the parsed SOAP body as a Hash.

When schema information is available (output_body_parts), values are automatically converted to appropriate Ruby types:

  • xsd:int, xsd:integer, xsd:long → Integer
  • xsd:decimal → BigDecimal
  • xsd:float, xsd:double → Float
  • xsd:boolean → true/false
  • xsd:date → Date
  • xsd:dateTime → Time (only when timezone is explicit)
  • xsd:base64Binary → decoded String

Elements with maxOccurs > 1 are always returned as Arrays, even when only one element is present.

Examples:

response.body
# => { GetUserResponse: { User: { Name: "John", Age: 30 } } }

Returns:

  • the parsed body content



118
119
120
# File 'lib/wsdl/response.rb', line 118

def body
  @body ||= parse_body
end

#docNokogiri::XML::Document

Returns the response as a Nokogiri XML document.

Use this when you need full XML manipulation capabilities or want to run XPath queries.

Returns:

  • the parsed XML document



153
154
155
# File 'lib/wsdl/response.rb', line 153

def doc
  @doc ||= XML::Parser.parse(raw)
end

#envelope_hashHash Also known as: to_envelope_hash

Returns the entire parsed SOAP envelope as a Hash.

Keys are symbolized, preserving original element names. Note: This method does not use schema-aware parsing. Use #body and #header for schema-aware access.

Returns:

  • the complete parsed envelope



142
143
144
# File 'lib/wsdl/response.rb', line 142

def envelope_hash
  @envelope_hash ||= Parser.parse(doc)
end

#faultFault?

Returns the parsed SOAP fault, or nil if the response is not a fault.

Examples:

fault = response.fault
if fault
  puts fault.code    # => "soap:Server"
  puts fault.reason  # => "Something went wrong"
  puts fault.detail  # => { Error: "details" }
  puts fault.role    # => "http://example.com/actor"
end

Returns:

  • the parsed fault, or nil



215
216
217
218
219
# File 'lib/wsdl/response.rb', line 215

def fault
  return @fault if defined?(@fault)

  @fault = FaultParser.parse(doc)
end

#fault?Boolean

Returns whether the response contains a SOAP fault.

Detects faults in both SOAP 1.1 and 1.2 envelopes.

Examples:

if response.fault?
  puts "Fault: #{response.fault.reason}"
else
  puts response.body
end

Returns:

  • true if the response is a SOAP fault



200
201
202
# File 'lib/wsdl/response.rb', line 200

def fault?
  !fault.nil?
end

#headerHash?

Returns the parsed SOAP header as a Hash.

When schema information is available (output_header_parts), values are automatically converted to appropriate Ruby types, similar to #body.

The header is extracted from the SOAP envelope and returned with symbolized keys preserving the original element names.

Returns:

  • the parsed header content, or nil if empty



131
132
133
# File 'lib/wsdl/response.rb', line 131

def header
  @header ||= parse_header
end

#http_headersHash{String => String}

Returns the HTTP response headers.

Returns:

  • the HTTP response headers



88
89
90
# File 'lib/wsdl/response.rb', line 88

def http_headers
  @http_response.headers
end

#http_statusInteger?

Returns the HTTP status code of the response.

Examples:

response.http_status  # => 200
response.http_status  # => 500 (SOAP fault)

Returns:

  • the HTTP status code, or nil if not available



81
82
83
# File 'lib/wsdl/response.rb', line 81

def http_status
  @http_response.status
end

#rawString

Returns the raw XML response string.

Returns:

  • the raw XML response body



95
96
97
# File 'lib/wsdl/response.rb', line 95

def raw
  @raw_response
end

#securitySecurityContext

Returns the security context for signature and timestamp verification.

The security context provides methods for:

  • Signature verification (signature_valid?, verify_signature!)
  • Timestamp validation (timestamp_valid?, verify_timestamp!)
  • Combined verification (valid?, verify!)

Examples:

Check if response is secure

if response.security.valid?
  puts "Response is signed and fresh"
end

Strict verification

response.security.verify!  # raises on failure

Access verification details

response.security.signed_elements  # => ["Body", "Timestamp"]
response.security.errors           # => ["Digest mismatch..."]

Returns:

  • the security verification context



246
247
248
# File 'lib/wsdl/response.rb', line 246

def security
  @security ||= SecurityContext.new(raw, @verification)
end

#xml_namespacesHash{String => String}

Returns all XML namespaces declared in the response document.

This is useful for building XPath queries that need to reference namespaced elements.

Examples:

response.xml_namespaces
# => { "xmlns:soap" => "http://schemas.xmlsoap.org/soap/envelope/",
#      "xmlns:ns1" => "http://example.com/users" }

Returns:

  • namespace prefix to URI mappings



181
182
183
# File 'lib/wsdl/response.rb', line 181

def xml_namespaces
  @xml_namespaces ||= doc.collect_namespaces
end

#xpath(path, namespaces = nil) ⇒ Nokogiri::XML::NodeSet

Executes an XPath query on the response document.

Examples:

Without custom namespaces

response.xpath('//User')

With custom namespaces

response.xpath('//ns:User', 'ns' => 'http://example.com/users')

Parameters:

  • the XPath expression

  • (defaults to: nil)

    optional namespace mappings (defaults to the namespaces declared in the document)

Returns:

  • the matching nodes



167
168
169
# File 'lib/wsdl/response.rb', line 167

def xpath(path, namespaces = nil)
  doc.xpath(path, namespaces || xml_namespaces)
end