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/builder.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 XML

response = operation.invoke
puts response.xml

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: Builder, 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, output_style: 'document/literal', verification: Security::ResponseVerification::Options.default) ⇒ Response

Creates a new Response instance.

Parameters:

  • http_response (HTTP::Response)

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

  • output_body_parts (Array<WSDL::XML::Element>, nil) (defaults to: nil)

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

  • output_header_parts (Array<WSDL::XML::Element>, nil) (defaults to: nil)

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

  • output_style (String) (defaults to: 'document/literal')

    binding style ('document/literal' or 'rpc/literal')

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

    response verification options for signature and timestamp validation



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

def initialize(http_response:, output_body_parts: nil, output_header_parts: nil,
               output_style: 'document/literal',
               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
  @output_style = output_style
  @verification = verification
end

Instance Attribute Details

#codeString? (readonly)

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

Returns:

  • (String, nil)

    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:

  • (Hash, nil)

    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:

  • (String, nil)

    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:

  • (String, nil)

    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:

  • (String, nil)

    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:

  • (Array<String>)

    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:

  • (Hash)

    the parsed body content



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

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:

  • (Nokogiri::XML::Document)

    the parsed XML document



140
141
142
# File 'lib/wsdl/response.rb', line 140

def doc
  @doc ||= XML::Parser.parse(xml)
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:

  • (Fault, nil)

    the parsed fault, or nil



174
175
176
177
178
# File 'lib/wsdl/response.rb', line 174

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:

  • (Boolean)

    true if the response is a SOAP fault



159
160
161
# File 'lib/wsdl/response.rb', line 159

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:

  • (Hash, nil)

    the parsed header content, or nil if empty



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

def header
  @header ||= parse_header
end

#http_headersHash{String => String}

Returns the HTTP response headers.

Returns:

  • (Hash{String => String})

    the HTTP response headers



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

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:

  • (Integer, nil)

    the HTTP status code, or nil if not available



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

def http_status
  @http_response.status
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:



205
206
207
# File 'lib/wsdl/response.rb', line 205

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

#xmlString

Returns the raw XML response string.

Returns:

  • (String)

    the raw XML response body



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

def xml
  @raw_response
end