savon 2.17.0 → 2.17.1
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 +5 -0
- data/README.md +38 -63
- data/lib/savon/operation.rb +6 -2
- data/lib/savon/transport/faraday.rb +4 -5
- data/lib/savon/transport/httpi.rb +0 -2
- data/lib/savon/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 00ae14802f108cb0df2757b85888a35df4b6b0e462ae0d01c1eedc9b4f9c123c
|
|
4
|
+
data.tar.gz: cee1d2d13ed6e869611817271c43352c470c4c7fb79e72dc7e6e7a4d9ac37191
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 8b754234ac51e2213f92254a88345743cc54e09026e220d85931b8bfe0ba78f5a417f81e561047b37410f52713f3583120c6d3095ab68a2b9705427f03822d07
|
|
7
|
+
data.tar.gz: 49a3260e064073d9370b80b376db5f9c75bab5e38dbdf7db2ffc8533dc2a58652bb0699830468f1e59319a98fd7210503a6c999b386e3ec6c9f4d23ac7f813e1
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
# Savon changelog
|
|
2
2
|
|
|
3
|
+
## 2.17.1 (2026-05-21)
|
|
4
|
+
|
|
5
|
+
* Fix: [#1008](https://github.com/savonrb/savon/pull/1008) - The HTTPI and Faraday transports no longer set an explicit `Content-Length` request header. The underlying HTTP library already computes it from the body; sending it as well produced a duplicate header on adapters that do not deduplicate (e.g. httpclient), which some servers reject.
|
|
6
|
+
* Fix: Requests using `attachments` were sent with a plain `text/xml` Content-Type instead of `multipart/related`. The 2.17.0 transport refactor assembled the request headers before the multipart body was built, leaving `Builder#multipart` empty at header time, so servers received a multipart body labelled as plain XML. 2.16.x and earlier are unaffected.
|
|
7
|
+
|
|
3
8
|
## 2.17.0 (2026-05-19)
|
|
4
9
|
|
|
5
10
|
**Add opt-in Faraday transport**
|
data/README.md
CHANGED
|
@@ -2,103 +2,78 @@
|
|
|
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)
|
|
7
|
-
|
|
8
5
|
[](https://github.com/savonrb/savon/actions/workflows/ci.yml)
|
|
9
6
|
[](http://badge.fury.io/rb/savon)
|
|
10
7
|
[](https://coveralls.io/r/savonrb/savon)
|
|
11
8
|
|
|
9
|
+
Savon is a SOAP client for Ruby. [SOAP is the protocol](https://www.w3.org/TR/soap/) spoken by many enterprise systems in banking, government, ERP or payroll. When they hand you a WSDL URL or file instead of a REST spec, it's SOAP. Savon reads the WSDL, maps available operations to Ruby symbols, converts Ruby hashes to SOAP envelopes and turns XML responses into hashes you can work with.
|
|
12
10
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
Savon is available through [Rubygems](http://rubygems.org/gems/savon) and can be installed via:
|
|
16
|
-
|
|
17
|
-
```
|
|
18
|
-
$ gem install savon
|
|
19
|
-
```
|
|
11
|
+
Full documentation is at [savonrb.com](https://savonrb.com).
|
|
20
12
|
|
|
21
|
-
|
|
13
|
+
## Installation
|
|
22
14
|
|
|
23
|
-
```
|
|
24
|
-
gem 'savon', '~> 2.
|
|
15
|
+
```ruby
|
|
16
|
+
gem 'savon', '~> 2.17'
|
|
25
17
|
```
|
|
26
18
|
|
|
27
|
-
## Usage
|
|
19
|
+
## Usage
|
|
28
20
|
|
|
29
|
-
```
|
|
21
|
+
```ruby
|
|
30
22
|
require 'savon'
|
|
31
23
|
|
|
32
|
-
#
|
|
33
|
-
client = Savon.client(wsdl: '
|
|
34
|
-
|
|
35
|
-
# or: create a client with a wsdl provided as a string
|
|
36
|
-
client = Savon.client do |config|
|
|
37
|
-
wsdl_content = File.read("/path/to/wsdl")
|
|
38
|
-
config.wsdl wsdl_content
|
|
39
|
-
end
|
|
24
|
+
# Point Savon to a local or remote WSDL document
|
|
25
|
+
client = Savon.client(wsdl: 'https://service.example.com?wsdl')
|
|
40
26
|
|
|
27
|
+
# See what the service exposes
|
|
41
28
|
client.operations
|
|
42
|
-
# => [:find_user, :
|
|
29
|
+
# => [:find_user, :create_user]
|
|
43
30
|
|
|
44
|
-
#
|
|
31
|
+
# Make a request and work with the response
|
|
45
32
|
response = client.call(:find_user, message: { id: 42 })
|
|
33
|
+
response.body[:find_user_response]
|
|
34
|
+
# => { id: 42, name: "Hoff" }
|
|
46
35
|
|
|
47
|
-
|
|
48
|
-
|
|
36
|
+
# Savon raises a Savon::SOAPFault when the server returns a SOAP fault
|
|
37
|
+
rescue Savon::SOAPFault => e
|
|
38
|
+
puts e.to_hash.dig(:fault, :faultstring)
|
|
49
39
|
```
|
|
50
40
|
|
|
51
|
-
|
|
52
|
-
[integration tests](https://github.com/savonrb/savon/tree/version2/spec/integration).
|
|
53
|
-
|
|
54
|
-
## Faraday transport
|
|
55
|
-
|
|
56
|
-
Savon uses HTTPI for HTTP by default. To opt into Faraday instead, add `faraday` to your Gemfile and set `transport: :faraday`:
|
|
41
|
+
Enable logging to see the raw SOAP envelopes. That's probably the single most useful thing while getting a new integration working:
|
|
57
42
|
|
|
58
43
|
```ruby
|
|
59
44
|
client = Savon.client(
|
|
60
|
-
|
|
61
|
-
|
|
45
|
+
wsdl: 'https://service.example.com?wsdl',
|
|
46
|
+
pretty_print_xml: true,
|
|
47
|
+
log: true
|
|
62
48
|
)
|
|
63
49
|
```
|
|
64
50
|
|
|
65
|
-
|
|
51
|
+
### Authentication
|
|
66
52
|
|
|
67
|
-
|
|
68
|
-
client.faraday.ssl.verify = false
|
|
69
|
-
client.faraday.options.timeout = 30
|
|
70
|
-
client.faraday.options.open_timeout = 5
|
|
71
|
-
client.faraday.headers["Authorization"] = "Bearer #{token}"
|
|
72
|
-
client.faraday.use Faraday::Response::Logger
|
|
73
|
-
```
|
|
53
|
+
Most enterprise services require authentication. Common options:
|
|
74
54
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
55
|
+
```ruby
|
|
56
|
+
# HTTP basic auth
|
|
57
|
+
Savon.client(wsdl: '...', basic_auth: ['user', 'secret'])
|
|
78
58
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
* 2.12.x - MRI 2.2, 2.3, 2.4, 2.5
|
|
83
|
-
* 2.11.x - MRI 2.0, 2.1, 2.2, and 2.3
|
|
59
|
+
# WS-Security (WSSE)
|
|
60
|
+
Savon.client(wsdl: '...', wsse_auth: ['user', 'secret', :digest], wsse_timestamp: true)
|
|
61
|
+
```
|
|
84
62
|
|
|
85
|
-
|
|
63
|
+
See [Authentication](https://savonrb.com/version2/globals.html) on the website for HTTP digest, NTLM, and certificate-based options.
|
|
86
64
|
|
|
87
|
-
|
|
65
|
+
### Transport
|
|
88
66
|
|
|
89
|
-
|
|
67
|
+
Savon uses [HTTPI](https://github.com/savonrb/httpi) for HTTP by default. Since v2.17.0 you can opt-in to use Faraday by passing `transport: :faraday` which exposes the Faraday connection at `client.faraday` for you to configure. Savon is only adding some SOAP-specifics on top.
|
|
90
68
|
|
|
91
|
-
|
|
92
|
-
$ bundle install
|
|
93
|
-
$ bundle exec rspec
|
|
94
|
-
```
|
|
69
|
+
## Ruby support
|
|
95
70
|
|
|
96
|
-
|
|
71
|
+
Savon 2.x requires Ruby 3.0 or later. See the [changelog](CHANGELOG.md) for historical compatibility.
|
|
97
72
|
|
|
98
|
-
|
|
99
|
-
- See https://github.com/savonrb/savon/issues/488 for more info
|
|
73
|
+
## Known limitations
|
|
100
74
|
|
|
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.
|
|
101
76
|
|
|
102
|
-
##
|
|
77
|
+
## Contributing
|
|
103
78
|
|
|
104
|
-
|
|
79
|
+
See [CONTRIBUTING.md](CONTRIBUTING.md). MIT licensed.
|
data/lib/savon/operation.rb
CHANGED
|
@@ -78,7 +78,9 @@ module Savon
|
|
|
78
78
|
|
|
79
79
|
response =
|
|
80
80
|
if response.nil?
|
|
81
|
-
|
|
81
|
+
body = builder.to_s
|
|
82
|
+
headers = soap_headers(builder)
|
|
83
|
+
@transport.post(endpoint.to_s, headers, body, @locals)
|
|
82
84
|
else
|
|
83
85
|
normalize_observer_response(response)
|
|
84
86
|
end
|
|
@@ -97,7 +99,9 @@ module Savon
|
|
|
97
99
|
end
|
|
98
100
|
|
|
99
101
|
builder = build(locals, &block)
|
|
100
|
-
|
|
102
|
+
# Build the body before soap_headers - see #call.
|
|
103
|
+
body = builder.to_s
|
|
104
|
+
@transport.to_httpi_request(endpoint.to_s, soap_headers(builder), body, @locals)
|
|
101
105
|
end
|
|
102
106
|
|
|
103
107
|
private
|
|
@@ -8,7 +8,7 @@ module Savon
|
|
|
8
8
|
# Faraday-backed HTTP transport for the opt-in Faraday path.
|
|
9
9
|
#
|
|
10
10
|
# Encapsulates everything Faraday-specific:
|
|
11
|
-
# * header assembly (SOAP + global + local + cookies
|
|
11
|
+
# * header assembly (SOAP + global + local + cookies)
|
|
12
12
|
# * request execution via the caller-configured Faraday::Connection
|
|
13
13
|
#
|
|
14
14
|
# Transport-level concerns (SSL, auth, proxy, timeouts, middleware) are
|
|
@@ -33,7 +33,7 @@ module Savon
|
|
|
33
33
|
# @param locals [Savon::LocalOptions] per-request options
|
|
34
34
|
# @return [Transport::Response]
|
|
35
35
|
def post(url, soap_headers, body, locals)
|
|
36
|
-
headers = build_headers(soap_headers,
|
|
36
|
+
headers = build_headers(soap_headers, locals)
|
|
37
37
|
|
|
38
38
|
log_request(url, headers, body) if log?
|
|
39
39
|
|
|
@@ -49,8 +49,8 @@ module Savon
|
|
|
49
49
|
|
|
50
50
|
# Merges all header sources in precedence order:
|
|
51
51
|
# locals[:headers] > globals[:headers] > soap_headers
|
|
52
|
-
# Appends Cookie from locals[:cookies]
|
|
53
|
-
def build_headers(soap_headers,
|
|
52
|
+
# Appends Cookie from locals[:cookies].
|
|
53
|
+
def build_headers(soap_headers, locals)
|
|
54
54
|
headers = {}
|
|
55
55
|
headers.merge!(@globals[:headers]) if @globals.include?(:headers)
|
|
56
56
|
headers.merge!(locals[:headers]) if locals.include?(:headers)
|
|
@@ -62,7 +62,6 @@ module Savon
|
|
|
62
62
|
headers["Cookie"] = locals[:cookies].map(&:name_and_value).join(";")
|
|
63
63
|
end
|
|
64
64
|
|
|
65
|
-
headers["Content-Length"] = body.bytesize.to_s
|
|
66
65
|
headers
|
|
67
66
|
end
|
|
68
67
|
end
|
data/lib/savon/version.rb
CHANGED