savon 2.15.0 → 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 +23 -1
- data/README.md +15 -4
- data/lib/savon/http_error.rb +3 -3
- data/lib/savon/mock/expectation.rb +4 -4
- data/lib/savon/operation.rb +43 -27
- data/lib/savon/options.rb +24 -8
- data/lib/savon/request.rb +81 -47
- data/lib/savon/request_logger.rb +8 -5
- data/lib/savon/soap_fault.rb +1 -1
- data/lib/savon/version.rb +1 -1
- data/lib/savon.rb +8 -0
- metadata +94 -22
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
@@ -3,9 +3,30 @@
|
|
3
3
|
## Unreleased
|
4
4
|
* Add your PR changelog line here
|
5
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
|
20
|
+
|
21
|
+
## 2.15.1 (2024-07-08)
|
22
|
+
|
23
|
+
* Ruby 3.0+ is required in the gemspec.
|
24
|
+
* Require httpi 4.x - older versions rely on `Rack::Utils::HeaderHash` which is removed in Rack 3.0.
|
25
|
+
|
6
26
|
## 2.15.0 (2024-02-10)
|
7
27
|
|
8
28
|
* Drop support for ruby 2.7 and below. Added Ruby 3.2 and 3.3 to test matrix.
|
29
|
+
* Allows wasabi v5.x, which now supports faraday
|
9
30
|
|
10
31
|
## 2.14.0 (2022-12-16)
|
11
32
|
|
@@ -16,6 +37,7 @@
|
|
16
37
|
## 2.13.1 (2022-09-04)
|
17
38
|
|
18
39
|
* Fix: [#977](https://github.com/savonrb/savon/pull/977) Prevent "xmlns:xmlns" namespace but allow "xmlns" namespace.
|
40
|
+
* Change: Require Ruby 2.7.0+ in the gemspec. [0e0d695f](https://github.com/savonrb/savon/commit/0e0d695f463b719fa0fef0f58a0404b1228957f0)
|
19
41
|
|
20
42
|
## 2.13.0 (2022-08-03)
|
21
43
|
|
@@ -535,7 +557,7 @@ Combined release ticket: [#481](https://github.com/savonrb/savon/issues/481)
|
|
535
557
|
|
536
558
|
* `Hash#map_soap_response` and some of its helpers are moved to [Nori v1.0.0](http://rubygems.org/gems/nori/versions/1.0.0).
|
537
559
|
Along with replacing core extensions with a proper implementation, Nori now contains a number of methods
|
538
|
-
for [configuring its default behavior](https://github.com/savonrb/nori/blob/
|
560
|
+
for [configuring its default behavior](https://github.com/savonrb/nori/blob/main/CHANGELOG.md):
|
539
561
|
|
540
562
|
* The option whether to strip namespaces was moved to Nori.strip_namespaces
|
541
563
|
* You can disable "advanced typecasting" for SOAP response values
|
data/README.md
CHANGED
@@ -10,10 +10,11 @@ Heavy metal SOAP client
|
|
10
10
|
[](https://codeclimate.com/github/savonrb/savon)
|
11
11
|
[](https://coveralls.io/r/savonrb/savon)
|
12
12
|
|
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).
|
13
14
|
|
14
|
-
##
|
15
|
+
## Installation
|
15
16
|
|
16
|
-
Savon
|
17
|
+
Savon is available through [Rubygems](http://rubygems.org/gems/savon) and can be installed via:
|
17
18
|
|
18
19
|
```
|
19
20
|
$ gem install savon
|
@@ -22,7 +23,7 @@ $ gem install savon
|
|
22
23
|
or add it to your Gemfile like this:
|
23
24
|
|
24
25
|
```
|
25
|
-
gem 'savon', '~>
|
26
|
+
gem 'savon', '~> 3.0.0'
|
26
27
|
```
|
27
28
|
|
28
29
|
## Usage example
|
@@ -52,14 +53,24 @@ response.body
|
|
52
53
|
For more examples, you should check out the
|
53
54
|
[integration tests](https://github.com/savonrb/savon/tree/version2/spec/integration).
|
54
55
|
|
56
|
+
## Upgrading from v2.x to v3.x
|
57
|
+
|
58
|
+
See [UPGRADING.md](UPGRADING.md) for more information.
|
59
|
+
|
55
60
|
## Ruby version support
|
56
61
|
|
57
|
-
|
62
|
+
Every savon release is tested with contemporary supported versions of ruby. Historical compatibility information:
|
63
|
+
|
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
|
58
67
|
* 2.12.x - MRI 2.2, 2.3, 2.4, 2.5
|
59
68
|
* 2.11.x - MRI 2.0, 2.1, 2.2, and 2.3
|
60
69
|
|
61
70
|
If you are running MRI 1.8.7, try a 2.6.x release.
|
62
71
|
|
72
|
+
Most changes are not backported to older versions of savon, or unsupported ruby versions.
|
73
|
+
|
63
74
|
## Running tests
|
64
75
|
|
65
76
|
```bash
|
data/lib/savon/http_error.rb
CHANGED
@@ -4,7 +4,7 @@ module Savon
|
|
4
4
|
class HTTPError < Error
|
5
5
|
|
6
6
|
def self.present?(http)
|
7
|
-
http.
|
7
|
+
!http.success?
|
8
8
|
end
|
9
9
|
|
10
10
|
def initialize(http)
|
@@ -14,13 +14,13 @@ module Savon
|
|
14
14
|
attr_reader :http
|
15
15
|
|
16
16
|
def to_s
|
17
|
-
String.new("HTTP error (#{@http.
|
17
|
+
String.new("HTTP error (#{@http.status})").tap do |str_error|
|
18
18
|
str_error << ": #{@http.body}" unless @http.body.empty?
|
19
19
|
end
|
20
20
|
end
|
21
21
|
|
22
22
|
def to_hash
|
23
|
-
{ :code => @http.
|
23
|
+
{ :code => @http.status, :headers => @http.headers, :body => @http.body }
|
24
24
|
end
|
25
25
|
|
26
26
|
end
|
@@ -1,5 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
-
require "
|
2
|
+
require "faraday"
|
3
3
|
|
4
4
|
module Savon
|
5
5
|
class MockExpectation
|
@@ -41,8 +41,8 @@ module Savon
|
|
41
41
|
unless @response
|
42
42
|
raise ExpectationError, "This expectation was not set up with a response."
|
43
43
|
end
|
44
|
-
|
45
|
-
|
44
|
+
env = Faraday::Env.from(status: @response[:code], response_headers: @response[:headers], response_body: @response[:body])
|
45
|
+
Faraday::Response.new(env)
|
46
46
|
end
|
47
47
|
|
48
48
|
private
|
@@ -75,7 +75,7 @@ module Savon
|
|
75
75
|
next if (expected_value == :any && msg_real.include?(key))
|
76
76
|
return false if expected_value != msg_real[key]
|
77
77
|
end
|
78
|
-
|
78
|
+
true
|
79
79
|
end
|
80
80
|
end
|
81
81
|
end
|
data/lib/savon/operation.rb
CHANGED
@@ -7,6 +7,8 @@ require "savon/response"
|
|
7
7
|
require "savon/request_logger"
|
8
8
|
require "savon/http_error"
|
9
9
|
require "mail"
|
10
|
+
require 'faraday/gzip'
|
11
|
+
|
10
12
|
|
11
13
|
module Savon
|
12
14
|
class Operation
|
@@ -58,16 +60,20 @@ module Savon
|
|
58
60
|
builder = build(locals, &block)
|
59
61
|
|
60
62
|
response = Savon.notify_observers(@name, builder, @globals, @locals)
|
61
|
-
response ||= call_with_logging
|
63
|
+
response ||= call_with_logging build_connection(builder)
|
62
64
|
|
63
|
-
|
65
|
+
raise_expected_faraday_response! unless response.kind_of?(Faraday::Response)
|
64
66
|
|
65
67
|
create_response(response)
|
66
68
|
end
|
67
69
|
|
68
70
|
def request(locals = {}, &block)
|
69
71
|
builder = build(locals, &block)
|
70
|
-
|
72
|
+
connection = build_connection(builder)
|
73
|
+
connection.build_request(:post) do |req|
|
74
|
+
req.url(@globals[:endpoint])
|
75
|
+
req.body = @locals[:body]
|
76
|
+
end
|
71
77
|
end
|
72
78
|
|
73
79
|
private
|
@@ -83,37 +89,47 @@ module Savon
|
|
83
89
|
@locals = locals
|
84
90
|
end
|
85
91
|
|
86
|
-
def call_with_logging(
|
87
|
-
|
92
|
+
def call_with_logging(connection)
|
93
|
+
ntlm_auth = handle_ntlm(connection) if @globals.include?(:ntlm)
|
94
|
+
@logger.log_response(connection.post(@globals[:endpoint]) { |request|
|
95
|
+
request.body = @locals[:body]
|
96
|
+
request.headers['Authorization'] = "NTLM #{auth.encode64}" if ntlm_auth
|
97
|
+
@logger.log_request(request)
|
98
|
+
})
|
88
99
|
end
|
89
100
|
|
90
|
-
def
|
91
|
-
|
92
|
-
@globals[:endpoint]
|
101
|
+
def handle_ntlm(connection)
|
102
|
+
ntlm_message = Net::NTLM::Message
|
103
|
+
response = connection.get(@globals[:endpoint]) do |request|
|
104
|
+
request.headers['Authorization'] = 'NTLM ' + ntlm_message::Type1.new.encode64
|
105
|
+
end
|
106
|
+
challenge = response.headers['www-authenticate'][/(?:NTLM|Negotiate) (.*)$/, 1]
|
107
|
+
message = ntlm_message::Type2.decode64(challenge)
|
108
|
+
message.response([:user, :password, :domain].zip(@globals[:ntlm]).to_h)
|
109
|
+
end
|
93
110
|
|
94
|
-
|
111
|
+
def build_connection(builder)
|
112
|
+
@globals[:endpoint] ||= endpoint
|
113
|
+
@locals[:soap_action] ||= soap_action
|
114
|
+
@locals[:body] = builder.to_s
|
115
|
+
@connection = SOAPRequest.new(@globals).build(
|
95
116
|
:soap_action => soap_action,
|
96
117
|
:cookies => @locals[:cookies],
|
97
118
|
:headers => @locals[:headers]
|
98
|
-
)
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
request.headers["MIME-Version"] = "1.0"
|
119
|
+
) do |connection|
|
120
|
+
if builder.multipart
|
121
|
+
connection.request :gzip
|
122
|
+
connection.headers["Content-Type"] = %W[multipart/related
|
123
|
+
type="#{SOAP_REQUEST_TYPE[@globals[:soap_version]]}",
|
124
|
+
start="#{builder.multipart[:start]}",
|
125
|
+
boundary="#{builder.multipart[:multipart_boundary]}"].join("; ")
|
126
|
+
connection.headers["MIME-Version"] = "1.0"
|
127
|
+
end
|
128
|
+
|
129
|
+
connection.headers["Content-Length"] = @locals[:body].bytesize.to_s
|
110
130
|
end
|
111
131
|
|
112
|
-
# TODO: could HTTPI do this automatically in case the header
|
113
|
-
# was not specified manually? [dh, 2013-01-04]
|
114
|
-
request.headers["Content-Length"] = request.body.bytesize.to_s
|
115
132
|
|
116
|
-
request
|
117
133
|
end
|
118
134
|
|
119
135
|
def soap_action
|
@@ -138,8 +154,8 @@ module Savon
|
|
138
154
|
end
|
139
155
|
end
|
140
156
|
|
141
|
-
def
|
142
|
-
raise Error, "Observers need to return
|
157
|
+
def raise_expected_faraday_response!
|
158
|
+
raise Error, "Observers need to return a Faraday::Response to mock " \
|
143
159
|
"the request or nil to execute the request."
|
144
160
|
end
|
145
161
|
|
data/lib/savon/options.rb
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
require "logger"
|
3
|
-
require "httpi"
|
4
3
|
|
5
4
|
module Savon
|
6
5
|
class Options
|
@@ -10,6 +9,10 @@ module Savon
|
|
10
9
|
assign options
|
11
10
|
end
|
12
11
|
|
12
|
+
def deprecate(option)
|
13
|
+
raise DeprecatedOptionError.new(option)
|
14
|
+
end
|
15
|
+
|
13
16
|
attr_reader :option_type
|
14
17
|
|
15
18
|
def [](option)
|
@@ -127,7 +130,7 @@ module Savon
|
|
127
130
|
@options[:namespace] = namespace
|
128
131
|
end
|
129
132
|
|
130
|
-
# The namespace
|
133
|
+
# The namespace identifier.
|
131
134
|
def namespace_identifier(identifier)
|
132
135
|
@options[:namespace_identifier] = identifier
|
133
136
|
end
|
@@ -198,13 +201,11 @@ module Savon
|
|
198
201
|
|
199
202
|
# Whether or not to log.
|
200
203
|
def log(log)
|
201
|
-
HTTPI.log = log
|
202
204
|
@options[:log] = log
|
203
205
|
end
|
204
206
|
|
205
207
|
# The logger to use. Defaults to a Savon::Logger instance.
|
206
208
|
def logger(logger)
|
207
|
-
HTTPI.logger = logger
|
208
209
|
@options[:logger] = logger
|
209
210
|
end
|
210
211
|
|
@@ -257,6 +258,7 @@ module Savon
|
|
257
258
|
|
258
259
|
# Sets the cert key file to use.
|
259
260
|
def ssl_cert_key_file(file)
|
261
|
+
deprecate('ssl_cert_key_file')
|
260
262
|
@options[:ssl_cert_key_file] = file
|
261
263
|
end
|
262
264
|
|
@@ -267,11 +269,13 @@ module Savon
|
|
267
269
|
|
268
270
|
# Sets the cert key password to use.
|
269
271
|
def ssl_cert_key_password(password)
|
272
|
+
deprecate('ssl_cert_key_password')
|
270
273
|
@options[:ssl_cert_key_password] = password
|
271
274
|
end
|
272
275
|
|
273
276
|
# Sets the cert file to use.
|
274
277
|
def ssl_cert_file(file)
|
278
|
+
deprecate('ssl_cert_file')
|
275
279
|
@options[:ssl_cert_file] = file
|
276
280
|
end
|
277
281
|
|
@@ -287,10 +291,12 @@ module Savon
|
|
287
291
|
|
288
292
|
# Sets the ca cert to use.
|
289
293
|
def ssl_ca_cert(cert)
|
294
|
+
deprecate('ssl_ca_cert')
|
290
295
|
@options[:ssl_ca_cert] = cert
|
291
296
|
end
|
292
297
|
|
293
298
|
def ssl_ciphers(ciphers)
|
299
|
+
deprecate('ssl_ciphers')
|
294
300
|
@options[:ssl_ciphers] = ciphers
|
295
301
|
end
|
296
302
|
|
@@ -311,6 +317,7 @@ module Savon
|
|
311
317
|
|
312
318
|
# HTTP digest auth credentials.
|
313
319
|
def digest_auth(*credentials)
|
320
|
+
deprecate('digest_auth')
|
314
321
|
@options[:digest_auth] = credentials.flatten
|
315
322
|
end
|
316
323
|
|
@@ -360,7 +367,7 @@ module Savon
|
|
360
367
|
@options[:multipart] = multipart
|
361
368
|
end
|
362
369
|
|
363
|
-
# Instruct Savon what
|
370
|
+
# Instruct Savon what Faraday adapter it should use instead of default
|
364
371
|
def adapter(adapter)
|
365
372
|
@options[:adapter] = adapter
|
366
373
|
end
|
@@ -389,7 +396,8 @@ module Savon
|
|
389
396
|
defaults = {
|
390
397
|
:advanced_typecasting => true,
|
391
398
|
:response_parser => :nokogiri,
|
392
|
-
:multipart => false
|
399
|
+
:multipart => false,
|
400
|
+
:body => false
|
393
401
|
}
|
394
402
|
|
395
403
|
super defaults.merge(options)
|
@@ -397,7 +405,7 @@ module Savon
|
|
397
405
|
|
398
406
|
# The local SOAP header. Expected to be a Hash or respond to #to_s.
|
399
407
|
# Will be merged with the global SOAP header if both are Hashes.
|
400
|
-
# Otherwise the local option will be
|
408
|
+
# Otherwise the local option will be preferred.
|
401
409
|
def soap_header(header)
|
402
410
|
@options[:soap_header] = header
|
403
411
|
end
|
@@ -457,7 +465,11 @@ module Savon
|
|
457
465
|
@options[:soap_action] = soap_action
|
458
466
|
end
|
459
467
|
|
460
|
-
# Cookies to be used for the next request
|
468
|
+
# Cookies to be used for the next request
|
469
|
+
# @param [Hash] cookies cookies associated to nil will be appended as array cookies, if you need a cookie equal to
|
470
|
+
# and empty string, set it to ""
|
471
|
+
# @example cookies({accept: 'application/json', some-cookie: 'foo', "empty-cookie": "", HttpOnly: nil})
|
472
|
+
# # => "accept=application/json; some-cookie=foo; empty-cookie=; HttpOnly"
|
461
473
|
def cookies(cookies)
|
462
474
|
@options[:cookies] = cookies
|
463
475
|
end
|
@@ -485,5 +497,9 @@ module Savon
|
|
485
497
|
def headers(headers)
|
486
498
|
@options[:headers] = headers
|
487
499
|
end
|
500
|
+
|
501
|
+
def body(body)
|
502
|
+
@options[:body] = body
|
503
|
+
end
|
488
504
|
end
|
489
505
|
end
|
data/lib/savon/request.rb
CHANGED
@@ -1,61 +1,87 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
-
require "
|
2
|
+
require "faraday"
|
3
3
|
|
4
4
|
module Savon
|
5
5
|
class HTTPRequest
|
6
6
|
|
7
|
-
def initialize(globals,
|
7
|
+
def initialize(globals, connection = nil)
|
8
8
|
@globals = globals
|
9
|
-
@
|
10
|
-
end
|
11
|
-
|
12
|
-
def build
|
13
|
-
@http_request
|
9
|
+
@connection = connection || Faraday::Connection.new
|
14
10
|
end
|
15
11
|
|
16
12
|
private
|
17
13
|
|
18
14
|
def configure_proxy
|
19
|
-
|
15
|
+
connection.proxy = @globals[:proxy] if @globals.include? :proxy
|
20
16
|
end
|
21
17
|
|
22
18
|
def configure_timeouts
|
23
|
-
|
24
|
-
|
25
|
-
|
19
|
+
connection.options.open_timeout = @globals[:open_timeout] if @globals.include? :open_timeout
|
20
|
+
connection.options.read_timeout = @globals[:read_timeout] if @globals.include? :read_timeout
|
21
|
+
connection.options.write_timeout = @globals[:write_timeout] if @globals.include? :write_timeout
|
26
22
|
end
|
27
23
|
|
28
24
|
def configure_ssl
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
25
|
+
connection.ssl.verify = @globals[:ssl_verify] if @globals.include? :ssl_verify
|
26
|
+
connection.ssl.ca_file = @globals[:ssl_ca_cert_file] if @globals.include? :ssl_ca_cert_file
|
27
|
+
connection.ssl.verify_hostname = @globals[:verify_hostname] if @globals.include? :verify_hostname
|
28
|
+
connection.ssl.ca_path = @globals[:ssl_ca_cert_path] if @globals.include? :ssl_ca_cert_path
|
29
|
+
connection.ssl.verify_mode = @globals[:ssl_verify_mode] if @globals.include? :ssl_verify_mode
|
30
|
+
connection.ssl.cert_store = @globals[:ssl_cert_store] if @globals.include? :ssl_cert_store
|
31
|
+
connection.ssl.client_cert = @globals[:ssl_cert] if @globals.include? :ssl_cert
|
32
|
+
connection.ssl.client_key = @globals[:ssl_cert_key] if @globals.include? :ssl_cert_key
|
33
|
+
connection.ssl.certificate = @globals[:ssl_certificate] if @globals.include? :ssl_certificate
|
34
|
+
connection.ssl.private_key = @globals[:ssl_private_key] if @globals.include? :ssl_private_key
|
35
|
+
connection.ssl.verify_depth = @globals[:verify_depth] if @globals.include? :verify_depth
|
36
|
+
connection.ssl.version = @globals[:ssl_version] if @globals.include? :ssl_version
|
37
|
+
connection.ssl.min_version = @globals[:ssl_min_version] if @globals.include? :ssl_min_version
|
38
|
+
connection.ssl.max_version = @globals[:ssl_max_version] if @globals.include? :ssl_max_version
|
39
|
+
|
40
|
+
# No Faraday Equivalent out of box, see: https://lostisland.github.io/faraday/#/customization/ssl-options
|
41
|
+
# connection.ssl.cert_file = @globals[:ssl_cert_file] if @globals.include? :ssl_cert_file
|
42
|
+
# connection.ssl.cert_key_file = @globals[:ssl_cert_key_file] if @globals.include? :ssl_cert_key_file
|
43
|
+
# connection.ssl.ca_cert = @globals[:ssl_ca_cert] if @globals.include? :ssl_ca_cert
|
44
|
+
# connection.ssl.ciphers = @globals[:ssl_ciphers] if @globals.include? :ssl_ciphers
|
45
|
+
# connection.ssl.cert_key_password = @globals[:ssl_cert_key_password] if @globals.include? :ssl_cert_key_password
|
46
|
+
|
46
47
|
end
|
47
48
|
|
48
49
|
def configure_auth
|
49
|
-
|
50
|
-
|
51
|
-
|
50
|
+
basic_auth if @globals.include?(:basic_auth)
|
51
|
+
ntlm_auth if @globals.include?(:ntlm)
|
52
|
+
end
|
53
|
+
|
54
|
+
def basic_auth
|
55
|
+
connection.request(:authorization, :basic, *@globals[:basic_auth])
|
56
|
+
end
|
57
|
+
|
58
|
+
def ntlm_auth
|
59
|
+
begin
|
60
|
+
require 'rubyntlm'
|
61
|
+
require 'faraday/net_http_persistent'
|
62
|
+
connection.adapter :net_http_persistent, pool_size: 5
|
63
|
+
rescue LoadError
|
64
|
+
raise LoadError, 'Using NTLM Auth requires both `rubyntlm` and `faraday-net_http_persistent` to be installed.'
|
65
|
+
end
|
52
66
|
end
|
53
67
|
|
54
68
|
def configure_redirect_handling
|
55
|
-
if @globals
|
56
|
-
|
69
|
+
if @globals[:follow_redirects]
|
70
|
+
require 'faraday/follow_redirects'
|
71
|
+
connection.response :follow_redirects
|
57
72
|
end
|
58
73
|
end
|
74
|
+
|
75
|
+
def configure_adapter
|
76
|
+
connection.adapter(*@globals[:adapter]) unless @globals[:adapter].nil?
|
77
|
+
end
|
78
|
+
|
79
|
+
def configure_logging
|
80
|
+
connection.response(:logger, nil, headers: @globals[:log_headers], level: @globals[:logger].level) if @globals[:log]
|
81
|
+
end
|
82
|
+
|
83
|
+
protected
|
84
|
+
attr_reader :connection
|
59
85
|
end
|
60
86
|
|
61
87
|
class WSDLRequest < HTTPRequest
|
@@ -63,18 +89,18 @@ module Savon
|
|
63
89
|
def build
|
64
90
|
configure_proxy
|
65
91
|
configure_timeouts
|
66
|
-
configure_headers
|
67
92
|
configure_ssl
|
68
93
|
configure_auth
|
69
|
-
|
70
|
-
|
71
|
-
|
94
|
+
configure_adapter
|
95
|
+
configure_logging
|
96
|
+
configure_headers
|
97
|
+
connection
|
72
98
|
end
|
73
99
|
|
74
100
|
private
|
75
101
|
|
76
102
|
def configure_headers
|
77
|
-
|
103
|
+
connection.headers = @globals[:headers] if @globals.include? :headers
|
78
104
|
end
|
79
105
|
end
|
80
106
|
|
@@ -88,26 +114,34 @@ module Savon
|
|
88
114
|
def build(options = {})
|
89
115
|
configure_proxy
|
90
116
|
configure_timeouts
|
91
|
-
configure_headers options[:soap_action], options[:headers]
|
92
|
-
configure_cookies options[:cookies]
|
93
117
|
configure_ssl
|
94
118
|
configure_auth
|
119
|
+
configure_headers(options[:soap_action], options[:headers])
|
120
|
+
configure_cookies(options[:cookies])
|
121
|
+
configure_adapter
|
122
|
+
configure_logging
|
95
123
|
configure_redirect_handling
|
96
|
-
|
97
|
-
|
124
|
+
yield(connection) if block_given?
|
125
|
+
connection
|
98
126
|
end
|
99
127
|
|
100
128
|
private
|
101
129
|
|
102
130
|
def configure_cookies(cookies)
|
103
|
-
|
131
|
+
connection.headers['Cookie'] = cookies.map do |key, value|
|
132
|
+
if value.nil?
|
133
|
+
key
|
134
|
+
else
|
135
|
+
"#{key}=#{value}"
|
136
|
+
end
|
137
|
+
end.join('; ') if cookies
|
104
138
|
end
|
105
139
|
|
106
140
|
def configure_headers(soap_action, headers)
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
141
|
+
connection.headers = @globals[:headers] if @globals.include? :headers
|
142
|
+
connection.headers.merge!(headers) if headers
|
143
|
+
connection.headers["SOAPAction"] ||= %{"#{soap_action}"} if soap_action
|
144
|
+
connection.headers["Content-Type"] ||= CONTENT_TYPE[@globals[:soap_version]] % @globals[:encoding]
|
111
145
|
end
|
112
146
|
end
|
113
147
|
end
|
data/lib/savon/request_logger.rb
CHANGED
@@ -27,21 +27,24 @@ module Savon
|
|
27
27
|
def log_headers?
|
28
28
|
@globals[:log_headers]
|
29
29
|
end
|
30
|
-
|
31
|
-
private
|
32
|
-
|
33
30
|
def log_request(request)
|
34
|
-
|
31
|
+
return unless log?
|
32
|
+
logger.info { "SOAP request: #{request.path}" }
|
35
33
|
logger.info { headers_to_log(request.headers) } if log_headers?
|
36
34
|
logger.debug { body_to_log(request.body) }
|
37
35
|
end
|
38
36
|
|
39
37
|
def log_response(response)
|
40
|
-
|
38
|
+
return response unless log?
|
39
|
+
logger.info { "SOAP response (status #{response.status})" }
|
41
40
|
logger.debug { headers_to_log(response.headers) } if log_headers?
|
42
41
|
logger.debug { body_to_log(response.body) }
|
42
|
+
response
|
43
43
|
end
|
44
44
|
|
45
|
+
private
|
46
|
+
|
47
|
+
|
45
48
|
def headers_to_log(headers)
|
46
49
|
headers.map { |key, value| "#{key}: #{value}" }.join("\n")
|
47
50
|
end
|
data/lib/savon/soap_fault.rb
CHANGED
@@ -5,7 +5,7 @@ module Savon
|
|
5
5
|
def self.present?(http, xml = nil)
|
6
6
|
xml ||= http.body
|
7
7
|
fault_node = xml.include?("Fault>")
|
8
|
-
soap1_fault = xml.match(/faultcode
|
8
|
+
soap1_fault = xml.match(/faultcode\/?>/) && xml.match(/faultstring\/?>/)
|
9
9
|
soap2_fault = xml.include?("Code>") && xml.include?("Reason>")
|
10
10
|
|
11
11
|
fault_node && (soap1_fault || soap2_fault)
|
data/lib/savon/version.rb
CHANGED
data/lib/savon.rb
CHANGED
@@ -7,6 +7,14 @@ module Savon
|
|
7
7
|
UnknownOperationError = Class.new(Error)
|
8
8
|
InvalidResponseError = Class.new(Error)
|
9
9
|
|
10
|
+
class DeprecatedOptionError < Error
|
11
|
+
attr_accessor :option
|
12
|
+
def initialize(option)
|
13
|
+
@option = option
|
14
|
+
super("#{option} is deprecated as it is not supported in Faraday. See https://github.com/savonrb/savon/blob/main/UPGRADING.md for more information.")
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
10
18
|
def self.client(globals = {}, &block)
|
11
19
|
Client.new(globals, &block)
|
12
20
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: savon
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 3.0.0.rc1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Daniel Harrington
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-
|
11
|
+
date: 2024-07-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: nori
|
@@ -25,45 +25,61 @@ dependencies:
|
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '2.4'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
|
-
name:
|
28
|
+
name: faraday
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- - "
|
31
|
+
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: 2.
|
34
|
-
|
33
|
+
version: '2.8'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
35
39
|
- !ruby/object:Gem::Version
|
36
|
-
version: '
|
40
|
+
version: '2.8'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: faraday-gzip
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '2.0'
|
37
48
|
type: :runtime
|
38
49
|
prerelease: false
|
39
50
|
version_requirements: !ruby/object:Gem::Requirement
|
40
51
|
requirements:
|
41
|
-
- - "
|
52
|
+
- - "~>"
|
42
53
|
- !ruby/object:Gem::Version
|
43
|
-
version: 2.
|
44
|
-
|
54
|
+
version: '2.0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: faraday-follow_redirects
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
45
60
|
- !ruby/object:Gem::Version
|
46
|
-
version: '
|
61
|
+
version: '0.3'
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0.3'
|
47
69
|
- !ruby/object:Gem::Dependency
|
48
70
|
name: wasabi
|
49
71
|
requirement: !ruby/object:Gem::Requirement
|
50
72
|
requirements:
|
51
|
-
- - "
|
73
|
+
- - ">"
|
52
74
|
- !ruby/object:Gem::Version
|
53
|
-
version: '
|
54
|
-
- - "<"
|
55
|
-
- !ruby/object:Gem::Version
|
56
|
-
version: '6'
|
75
|
+
version: '5'
|
57
76
|
type: :runtime
|
58
77
|
prerelease: false
|
59
78
|
version_requirements: !ruby/object:Gem::Requirement
|
60
79
|
requirements:
|
61
|
-
- - "
|
62
|
-
- !ruby/object:Gem::Version
|
63
|
-
version: '3.7'
|
64
|
-
- - "<"
|
80
|
+
- - ">"
|
65
81
|
- !ruby/object:Gem::Version
|
66
|
-
version: '
|
82
|
+
version: '5'
|
67
83
|
- !ruby/object:Gem::Dependency
|
68
84
|
name: akami
|
69
85
|
requirement: !ruby/object:Gem::Requirement
|
@@ -134,6 +150,34 @@ dependencies:
|
|
134
150
|
- - "~>"
|
135
151
|
- !ruby/object:Gem::Version
|
136
152
|
version: '2.5'
|
153
|
+
- !ruby/object:Gem::Dependency
|
154
|
+
name: faraday-net_http_persistent
|
155
|
+
requirement: !ruby/object:Gem::Requirement
|
156
|
+
requirements:
|
157
|
+
- - "~>"
|
158
|
+
- !ruby/object:Gem::Version
|
159
|
+
version: '2.1'
|
160
|
+
type: :development
|
161
|
+
prerelease: false
|
162
|
+
version_requirements: !ruby/object:Gem::Requirement
|
163
|
+
requirements:
|
164
|
+
- - "~>"
|
165
|
+
- !ruby/object:Gem::Version
|
166
|
+
version: '2.1'
|
167
|
+
- !ruby/object:Gem::Dependency
|
168
|
+
name: rubyntlm
|
169
|
+
requirement: !ruby/object:Gem::Requirement
|
170
|
+
requirements:
|
171
|
+
- - ">="
|
172
|
+
- !ruby/object:Gem::Version
|
173
|
+
version: '0.6'
|
174
|
+
type: :development
|
175
|
+
prerelease: false
|
176
|
+
version_requirements: !ruby/object:Gem::Requirement
|
177
|
+
requirements:
|
178
|
+
- - ">="
|
179
|
+
- !ruby/object:Gem::Version
|
180
|
+
version: '0.6'
|
137
181
|
- !ruby/object:Gem::Dependency
|
138
182
|
name: rack
|
139
183
|
requirement: !ruby/object:Gem::Requirement
|
@@ -168,6 +212,34 @@ dependencies:
|
|
168
212
|
- - "<"
|
169
213
|
- !ruby/object:Gem::Version
|
170
214
|
version: '7'
|
215
|
+
- !ruby/object:Gem::Dependency
|
216
|
+
name: httpclient
|
217
|
+
requirement: !ruby/object:Gem::Requirement
|
218
|
+
requirements:
|
219
|
+
- - ">="
|
220
|
+
- !ruby/object:Gem::Version
|
221
|
+
version: '0'
|
222
|
+
type: :development
|
223
|
+
prerelease: false
|
224
|
+
version_requirements: !ruby/object:Gem::Requirement
|
225
|
+
requirements:
|
226
|
+
- - ">="
|
227
|
+
- !ruby/object:Gem::Version
|
228
|
+
version: '0'
|
229
|
+
- !ruby/object:Gem::Dependency
|
230
|
+
name: mutex_m
|
231
|
+
requirement: !ruby/object:Gem::Requirement
|
232
|
+
requirements:
|
233
|
+
- - ">="
|
234
|
+
- !ruby/object:Gem::Version
|
235
|
+
version: '0'
|
236
|
+
type: :development
|
237
|
+
prerelease: false
|
238
|
+
version_requirements: !ruby/object:Gem::Requirement
|
239
|
+
requirements:
|
240
|
+
- - ">="
|
241
|
+
- !ruby/object:Gem::Version
|
242
|
+
version: '0'
|
171
243
|
- !ruby/object:Gem::Dependency
|
172
244
|
name: byebug
|
173
245
|
requirement: !ruby/object:Gem::Requirement
|
@@ -282,7 +354,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
282
354
|
requirements:
|
283
355
|
- - ">="
|
284
356
|
- !ruby/object:Gem::Version
|
285
|
-
version:
|
357
|
+
version: 3.0.0
|
286
358
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
287
359
|
requirements:
|
288
360
|
- - ">="
|