savon 0.6.8 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG +30 -0
- data/README.textile +6 -2
- data/Rakefile +22 -4
- data/lib/savon.rb +1 -1
- data/lib/savon/client.rb +23 -28
- data/lib/savon/core_ext.rb +1 -1
- data/lib/savon/core_ext/hash.rb +33 -17
- data/lib/savon/core_ext/net_http.rb +20 -0
- data/lib/savon/request.rb +38 -40
- data/lib/savon/response.rb +13 -25
- data/lib/savon/soap.rb +5 -0
- data/lib/savon/wsdl.rb +8 -0
- data/spec/basic_spec_helper.rb +12 -0
- data/spec/fixtures/response/response_fixture.rb +5 -1
- data/spec/fixtures/response/xml/multi_ref.xml +39 -0
- data/spec/fixtures/response/xml/soap_fault12.xml +17 -17
- data/spec/fixtures/wsdl/wsdl_fixture.rb +2 -2
- data/spec/integration/http_basic_auth_spec.rb +12 -0
- data/spec/integration/server.rb +51 -0
- data/spec/savon/client_spec.rb +34 -54
- data/spec/savon/core_ext/hash_spec.rb +24 -20
- data/spec/savon/core_ext/net_http_spec.rb +38 -0
- data/spec/savon/core_ext/string_spec.rb +2 -2
- data/spec/savon/request_spec.rb +10 -56
- data/spec/savon/response_spec.rb +13 -5
- data/spec/savon/savon_spec.rb +3 -3
- data/spec/savon/soap_spec.rb +16 -8
- data/spec/savon/wsdl_spec.rb +7 -3
- data/spec/savon/wsse_spec.rb +12 -12
- data/spec/spec_helper.rb +1 -12
- metadata +12 -2
data/CHANGELOG
CHANGED
@@ -1,3 +1,33 @@
|
|
1
|
+
== 0.7.0 (2010-01-09)
|
2
|
+
This version comes with several changes to the public API!
|
3
|
+
Pay attention to the following list and read the updated Wiki: http://wiki.github.com/rubiii/savon
|
4
|
+
|
5
|
+
* Changed how Savon::WSDL can be disabled. Instead of disabling the WSDL globally/per request via two
|
6
|
+
different methods, you now simply append an exclamation mark (!) to your SOAP call: client.get_all_users!
|
7
|
+
Make sure you know what you're doing because when the WSDL is disabled, Savon does not know about which
|
8
|
+
SOAP actions are valid and just dispatches everything.
|
9
|
+
* The Net::HTTP object used by Savon::Request to retrieve WSDL documents and execute SOAP calls is now public.
|
10
|
+
While this makes the library even more flexible, it also comes with two major changes:
|
11
|
+
* SSL client authentication needs to be defined directly on the Net::HTTP object:
|
12
|
+
client.request.http.client_cert = ...
|
13
|
+
I added a shortcut method for setting all options through a Hash similar to the previous implementation:
|
14
|
+
client.request.http.ssl_client_auth :client_cert => ...
|
15
|
+
* Open and read timeouts also need to be set on the Net::HTTP object:
|
16
|
+
client.request.http.open_timeout = 30
|
17
|
+
client.request.http.read_timeout = 30
|
18
|
+
* Please refer to the Net::HTTP documentation for more details:
|
19
|
+
http://www.ruby-doc.org/stdlib/libdoc/net/http/rdoc/index.html
|
20
|
+
* Thanks to JulianMorrison, Savon now supports HTTP basic authentication:
|
21
|
+
client.request.http.basic_auth "username", "password"
|
22
|
+
* Julian also added a way to explicitly specify the order of Hash keys and values, so you should now be able
|
23
|
+
to work with services requiring a specific order of input parameters while still using Hash input.
|
24
|
+
For example: client.find_user { |soap| soap.body = { :name => "Lucy", :id => 666, :@inorder => [:id, :name] } }
|
25
|
+
* Savon::Response#to_hash now returns the content inside of "soap:Body" instead of trying to go one level
|
26
|
+
deeper and return it's content. The previous implementation only worked when the "soap:Body" element
|
27
|
+
contained a single child. See: http://github.com/rubiii/savon/issues#issue/17
|
28
|
+
* Added Savon::SOAP#namespace as a shortcut for setting the "xmlns:wsdl" namespace.
|
29
|
+
Usage example: soap.namespace = "http://example.com"
|
30
|
+
|
1
31
|
== 0.6.8 (2010-01-01)
|
2
32
|
* Improved specifications for various kinds of WSDL documents.
|
3
33
|
* Added support for SOAP endpoints which are different than the WSDL endpoint of a service.
|
data/README.textile
CHANGED
@@ -4,6 +4,10 @@ h4. Heavy metal Ruby SOAP client library
|
|
4
4
|
|
5
5
|
p. "RDoc":http://rdoc.info/projects/rubiii/savon | "Wiki":http://wiki.github.com/rubiii/savon | "ToDo":http://rubiii.tadalist.com/lists/1459816/public | "Metrics":http://getcaliper.com/caliper/project?repo=git://github.com/rubiii/savon.git
|
6
6
|
|
7
|
+
h2. Warning
|
8
|
+
|
9
|
+
p. Savon 0.7.0 comes with several changes to the public API. Pay attention to the CHANGELOG and the updated Wiki.
|
10
|
+
|
7
11
|
h2. Installation
|
8
12
|
|
9
13
|
bc. $ gem install savon
|
@@ -20,7 +24,7 @@ p. More information: "Client":http://wiki.github.com/rubiii/savon/client
|
|
20
24
|
|
21
25
|
h2. Calling a SOAP action
|
22
26
|
|
23
|
-
p. Assuming your service applies to the
|
27
|
+
p. Assuming your service applies to the defaults, you can now call any available SOAP action.
|
24
28
|
|
25
29
|
bc. response = client.get_all_users
|
26
30
|
|
@@ -67,5 +71,5 @@ More information: "Errors":http://wiki.github.com/rubiii/savon/errors
|
|
67
71
|
|
68
72
|
h2. Logging
|
69
73
|
|
70
|
-
p. Savon logs each request and response to STDOUT. But there are a couple of options to change the default
|
74
|
+
p. Savon logs each request and response to STDOUT. But there are a couple of options to change the default behavior.
|
71
75
|
More information: "Logging":http://wiki.github.com/rubiii/savon/logging
|
data/Rakefile
CHANGED
@@ -1,24 +1,42 @@
|
|
1
|
-
require "rubygems"
|
2
1
|
require "rake"
|
3
2
|
require "spec/rake/spectask"
|
4
3
|
require "spec/rake/verify_rcov"
|
5
4
|
require "rake/rdoctask"
|
6
5
|
|
7
|
-
task :default => :
|
6
|
+
task :default => :spec_verify
|
8
7
|
|
9
8
|
Spec::Rake::SpecTask.new do |spec|
|
10
|
-
spec.spec_files = FileList["spec/**/*_spec.rb"]
|
9
|
+
spec.spec_files = FileList["spec/{savon}/**/*_spec.rb"]
|
11
10
|
spec.spec_opts << "--color"
|
12
11
|
spec.libs += ["lib", "spec"]
|
13
12
|
spec.rcov = true
|
14
13
|
spec.rcov_dir = "rcov"
|
15
14
|
end
|
16
15
|
|
17
|
-
RCov::VerifyTask.new(:
|
16
|
+
RCov::VerifyTask.new(:spec_verify => :spec) do |verify|
|
18
17
|
verify.threshold = 100.0
|
19
18
|
verify.index_html = "rcov/index.html"
|
20
19
|
end
|
21
20
|
|
21
|
+
desc "Run integration specs using WEBrick"
|
22
|
+
task :spec_integration do
|
23
|
+
pid = fork { exec "ruby spec/integration/server.rb" }
|
24
|
+
sleep 10 # wait until the server is actually ready
|
25
|
+
begin
|
26
|
+
task(:run_integration_spec).invoke
|
27
|
+
ensure
|
28
|
+
Process.kill "TERM", pid
|
29
|
+
Process.wait pid
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
desc "" # make this task invisible for "rake -T"
|
34
|
+
Spec::Rake::SpecTask.new(:run_integration_spec) do |spec|
|
35
|
+
spec.spec_files = FileList["spec/{integration}/**/*_spec.rb"]
|
36
|
+
spec.spec_opts << "--color"
|
37
|
+
spec.libs += ["lib", "spec"]
|
38
|
+
end
|
39
|
+
|
22
40
|
Rake::RDocTask.new do |rdoc|
|
23
41
|
rdoc.title = "Savon"
|
24
42
|
rdoc.rdoc_dir = "rdoc"
|
data/lib/savon.rb
CHANGED
data/lib/savon/client.rb
CHANGED
@@ -6,19 +6,6 @@ module Savon
|
|
6
6
|
# with SOAP services and XML.
|
7
7
|
class Client
|
8
8
|
|
9
|
-
# Global setting of whether to use Savon::WSDL.
|
10
|
-
@@wsdl = true
|
11
|
-
|
12
|
-
# Sets the global setting of whether to use Savon::WSDL.
|
13
|
-
def self.wsdl=(wsdl)
|
14
|
-
@@wsdl = wsdl
|
15
|
-
end
|
16
|
-
|
17
|
-
# Returns the global setting of whether to use Savon::WSDL.
|
18
|
-
def self.wsdl?
|
19
|
-
@@wsdl
|
20
|
-
end
|
21
|
-
|
22
9
|
# Expects a SOAP +endpoint+ String. Also accepts an optional Hash of
|
23
10
|
# +options+ for specifying a proxy server and SSL client authentication.
|
24
11
|
def initialize(endpoint, options = {})
|
@@ -26,17 +13,12 @@ module Savon
|
|
26
13
|
@wsdl = WSDL.new @request
|
27
14
|
end
|
28
15
|
|
29
|
-
#
|
30
|
-
|
16
|
+
# Returns the Savon::WSDL.
|
17
|
+
attr_reader :wsdl
|
31
18
|
|
32
19
|
# Returns the Savon::Request.
|
33
20
|
attr_reader :request
|
34
21
|
|
35
|
-
# Returns whether to use Savon::WSDL.
|
36
|
-
def wsdl?
|
37
|
-
self.class.wsdl? && @wsdl
|
38
|
-
end
|
39
|
-
|
40
22
|
# Returns +true+ for available methods and SOAP actions.
|
41
23
|
def respond_to?(method)
|
42
24
|
return true if @wsdl.respond_to? method
|
@@ -47,22 +29,35 @@ module Savon
|
|
47
29
|
|
48
30
|
# Dispatches requests to SOAP actions matching a given +method+ name.
|
49
31
|
def method_missing(method, *args, &block) #:doc:
|
50
|
-
|
32
|
+
soap_call = soap_call_from method.to_s
|
33
|
+
super if @wsdl.enabled? && !@wsdl.respond_to?(soap_call)
|
51
34
|
|
52
|
-
setup_objects operation_from(
|
35
|
+
setup_objects operation_from(soap_call), &block
|
53
36
|
Response.new @request.soap(@soap)
|
54
37
|
end
|
55
38
|
|
39
|
+
# Sets whether to use Savon::WSDL by a given +method+ name and
|
40
|
+
# removes exclamation marks from the given +method+ name.
|
41
|
+
def soap_call_from(method)
|
42
|
+
if method[-1, 1] == "!"
|
43
|
+
@wsdl.enabled = false
|
44
|
+
method[0, method.length-1].to_sym
|
45
|
+
else
|
46
|
+
@wsdl.enabled = true
|
47
|
+
method.to_sym
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
56
51
|
# Returns a SOAP operation Hash containing the SOAP action and input
|
57
|
-
# for a given +
|
58
|
-
def operation_from(
|
59
|
-
return @wsdl.operations[
|
60
|
-
{ :action =>
|
52
|
+
# for a given +soap_call+.
|
53
|
+
def operation_from(soap_call)
|
54
|
+
return @wsdl.operations[soap_call] if @wsdl.enabled?
|
55
|
+
{ :action => soap_call.to_soap_key, :input => soap_call.to_soap_key }
|
61
56
|
end
|
62
57
|
|
63
58
|
# Returns the SOAP endpoint.
|
64
59
|
def soap_endpoint
|
65
|
-
wsdl? ? @wsdl.soap_endpoint : @request.endpoint
|
60
|
+
@wsdl.enabled? ? @wsdl.soap_endpoint : @request.endpoint
|
66
61
|
end
|
67
62
|
|
68
63
|
# Expects a SOAP operation Hash and sets up Savon::SOAP and Savon::WSSE.
|
@@ -73,7 +68,7 @@ module Savon
|
|
73
68
|
|
74
69
|
yield_objects &block if block
|
75
70
|
|
76
|
-
@soap.namespaces["xmlns:wsdl"] ||= @wsdl.namespace_uri if wsdl?
|
71
|
+
@soap.namespaces["xmlns:wsdl"] ||= @wsdl.namespace_uri if @wsdl.enabled?
|
77
72
|
@soap.wsse = @wsse
|
78
73
|
end
|
79
74
|
|
data/lib/savon/core_ext.rb
CHANGED
data/lib/savon/core_ext/hash.rb
CHANGED
@@ -1,29 +1,34 @@
|
|
1
1
|
class Hash
|
2
2
|
|
3
|
-
#
|
4
|
-
|
5
|
-
|
6
|
-
#
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
result
|
3
|
+
# Error message for missing :@inorder elements.
|
4
|
+
InOrderMissing = "Missing elements in :@inorder %s"
|
5
|
+
|
6
|
+
# Error message for spurious :@inorder elements.
|
7
|
+
InOrderSpurious = "Spurious elements in :@inorder %s"
|
8
|
+
|
9
|
+
# Returns the values from the 'soap:Body' element or an empty Hash
|
10
|
+
# in case the node could not be found.
|
11
|
+
def find_soap_body
|
12
|
+
envelope = self[self.keys.first] || {}
|
13
|
+
body_key = envelope.keys.find { |key| /.+:Body/ =~ key } rescue nil
|
14
|
+
body_key ? envelope[body_key].map_soap_response : {}
|
16
15
|
end
|
17
16
|
|
18
17
|
# Returns the Hash translated into SOAP request compatible XML.
|
19
18
|
#
|
20
|
-
#
|
19
|
+
# To control the order of output, add a key of :@inorder with
|
20
|
+
# the value being an Array listing keys in order.
|
21
|
+
#
|
22
|
+
# === Examples
|
21
23
|
#
|
22
24
|
# { :find_user => { :id => 666 } }.to_soap_xml
|
23
25
|
# => "<findUser><id>666</id></findUser>"
|
26
|
+
#
|
27
|
+
# { :find_user => { :name => "Lucy", :id => 666, :@inorder => [:id, :name] } }.to_soap_xml
|
28
|
+
# => "<findUser><id>666</id><name>Lucy</name></findUser>"
|
24
29
|
def to_soap_xml
|
25
30
|
@soap_xml = Builder::XmlMarkup.new
|
26
|
-
each { |key
|
31
|
+
inorder(self).each { |key| nested_data_to_soap_xml key, self[key] }
|
27
32
|
@soap_xml.target!
|
28
33
|
end
|
29
34
|
|
@@ -49,14 +54,25 @@ private
|
|
49
54
|
def nested_data_to_soap_xml(key, value)
|
50
55
|
case value
|
51
56
|
when Array
|
52
|
-
value.map { |
|
57
|
+
value.map { |subitem| nested_data_to_soap_xml key, subitem }
|
53
58
|
when Hash
|
54
59
|
@soap_xml.tag!(key.to_soap_key) do
|
55
|
-
value.each { |subkey
|
60
|
+
inorder(value).each { |subkey| nested_data_to_soap_xml subkey, value[subkey] }
|
56
61
|
end
|
57
62
|
else
|
58
63
|
@soap_xml.tag!(key.to_soap_key) { @soap_xml << value.to_soap_value }
|
59
64
|
end
|
60
65
|
end
|
61
66
|
|
67
|
+
# Takes a +hash+, removes the :@inorder marker and returns its keys.
|
68
|
+
# Raises an error in case an :@inorder Array does not match the Hash keys.
|
69
|
+
def inorder(hash)
|
70
|
+
inorder = hash.delete :@inorder
|
71
|
+
hash_keys = hash.keys
|
72
|
+
inorder = hash_keys unless inorder.kind_of? Array
|
73
|
+
raise InOrderMissing % (hash_keys - inorder).inspect unless (hash_keys - inorder).empty?
|
74
|
+
raise InOrderSpurious % (inorder - hash_keys).inspect unless (inorder - hash_keys).empty?
|
75
|
+
inorder
|
76
|
+
end
|
77
|
+
|
62
78
|
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Net
|
2
|
+
class HTTP
|
3
|
+
|
4
|
+
# Sets the endpoint +address+ and +port+.
|
5
|
+
def endpoint(address, port)
|
6
|
+
@address, @port = address, port
|
7
|
+
end
|
8
|
+
|
9
|
+
# Convenience method for setting SSL client authentication
|
10
|
+
# through a Hash of +options+.
|
11
|
+
def ssl_client_auth(options)
|
12
|
+
self.use_ssl = true
|
13
|
+
self.cert = options[:cert] if options[:cert]
|
14
|
+
self.key = options[:key] if options[:key]
|
15
|
+
self.ca_file = options[:ca_file] if options[:ca_file]
|
16
|
+
self.verify_mode = options[:verify_mode] if options[:verify_mode]
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
end
|
data/lib/savon/request.rb
CHANGED
@@ -47,12 +47,11 @@ module Savon
|
|
47
47
|
@@log_level
|
48
48
|
end
|
49
49
|
|
50
|
-
# Expects a SOAP +endpoint+ String. Also accepts an optional Hash
|
51
|
-
# +options+ for specifying a proxy server
|
50
|
+
# Expects a SOAP +endpoint+ String. Also accepts an optional Hash
|
51
|
+
# of +options+ for specifying a proxy server.
|
52
52
|
def initialize(endpoint, options = {})
|
53
53
|
@endpoint = URI endpoint
|
54
|
-
@proxy = options[:proxy] ? URI(options[:proxy]) : URI("")
|
55
|
-
@ssl = options[:ssl] if options[:ssl]
|
54
|
+
@proxy = options[:proxy] ? URI(options[:proxy]) : URI("")
|
56
55
|
end
|
57
56
|
|
58
57
|
# Returns the endpoint URI.
|
@@ -61,35 +60,45 @@ module Savon
|
|
61
60
|
# Returns the proxy URI.
|
62
61
|
attr_reader :proxy
|
63
62
|
|
64
|
-
#
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
attr_accessor :read_timeout
|
63
|
+
# Sets the +username+ and +password+ for HTTP basic authentication.
|
64
|
+
def basic_auth(username, password)
|
65
|
+
@basic_auth = [username, password]
|
66
|
+
end
|
69
67
|
|
70
|
-
# Retrieves WSDL document and returns the Net::
|
68
|
+
# Retrieves WSDL document and returns the Net::HTTP response.
|
71
69
|
def wsdl
|
72
70
|
log "Retrieving WSDL from: #{@endpoint}"
|
73
|
-
http.
|
71
|
+
http.endpoint @endpoint.host, @endpoint.port
|
72
|
+
http.use_ssl = @endpoint.ssl?
|
73
|
+
http.start { |h| h.request request(:wsdl) }
|
74
74
|
end
|
75
75
|
|
76
76
|
# Executes a SOAP request using a given Savon::SOAP instance and
|
77
|
-
# returns the Net::
|
77
|
+
# returns the Net::HTTP response.
|
78
78
|
def soap(soap)
|
79
79
|
@soap = soap
|
80
|
+
http.endpoint @soap.endpoint.host, @soap.endpoint.port
|
81
|
+
http.use_ssl = @soap.endpoint.ssl?
|
80
82
|
|
81
83
|
log_request
|
82
|
-
@response = http
|
84
|
+
@response = http.start do |h|
|
85
|
+
h.request request(:soap) { |request| request.body = @soap.to_xml }
|
86
|
+
end
|
83
87
|
log_response
|
84
88
|
@response
|
85
89
|
end
|
86
90
|
|
91
|
+
# Returns the Net::HTTP object.
|
92
|
+
def http
|
93
|
+
@http ||= Net::HTTP::Proxy(@proxy.host, @proxy.port).new @endpoint.host, @endpoint.port
|
94
|
+
end
|
95
|
+
|
87
96
|
private
|
88
97
|
|
89
98
|
# Logs the SOAP request.
|
90
99
|
def log_request
|
91
100
|
log "SOAP request: #{@soap.endpoint}"
|
92
|
-
log http_header.map { |key, value| "#{key}: #{value}" }.join(
|
101
|
+
log http_header.map { |key, value| "#{key}: #{value}" }.join(", ")
|
93
102
|
log @soap.to_xml
|
94
103
|
end
|
95
104
|
|
@@ -99,33 +108,22 @@ module Savon
|
|
99
108
|
log @response.body
|
100
109
|
end
|
101
110
|
|
102
|
-
# Returns a Net::HTTP
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
def set_http_timeout
|
113
|
-
@http.open_timeout = @open_timeout if @open_timeout
|
114
|
-
@http.read_timeout = @read_timeout if @read_timeout
|
115
|
-
end
|
116
|
-
|
117
|
-
# Sets basic SSL options to the +@http+ instance.
|
118
|
-
def set_ssl_options(use_ssl)
|
119
|
-
@http.use_ssl = use_ssl
|
120
|
-
@http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
111
|
+
# Returns a Net::HTTP request for a given +type+. Yields the request
|
112
|
+
# to an optional block.
|
113
|
+
def request(type)
|
114
|
+
request = case type
|
115
|
+
when :wsdl then Net::HTTP::Get.new wsdl_endpoint
|
116
|
+
when :soap then Net::HTTP::Post.new @soap.endpoint.path, http_header
|
117
|
+
end
|
118
|
+
request.basic_auth *@basic_auth if @basic_auth
|
119
|
+
yield request if block_given?
|
120
|
+
request
|
121
121
|
end
|
122
122
|
|
123
|
-
#
|
124
|
-
def
|
125
|
-
@
|
126
|
-
@
|
127
|
-
@http.key = @ssl[:client_key] if @ssl[:client_key]
|
128
|
-
@http.ca_file = @ssl[:ca_file] if @ssl[:ca_file]
|
123
|
+
# Returns the WSDL endpoint.
|
124
|
+
def wsdl_endpoint
|
125
|
+
return @endpoint.path unless @endpoint.query
|
126
|
+
"#{@endpoint.path}?#{@endpoint.query}"
|
129
127
|
end
|
130
128
|
|
131
129
|
# Returns a Hash containing the header for an HTTP request.
|
@@ -138,7 +136,7 @@ module Savon
|
|
138
136
|
self.class.logger.send self.class.log_level, message if log?
|
139
137
|
end
|
140
138
|
|
141
|
-
# Returns whether
|
139
|
+
# Returns whether to log.
|
142
140
|
def log?
|
143
141
|
self.class.log? && self.class.logger.respond_to?(self.class.log_level)
|
144
142
|
end
|
data/lib/savon/response.rb
CHANGED
@@ -28,7 +28,7 @@ module Savon
|
|
28
28
|
|
29
29
|
# Returns whether there was a SOAP fault.
|
30
30
|
def soap_fault?
|
31
|
-
@soap_fault
|
31
|
+
@soap_fault ? true : false
|
32
32
|
end
|
33
33
|
|
34
34
|
# Returns the SOAP fault message.
|
@@ -36,15 +36,15 @@ module Savon
|
|
36
36
|
|
37
37
|
# Returns whether there was an HTTP error.
|
38
38
|
def http_error?
|
39
|
-
@http_error
|
39
|
+
@http_error ? true : false
|
40
40
|
end
|
41
41
|
|
42
42
|
# Returns the HTTP error message.
|
43
43
|
attr_reader :http_error
|
44
44
|
|
45
|
-
# Returns the SOAP response as a Hash.
|
45
|
+
# Returns the SOAP response body as a Hash.
|
46
46
|
def to_hash
|
47
|
-
@body.
|
47
|
+
@body ||= Crack::XML.parse(@response.body).find_soap_body
|
48
48
|
end
|
49
49
|
|
50
50
|
# Returns the SOAP response XML.
|
@@ -52,45 +52,33 @@ module Savon
|
|
52
52
|
@response.body
|
53
53
|
end
|
54
54
|
|
55
|
-
alias :to_s
|
55
|
+
alias :to_s :to_xml
|
56
56
|
|
57
57
|
private
|
58
58
|
|
59
|
-
# Returns the SOAP response body as a Hash.
|
60
|
-
def body
|
61
|
-
unless @body
|
62
|
-
body = Crack::XML.parse @response.body
|
63
|
-
@body = body.find_regexp [/.+:Envelope/, /.+:Body/]
|
64
|
-
end
|
65
|
-
@body
|
66
|
-
end
|
67
|
-
|
68
59
|
# Handles SOAP faults. Raises a Savon::SOAPFault unless the default
|
69
60
|
# behavior of raising errors was turned off.
|
70
61
|
def handle_soap_fault
|
71
62
|
if soap_fault_message
|
72
63
|
@soap_fault = soap_fault_message
|
73
|
-
raise Savon::SOAPFault,
|
64
|
+
raise Savon::SOAPFault, @soap_fault if self.class.raise_errors?
|
74
65
|
end
|
75
66
|
end
|
76
67
|
|
77
68
|
# Returns a SOAP fault message in case a SOAP fault was found.
|
78
69
|
def soap_fault_message
|
79
|
-
|
80
|
-
soap_fault = body.find_regexp [/.+:Fault/]
|
81
|
-
@soap_fault_message = soap_fault_message_by_version(soap_fault)
|
82
|
-
end
|
83
|
-
@soap_fault_message
|
70
|
+
@soap_fault_message ||= soap_fault_message_by_version to_hash[:fault]
|
84
71
|
end
|
85
72
|
|
86
73
|
# Expects a Hash that might contain information about a SOAP fault.
|
87
74
|
# Returns the SOAP fault message in case one was found.
|
88
75
|
def soap_fault_message_by_version(soap_fault)
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
#
|
93
|
-
|
76
|
+
return unless soap_fault
|
77
|
+
|
78
|
+
if soap_fault.keys.include? :faultcode
|
79
|
+
"(#{soap_fault[:faultcode]}) #{soap_fault[:faultstring]}"
|
80
|
+
elsif soap_fault.keys.include? :code
|
81
|
+
"(#{soap_fault[:code][:value]}) #{soap_fault[:reason][:text]}"
|
94
82
|
end
|
95
83
|
end
|
96
84
|
|