savon 0.6.8 → 0.7.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
|