savon 2.17.1 → 3.0.0.rc1
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +17 -33
- data/README.md +52 -42
- data/Rakefile +2 -6
- data/lib/savon/block_interface.rb +4 -3
- data/lib/savon/builder.rb +31 -25
- data/lib/savon/client.rb +13 -44
- data/lib/savon/header.rb +12 -12
- data/lib/savon/http_error.rb +5 -3
- data/lib/savon/log_message.rb +3 -2
- data/lib/savon/message.rb +7 -6
- data/lib/savon/mock/expectation.rb +24 -38
- data/lib/savon/mock/spec_helper.rb +11 -7
- data/lib/savon/mock.rb +0 -1
- data/lib/savon/model.rb +17 -12
- data/lib/savon/operation.rb +74 -99
- data/lib/savon/options.rb +171 -255
- data/lib/savon/qualified_message.rb +1 -2
- data/lib/savon/request.rb +147 -0
- data/lib/savon/request_logger.rb +57 -0
- data/lib/savon/response.rb +23 -30
- data/lib/savon/soap_fault.rb +6 -6
- data/lib/savon/string_utils.rb +4 -3
- data/lib/savon/version.rb +1 -2
- data/lib/savon.rb +11 -2
- metadata +128 -72
- data/lib/savon/transport/faraday.rb +0 -69
- data/lib/savon/transport/httpi.rb +0 -134
- data/lib/savon/transport/logging.rb +0 -60
- data/lib/savon/transport/response.rb +0 -44
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 3f58a5268715a082369bc199231506447defea5f760fae67cb51507a9011836c
|
|
4
|
+
data.tar.gz: d349d7d546fb236e45f433047bd575dd6f6ec206254707094f02420ec58dfc07
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 91d6cd948edbb82b643fa5aaeef265dcfeef5037459478f0815f01bdacbe04cb159165301a9f0ebc75fd897470ff2a0b51de1fa256123843698a14925f5ebf43
|
|
7
|
+
data.tar.gz: 3a9fe95352e4f85e9e88f7eaffba5fb04df58085380ed7c62e8c0f31c0b110b5127c494125f373e97489c789991b6c1271e68df000606c3e1a3311a17edc951a
|
data/CHANGELOG.md
CHANGED
|
@@ -1,38 +1,22 @@
|
|
|
1
1
|
# Savon changelog
|
|
2
2
|
|
|
3
|
-
##
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
*
|
|
15
|
-
|
|
16
|
-
*
|
|
17
|
-
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
* digest authentication via `faraday-digestauth` middleware (#1021, savonrb/httpi#250)
|
|
21
|
-
* proxy authentication with special characters in passwords (#941)
|
|
22
|
-
* and setting an `Accept` header for WSDL requests from Rails apps (savonrb/wasabi#115)
|
|
23
|
-
|
|
24
|
-
## 2.16.0 (2026-05-18)
|
|
25
|
-
|
|
26
|
-
**Restore compatibility**
|
|
27
|
-
|
|
28
|
-
If you stayed on 2.12.1 because a later version broke something, this release is for you. The fixes below target the most commonly reported upgrade blockers. Existing code should work without modification.
|
|
29
|
-
|
|
30
|
-
* Fix: Restore `Savon::Response#hash` removed in 2.14.0 (#985). Callers on 2.12.1 that use `response.hash` get the soap body back instead of Ruby's integer object id. A deprecation warning is emitted on each call. Use `#full_hash` going forward.
|
|
31
|
-
* Fix: Require wasabi >= 5.1.0 (#1015, #1016). Wasabi 4.x used message names as soap body element names and SOAPAction header values instead of operation names (savonrb/wasabi#122), causing servers to return a fault or reject the action for operations whose message name carried an `In` suffix.
|
|
32
|
-
* Fix: Stop dumping all WSDL namespaces into every soap envelope (#1014, #942). 2.13.0 injected every namespace from the entire WSDL document into each request, including structural ones that have no place in a request body. Strict servers reject envelopes with unexpected or duplicate declarations.
|
|
33
|
-
* Fix: Raise a proper `SOAPFault` instead of a raw exception when `soap:Fault` contains invalid encoding (#923).
|
|
34
|
-
* Fix: `SOAPFault.present?` was ignoring its `xml` argument and always operating on the instance's own body.
|
|
35
|
-
* Change: Added Ruby 3.4 (#1024) and Ruby 4.0 (#1039) to the CI test matrix.
|
|
3
|
+
## Unreleased
|
|
4
|
+
* Add your PR changelog line here
|
|
5
|
+
|
|
6
|
+
## 3.0.0.rc1 (2024-07-15)
|
|
7
|
+
|
|
8
|
+
* Use Faraday instead of HTTPI
|
|
9
|
+
* BC BREAKING Cookies are handled differently now
|
|
10
|
+
* BC BREAKING Multiple pieces of functionality will rely on faraday libraries to be provided by the consuming codebase
|
|
11
|
+
* BC BREAKING Adapter overrides now utilize the faraday model
|
|
12
|
+
* BC BREAKING Multiple hard deprecations due to a lack of feature parity between Faraday and HTTPI
|
|
13
|
+
* Deprecates digest auth
|
|
14
|
+
* Deprecates ssl_cert_key_file auth, upgrade path is to read the key
|
|
15
|
+
in and provide it
|
|
16
|
+
* Deprecates encrypted ssl keys, upgrade path is to
|
|
17
|
+
decrypt the key and pass it to faraday in code
|
|
18
|
+
* Deprecates providing a ca cert, upgrade path is to provide a ca cert file
|
|
19
|
+
* deprecates overriding ssl ciphers, as faraday does not support this
|
|
36
20
|
|
|
37
21
|
## 2.15.1 (2024-07-08)
|
|
38
22
|
|
data/README.md
CHANGED
|
@@ -2,78 +2,88 @@
|
|
|
2
2
|
|
|
3
3
|
Heavy metal SOAP client
|
|
4
4
|
|
|
5
|
+
[Documentation](https://www.rubydoc.info/gems/savon/) | [Support](https://stackoverflow.com/questions/tagged/savon) |
|
|
6
|
+
[Mailing list](https://groups.google.com/forum/#!forum/savonrb) | [Twitter](http://twitter.com/savonrb)
|
|
7
|
+
|
|
5
8
|
[](https://github.com/savonrb/savon/actions/workflows/ci.yml)
|
|
6
9
|
[](http://badge.fury.io/rb/savon)
|
|
10
|
+
[](https://codeclimate.com/github/savonrb/savon)
|
|
7
11
|
[](https://coveralls.io/r/savonrb/savon)
|
|
8
12
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
Full documentation is at [savonrb.com](https://savonrb.com).
|
|
13
|
+
If you're reading this on GitHub, note that this README is for the main branch and that features/changes described here might not correspond to your version. You can find the documentation for your release [at rubydoc.info](https://www.rubydoc.info/find/gems?q=savon).
|
|
12
14
|
|
|
13
15
|
## Installation
|
|
14
16
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
+
Savon is available through [Rubygems](http://rubygems.org/gems/savon) and can be installed via:
|
|
18
|
+
|
|
19
|
+
```
|
|
20
|
+
$ gem install savon
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
or add it to your Gemfile like this:
|
|
24
|
+
|
|
25
|
+
```
|
|
26
|
+
gem 'savon', '~> 3.0.0'
|
|
17
27
|
```
|
|
18
28
|
|
|
19
|
-
## Usage
|
|
29
|
+
## Usage example
|
|
20
30
|
|
|
21
|
-
```ruby
|
|
31
|
+
``` ruby
|
|
22
32
|
require 'savon'
|
|
23
33
|
|
|
24
|
-
#
|
|
25
|
-
client = Savon.client(wsdl: '
|
|
34
|
+
# create a client for the service
|
|
35
|
+
client = Savon.client(wsdl: 'http://service.example.com?wsdl')
|
|
36
|
+
|
|
37
|
+
# or: create a client with a wsdl provided as a string
|
|
38
|
+
client = Savon.client do |config|
|
|
39
|
+
wsdl_content = File.read("/path/to/wsdl")
|
|
40
|
+
config.wsdl wsdl_content
|
|
41
|
+
end
|
|
26
42
|
|
|
27
|
-
# See what the service exposes
|
|
28
43
|
client.operations
|
|
29
|
-
# => [:find_user, :
|
|
44
|
+
# => [:find_user, :list_users]
|
|
30
45
|
|
|
31
|
-
#
|
|
46
|
+
# call the 'findUser' operation
|
|
32
47
|
response = client.call(:find_user, message: { id: 42 })
|
|
33
|
-
response.body[:find_user_response]
|
|
34
|
-
# => { id: 42, name: "Hoff" }
|
|
35
48
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
puts e.to_hash.dig(:fault, :faultstring)
|
|
49
|
+
response.body
|
|
50
|
+
# => { find_user_response: { id: 42, name: 'Hoff' } }
|
|
39
51
|
```
|
|
40
52
|
|
|
41
|
-
|
|
53
|
+
For more examples, you should check out the
|
|
54
|
+
[integration tests](https://github.com/savonrb/savon/tree/version2/spec/integration).
|
|
42
55
|
|
|
43
|
-
|
|
44
|
-
client = Savon.client(
|
|
45
|
-
wsdl: 'https://service.example.com?wsdl',
|
|
46
|
-
pretty_print_xml: true,
|
|
47
|
-
log: true
|
|
48
|
-
)
|
|
49
|
-
```
|
|
56
|
+
## Upgrading from v2.x to v3.x
|
|
50
57
|
|
|
51
|
-
|
|
58
|
+
See [UPGRADING.md](UPGRADING.md) for more information.
|
|
52
59
|
|
|
53
|
-
|
|
60
|
+
## Ruby version support
|
|
54
61
|
|
|
55
|
-
|
|
56
|
-
# HTTP basic auth
|
|
57
|
-
Savon.client(wsdl: '...', basic_auth: ['user', 'secret'])
|
|
62
|
+
Every savon release is tested with contemporary supported versions of ruby. Historical compatibility information:
|
|
58
63
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
64
|
+
* `main` - same support as Ruby
|
|
65
|
+
* 2.15.x - MRI 3.0, 3.1, 3.2, 3.3
|
|
66
|
+
* 2.13.x, 2.14.x - MRI 2.7, 3.0, 3.1
|
|
67
|
+
* 2.12.x - MRI 2.2, 2.3, 2.4, 2.5
|
|
68
|
+
* 2.11.x - MRI 2.0, 2.1, 2.2, and 2.3
|
|
62
69
|
|
|
63
|
-
|
|
70
|
+
If you are running MRI 1.8.7, try a 2.6.x release.
|
|
64
71
|
|
|
65
|
-
|
|
72
|
+
Most changes are not backported to older versions of savon, or unsupported ruby versions.
|
|
66
73
|
|
|
67
|
-
|
|
74
|
+
## Running tests
|
|
68
75
|
|
|
69
|
-
|
|
76
|
+
```bash
|
|
77
|
+
$ bundle install
|
|
78
|
+
$ bundle exec rspec
|
|
79
|
+
```
|
|
70
80
|
|
|
71
|
-
|
|
81
|
+
## FAQ
|
|
72
82
|
|
|
73
|
-
|
|
83
|
+
* URI::InvalidURIError -- if you see this error, then it is likely that the http client you are using cannot parse the URI for your WSDL. Try `gem install httpclient` or add it to your `Gemfile`.
|
|
84
|
+
- See https://github.com/savonrb/savon/issues/488 for more info
|
|
74
85
|
|
|
75
|
-
**WSDL imports are not followed.** Savon parses only the root WSDL document via [Wasabi](https://github.com/savonrb/wasabi). Messages, port types, and bindings defined in imported files are invisible to Savon. If you control the WSDL, merge the imported elements into the root document and pass that to Savon as a string. If you need full import support, the [WSDL](https://rubygems.org/gems/wsdl) gem is an alternative.
|
|
76
86
|
|
|
77
|
-
##
|
|
87
|
+
## Documentation
|
|
78
88
|
|
|
79
|
-
|
|
89
|
+
Please be sure to [read the documentation](https://www.rubydoc.info/github/savonrb/savon/).
|
data/Rakefile
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
1
|
require "bundler/gem_tasks"
|
|
4
2
|
require "rspec/core/rake_task"
|
|
5
3
|
|
|
@@ -12,7 +10,5 @@ RSpec::Core::RakeTask.new "spec:integration" do |t|
|
|
|
12
10
|
t.pattern = "spec/integration/**/*_spec.rb"
|
|
13
11
|
end
|
|
14
12
|
|
|
15
|
-
|
|
16
|
-
task test
|
|
17
|
-
|
|
18
|
-
task default: :spec
|
|
13
|
+
task :default => :spec
|
|
14
|
+
task :test => :spec
|
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
|
-
|
|
3
2
|
module Savon
|
|
4
3
|
class BlockInterface
|
|
4
|
+
|
|
5
5
|
def initialize(target)
|
|
6
6
|
@target = target
|
|
7
7
|
end
|
|
8
8
|
|
|
9
9
|
def evaluate(block)
|
|
10
|
-
if block.arity
|
|
10
|
+
if block.arity > 0
|
|
11
11
|
block.call(@target)
|
|
12
12
|
else
|
|
13
|
-
@original = eval("self", block.binding
|
|
13
|
+
@original = eval("self", block.binding)
|
|
14
14
|
instance_eval(&block)
|
|
15
15
|
end
|
|
16
16
|
end
|
|
@@ -22,5 +22,6 @@ module Savon
|
|
|
22
22
|
rescue NoMethodError
|
|
23
23
|
@original.send(method, *args, &block)
|
|
24
24
|
end
|
|
25
|
+
|
|
25
26
|
end
|
|
26
27
|
end
|
data/lib/savon/builder.rb
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
|
-
|
|
3
2
|
require "savon/header"
|
|
4
3
|
require "savon/message"
|
|
5
4
|
require "nokogiri"
|
|
@@ -13,12 +12,12 @@ module Savon
|
|
|
13
12
|
SCHEMA_TYPES = {
|
|
14
13
|
"xmlns:xsd" => "http://www.w3.org/2001/XMLSchema",
|
|
15
14
|
"xmlns:xsi" => "http://www.w3.org/2001/XMLSchema-instance"
|
|
16
|
-
}
|
|
15
|
+
}
|
|
17
16
|
|
|
18
17
|
SOAP_NAMESPACE = {
|
|
19
18
|
1 => "http://schemas.xmlsoap.org/soap/envelope/",
|
|
20
19
|
2 => "http://www.w3.org/2003/05/soap-envelope"
|
|
21
|
-
}
|
|
20
|
+
}
|
|
22
21
|
|
|
23
22
|
WSA_NAMESPACE = "http://www.w3.org/2005/08/addressing"
|
|
24
23
|
|
|
@@ -35,7 +34,7 @@ module Savon
|
|
|
35
34
|
end
|
|
36
35
|
|
|
37
36
|
def pretty
|
|
38
|
-
Nokogiri.XML(to_s).to_xml(indent
|
|
37
|
+
Nokogiri.XML(to_s).to_xml(:indent => 2)
|
|
39
38
|
end
|
|
40
39
|
|
|
41
40
|
def build_document
|
|
@@ -72,36 +71,33 @@ module Savon
|
|
|
72
71
|
|
|
73
72
|
def to_s
|
|
74
73
|
return @locals[:xml] if @locals.include? :xml
|
|
75
|
-
|
|
76
74
|
build_document
|
|
77
75
|
end
|
|
78
76
|
|
|
79
77
|
private
|
|
80
78
|
|
|
81
79
|
def convert_type_definitions_to_hash
|
|
82
|
-
@wsdl.type_definitions.
|
|
80
|
+
@wsdl.type_definitions.inject({}) do |memo, (path, type)|
|
|
83
81
|
memo[path] = type
|
|
82
|
+
memo
|
|
84
83
|
end
|
|
85
84
|
end
|
|
86
85
|
|
|
87
86
|
def convert_type_namespaces_to_hash
|
|
88
|
-
@wsdl.type_namespaces.
|
|
87
|
+
@wsdl.type_namespaces.inject({}) do |memo, (path, uri)|
|
|
89
88
|
key, value = use_namespace(path, uri)
|
|
90
89
|
memo[key] = value
|
|
90
|
+
memo
|
|
91
91
|
end
|
|
92
92
|
end
|
|
93
93
|
|
|
94
94
|
def use_namespace(path, uri)
|
|
95
95
|
@internal_namespace_count ||= 0
|
|
96
96
|
|
|
97
|
-
unless
|
|
98
|
-
|
|
99
|
-
# The prefix may already be taken by the target namespace or a user-supplied
|
|
100
|
-
# :namespaces override - fall back to ins0, ins1... rather than overwriting it.
|
|
101
|
-
wsdl_identifier = nil if wsdl_identifier && namespaces.key?("xmlns:#{wsdl_identifier}")
|
|
102
|
-
identifier = wsdl_identifier || "ins#{@internal_namespace_count}"
|
|
97
|
+
unless identifier = namespace_by_uri(uri)
|
|
98
|
+
identifier = "ins#{@internal_namespace_count}"
|
|
103
99
|
namespaces["xmlns:#{identifier}"] = uri
|
|
104
|
-
@internal_namespace_count += 1
|
|
100
|
+
@internal_namespace_count += 1
|
|
105
101
|
end
|
|
106
102
|
|
|
107
103
|
[path, identifier]
|
|
@@ -120,9 +116,21 @@ module Savon
|
|
|
120
116
|
@globals[:namespace] || @wsdl.namespace
|
|
121
117
|
|
|
122
118
|
# check env_namespace
|
|
123
|
-
namespaces["xmlns#{env_namespace && env_namespace !=
|
|
119
|
+
namespaces["xmlns#{env_namespace && env_namespace != "" ? ":#{env_namespace}" : ''}"] =
|
|
124
120
|
SOAP_NAMESPACE[@globals[:soap_version]]
|
|
125
121
|
|
|
122
|
+
if @wsdl&.document
|
|
123
|
+
@wsdl.parser.namespaces.each do |identifier, path|
|
|
124
|
+
next if identifier == 'xmlns' # Do not include xmlns namespace as this causes issues for some servers (https://github.com/savonrb/savon/issues/986)
|
|
125
|
+
|
|
126
|
+
prefixed_identifier = "xmlns:#{identifier}"
|
|
127
|
+
|
|
128
|
+
next if namespaces.key?(prefixed_identifier)
|
|
129
|
+
|
|
130
|
+
namespaces[prefixed_identifier] = path
|
|
131
|
+
end
|
|
132
|
+
end
|
|
133
|
+
|
|
126
134
|
namespaces
|
|
127
135
|
end
|
|
128
136
|
end
|
|
@@ -137,9 +145,8 @@ module Savon
|
|
|
137
145
|
|
|
138
146
|
def namespaced_message_tag
|
|
139
147
|
tag_name = message_tag
|
|
140
|
-
return [tag_name] if @wsdl.document?
|
|
141
|
-
|
|
142
|
-
if namespace_identifier.nil?
|
|
148
|
+
return [tag_name] if @wsdl.document? and @wsdl.soap_input(@operation_name.to_sym).is_a?(Hash)
|
|
149
|
+
if namespace_identifier == nil
|
|
143
150
|
[tag_name, message_attributes]
|
|
144
151
|
elsif @used_namespaces[[tag_name.to_s]]
|
|
145
152
|
[@used_namespaces[[tag_name.to_s]], tag_name, message_attributes]
|
|
@@ -157,7 +164,6 @@ module Savon
|
|
|
157
164
|
message_tag = serialized_message_tag[1]
|
|
158
165
|
@wsdl.soap_input(@operation_name.to_sym)[message_tag].each_pair do |message, type|
|
|
159
166
|
break if @locals[:message].nil?
|
|
160
|
-
|
|
161
167
|
message_locals = @locals[:message][StringUtils.snakecase(message).to_sym]
|
|
162
168
|
message_content = Message.new(message_tag, namespace_identifier, @types, @used_namespaces, message_locals, :unqualified, @globals[:convert_request_keys_to], @globals[:unwrap]).to_s
|
|
163
169
|
messages += "<#{message} xsi:type=\"#{type.join(':')}\">#{message_content}</#{message}>"
|
|
@@ -171,7 +177,7 @@ module Savon
|
|
|
171
177
|
message_tag = wsdl_tag_name.keys.first if wsdl_tag_name.is_a?(Hash)
|
|
172
178
|
message_tag ||= @locals[:message_tag]
|
|
173
179
|
message_tag ||= wsdl_tag_name
|
|
174
|
-
message_tag ||= Gyoku.xml_tag(@operation_name, key_converter
|
|
180
|
+
message_tag ||= Gyoku.xml_tag(@operation_name, :key_converter => @globals[:convert_request_keys_to])
|
|
175
181
|
|
|
176
182
|
message_tag.to_sym
|
|
177
183
|
end
|
|
@@ -181,7 +187,7 @@ module Savon
|
|
|
181
187
|
end
|
|
182
188
|
|
|
183
189
|
def body_message
|
|
184
|
-
if @wsdl.document?
|
|
190
|
+
if @wsdl.document? and @wsdl.soap_input(@operation_name.to_sym).is_a?(Hash)
|
|
185
191
|
serialized_messages
|
|
186
192
|
else
|
|
187
193
|
message.to_s
|
|
@@ -215,7 +221,7 @@ module Savon
|
|
|
215
221
|
|
|
216
222
|
def builder
|
|
217
223
|
builder = ::Builder::XmlMarkup.new
|
|
218
|
-
builder.instruct!(:xml, encoding
|
|
224
|
+
builder.instruct!(:xml, :encoding => @globals[:encoding])
|
|
219
225
|
builder
|
|
220
226
|
end
|
|
221
227
|
|
|
@@ -248,7 +254,7 @@ module Savon
|
|
|
248
254
|
|
|
249
255
|
# the mail.body.encoded algorithm reorders the parts, default order is [ "text/plain", "text/enriched", "text/html" ]
|
|
250
256
|
# should redefine the sort order, because the soap request xml should be the first
|
|
251
|
-
multipart_message.body.set_sort_order ["text/xml"]
|
|
257
|
+
multipart_message.body.set_sort_order [ "text/xml" ]
|
|
252
258
|
|
|
253
259
|
multipart_message.body.encoded(multipart_message.content_transfer_encoding)
|
|
254
260
|
end
|
|
@@ -263,10 +269,10 @@ module Savon
|
|
|
263
269
|
end
|
|
264
270
|
multipart_message.add_part xml_part
|
|
265
271
|
|
|
266
|
-
#
|
|
272
|
+
#request.headers["Content-Type"] = "multipart/related; boundary=\"#{multipart_message.body.boundary}\"; type=\"text/xml\"; start=\"#{xml_part.content_id}\""
|
|
267
273
|
@multipart = {
|
|
268
274
|
multipart_boundary: multipart_message.body.boundary,
|
|
269
|
-
start: xml_part.content_id
|
|
275
|
+
start: xml_part.content_id,
|
|
270
276
|
}
|
|
271
277
|
|
|
272
278
|
multipart_message
|
data/lib/savon/client.rb
CHANGED
|
@@ -1,26 +1,19 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
|
-
|
|
3
2
|
require "savon/operation"
|
|
4
|
-
require "savon/
|
|
5
|
-
require "savon/transport/faraday"
|
|
3
|
+
require "savon/request"
|
|
6
4
|
require "savon/options"
|
|
7
5
|
require "savon/block_interface"
|
|
8
6
|
require "wasabi"
|
|
9
7
|
|
|
10
8
|
module Savon
|
|
11
|
-
# The main entry point for Savon.
|
|
12
|
-
#
|
|
13
|
-
# Holds global configuration, owns the WSDL document, and dispatches
|
|
14
|
-
# named operations. A single Client instance is typically shared across
|
|
15
|
-
# multiple calls to the same service.
|
|
16
9
|
class Client
|
|
10
|
+
|
|
17
11
|
def initialize(globals = {}, &block)
|
|
18
|
-
unless globals.
|
|
12
|
+
unless globals.kind_of? Hash
|
|
19
13
|
raise_version1_initialize_error! globals
|
|
20
14
|
end
|
|
21
15
|
|
|
22
16
|
set_globals(globals, block)
|
|
23
|
-
@globals.validate_transport!
|
|
24
17
|
|
|
25
18
|
unless wsdl_or_endpoint_and_namespace_specified?
|
|
26
19
|
raise_initialization_error!
|
|
@@ -31,25 +24,13 @@ module Savon
|
|
|
31
24
|
|
|
32
25
|
attr_reader :globals, :wsdl
|
|
33
26
|
|
|
34
|
-
# Returns the memoized Faraday::Connection for this client.
|
|
35
|
-
# Callers use this to configure middleware, SSL, auth, timeouts, and any
|
|
36
|
-
# other transport-level concern before making calls.
|
|
37
|
-
# Raises ArgumentError if transport is not :faraday.
|
|
38
|
-
def faraday
|
|
39
|
-
unless @globals[:transport] == :faraday
|
|
40
|
-
raise ArgumentError, "client.faraday is only available when transport: :faraday is set"
|
|
41
|
-
end
|
|
42
|
-
|
|
43
|
-
@faraday ||= ::Faraday.new
|
|
44
|
-
end
|
|
45
|
-
|
|
46
27
|
def operations
|
|
47
28
|
raise_missing_wsdl_error! unless @wsdl.document?
|
|
48
29
|
@wsdl.soap_actions
|
|
49
30
|
end
|
|
50
31
|
|
|
51
32
|
def operation(operation_name)
|
|
52
|
-
Operation.create(operation_name, @wsdl, @globals
|
|
33
|
+
Operation.create(operation_name, @wsdl, @globals)
|
|
53
34
|
end
|
|
54
35
|
|
|
55
36
|
def call(operation_name, locals = {}, &block)
|
|
@@ -67,15 +48,6 @@ module Savon
|
|
|
67
48
|
|
|
68
49
|
private
|
|
69
50
|
|
|
70
|
-
# Builds the transport for a single operation.
|
|
71
|
-
def build_transport
|
|
72
|
-
if @globals[:transport] == :faraday
|
|
73
|
-
Transport::Faraday.new(faraday, @globals)
|
|
74
|
-
else
|
|
75
|
-
Transport::HTTPI.new(@globals)
|
|
76
|
-
end
|
|
77
|
-
end
|
|
78
|
-
|
|
79
51
|
def set_globals(globals, block)
|
|
80
52
|
globals = GlobalOptions.new(globals)
|
|
81
53
|
BlockInterface.new(globals).evaluate(block) if block
|
|
@@ -86,16 +58,12 @@ module Savon
|
|
|
86
58
|
def build_wsdl_document
|
|
87
59
|
@wsdl = Wasabi::Document.new
|
|
88
60
|
|
|
89
|
-
@wsdl.document
|
|
90
|
-
@wsdl.endpoint
|
|
91
|
-
@wsdl.namespace
|
|
61
|
+
@wsdl.document = @globals[:wsdl] if @globals.include? :wsdl
|
|
62
|
+
@wsdl.endpoint = @globals[:endpoint] if @globals.include? :endpoint
|
|
63
|
+
@wsdl.namespace = @globals[:namespace] if @globals.include? :namespace
|
|
64
|
+
@wsdl.adapter = @globals[:adapter] if @globals.include? :adapter
|
|
92
65
|
|
|
93
|
-
|
|
94
|
-
@wsdl.request = faraday
|
|
95
|
-
else
|
|
96
|
-
@wsdl.adapter = @globals[:adapter] if @globals.include? :adapter
|
|
97
|
-
@wsdl.request = Transport::HTTPI.new(@globals).wsdl_request
|
|
98
|
-
end
|
|
66
|
+
@wsdl.request = WSDLRequest.new(@globals).build
|
|
99
67
|
end
|
|
100
68
|
|
|
101
69
|
def wsdl_or_endpoint_and_namespace_specified?
|
|
@@ -104,9 +72,9 @@ module Savon
|
|
|
104
72
|
|
|
105
73
|
def raise_version1_initialize_error!(object)
|
|
106
74
|
raise InitializationError,
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
75
|
+
"Some code tries to initialize Savon with the #{object.inspect} (#{object.class}) \n" \
|
|
76
|
+
"Savon 2 expects a Hash of options for creating a new client and executing requests.\n" \
|
|
77
|
+
"Please read the updated documentation for version 2: http://savonrb.com/version2.html"
|
|
110
78
|
end
|
|
111
79
|
|
|
112
80
|
def raise_initialization_error!
|
|
@@ -120,5 +88,6 @@ module Savon
|
|
|
120
88
|
def raise_missing_wsdl_error!
|
|
121
89
|
raise "Unable to inspect the service without a WSDL document."
|
|
122
90
|
end
|
|
91
|
+
|
|
123
92
|
end
|
|
124
93
|
end
|
data/lib/savon/header.rb
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
|
-
|
|
3
2
|
require "akami"
|
|
4
3
|
require "gyoku"
|
|
5
4
|
require "securerandom"
|
|
6
5
|
|
|
7
6
|
module Savon
|
|
8
7
|
class Header
|
|
8
|
+
|
|
9
9
|
def initialize(globals, locals)
|
|
10
|
-
@gyoku_options = { key_converter
|
|
10
|
+
@gyoku_options = { :key_converter => globals[:convert_request_keys_to] }
|
|
11
11
|
|
|
12
12
|
@wsse_auth = locals[:wsse_auth].nil? ? globals[:wsse_auth] : locals[:wsse_auth]
|
|
13
13
|
@wsse_timestamp = locals[:wsse_timestamp].nil? ? globals[:wsse_timestamp] : locals[:wsse_timestamp]
|
|
@@ -41,7 +41,7 @@ module Savon
|
|
|
41
41
|
|
|
42
42
|
def build_header
|
|
43
43
|
header =
|
|
44
|
-
if global_header.
|
|
44
|
+
if global_header.kind_of?(Hash) && local_header.kind_of?(Hash)
|
|
45
45
|
global_header.merge(local_header)
|
|
46
46
|
elsif local_header
|
|
47
47
|
local_header
|
|
@@ -58,17 +58,16 @@ module Savon
|
|
|
58
58
|
end
|
|
59
59
|
|
|
60
60
|
def build_wsa_header
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
})
|
|
61
|
+
return '' unless @globals[:use_wsa_headers]
|
|
62
|
+
convert_to_xml({
|
|
63
|
+
'wsa:Action' => @locals[:soap_action],
|
|
64
|
+
'wsa:To' => @globals[:endpoint],
|
|
65
|
+
'wsa:MessageID' => "urn:uuid:#{SecureRandom.uuid}"
|
|
66
|
+
})
|
|
68
67
|
end
|
|
69
68
|
|
|
70
69
|
def convert_to_xml(hash_or_string)
|
|
71
|
-
if hash_or_string.
|
|
70
|
+
if hash_or_string.kind_of? Hash
|
|
72
71
|
Gyoku.xml(hash_or_string, gyoku_options)
|
|
73
72
|
else
|
|
74
73
|
hash_or_string.to_s
|
|
@@ -79,11 +78,12 @@ module Savon
|
|
|
79
78
|
wsse = Akami.wsse
|
|
80
79
|
wsse.credentials(*wsse_auth) if wsse_auth
|
|
81
80
|
wsse.timestamp = wsse_timestamp if wsse_timestamp
|
|
82
|
-
if wsse_signature
|
|
81
|
+
if wsse_signature && wsse_signature.have_document?
|
|
83
82
|
wsse.signature = wsse_signature
|
|
84
83
|
end
|
|
85
84
|
|
|
86
85
|
wsse
|
|
87
86
|
end
|
|
87
|
+
|
|
88
88
|
end
|
|
89
89
|
end
|
data/lib/savon/http_error.rb
CHANGED
|
@@ -2,8 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
module Savon
|
|
4
4
|
class HTTPError < Error
|
|
5
|
+
|
|
5
6
|
def self.present?(http)
|
|
6
|
-
http.
|
|
7
|
+
!http.success?
|
|
7
8
|
end
|
|
8
9
|
|
|
9
10
|
def initialize(http)
|
|
@@ -13,13 +14,14 @@ module Savon
|
|
|
13
14
|
attr_reader :http
|
|
14
15
|
|
|
15
16
|
def to_s
|
|
16
|
-
String.new("HTTP error (#{@http.
|
|
17
|
+
String.new("HTTP error (#{@http.status})").tap do |str_error|
|
|
17
18
|
str_error << ": #{@http.body}" unless @http.body.empty?
|
|
18
19
|
end
|
|
19
20
|
end
|
|
20
21
|
|
|
21
22
|
def to_hash
|
|
22
|
-
{ code
|
|
23
|
+
{ :code => @http.status, :headers => @http.headers, :body => @http.body }
|
|
23
24
|
end
|
|
25
|
+
|
|
24
26
|
end
|
|
25
27
|
end
|
data/lib/savon/log_message.rb
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
|
-
|
|
3
2
|
require "nokogiri"
|
|
4
3
|
|
|
5
4
|
module Savon
|
|
6
5
|
class LogMessage
|
|
6
|
+
|
|
7
7
|
def initialize(message, filters = [], pretty_print = false)
|
|
8
8
|
@message = message
|
|
9
9
|
@filters = filters
|
|
@@ -46,7 +46,8 @@ module Savon
|
|
|
46
46
|
end
|
|
47
47
|
|
|
48
48
|
def nokogiri_options
|
|
49
|
-
@pretty_print ? { indent
|
|
49
|
+
@pretty_print ? { :indent => 2 } : { :save_with => Nokogiri::XML::Node::SaveOptions::AS_XML }
|
|
50
50
|
end
|
|
51
|
+
|
|
51
52
|
end
|
|
52
53
|
end
|