savon 2.17.2 → 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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ffcf3a770d4dd548ec193c9f6d8b8723eef3a661273dc50e8bb5a06ba99f0f13
4
- data.tar.gz: d03d1de9d1bc5b1af722b56dc71e99acc1a46f951f45d377b9eea2974016f2ed
3
+ metadata.gz: 3f58a5268715a082369bc199231506447defea5f760fae67cb51507a9011836c
4
+ data.tar.gz: d349d7d546fb236e45f433047bd575dd6f6ec206254707094f02420ec58dfc07
5
5
  SHA512:
6
- metadata.gz: 5a5e490cbf30a0e2216439dc9ceb51493c5b5fec107ce3ff4219eb8c5ded1c9e3b612b6bb8b44c4163d12a97c73415f441f33542b35e22bd7b1908f8cb123fa2
7
- data.tar.gz: c6d5c85d39f406f75e5e0b005b250e5a97da5d60e42ca44fe827d72f97b2fd967a054684be73e8134c19506e8da6e8dcc7222769fa017d2b7c02cf2336e6dc12
6
+ metadata.gz: 91d6cd948edbb82b643fa5aaeef265dcfeef5037459478f0815f01bdacbe04cb159165301a9f0ebc75fd897470ff2a0b51de1fa256123843698a14925f5ebf43
7
+ data.tar.gz: 3a9fe95352e4f85e9e88f7eaffba5fb04df58085380ed7c62e8c0f31c0b110b5127c494125f373e97489c789991b6c1271e68df000606c3e1a3311a17edc951a
data/CHANGELOG.md CHANGED
@@ -1,91 +1,22 @@
1
1
  # Savon changelog
2
2
 
3
- All notable changes to this project will be documented in this file.
4
-
5
- The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
- and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
-
8
- ## [2.17.2] - 2026-06-10
9
-
10
- **Fix CVE-2026-53510 and restore 2.17.0 cookie regressions**
11
-
12
- ### Fixed
13
-
14
- * **Fix CVE-2026-53510** `Savon::Model` generated SOAP operation methods by interpolating operation names into Ruby source passed to `module_eval`. An attacker who can control the operation names of a WSDL, can inject Ruby code that executes in the application process. This affects only the `.all_operations` class method provided by `Savon::Model` to automatically register all operations provided by the WSDL. Configuring `Savon::Model` with trusted operation names via `.operations` is safe. Thanks to @connorshea for securely disclosing this, providing a proof and a great report.
15
- * **`:cookies` request option works again.** The 2.17.0 transport refactor reimplemented cookie handling on top of `Array#map`, which broke callers passing an object that responds to `#cookies` and lost cookie-name de-duplication via `HTTPI::CookieStore`. The HTTPI transport delegates to `HTTPI::Request#set_cookies` again, restoring both shapes.
16
- * **`response.http.cookies` works again.** 2.17.0's `Savon::Transport::Response` only exposed `code`, `headers`, and `body`. The HTTPI transport now returns `Array<HTTPI::Cookie>` (matching 2.12.1). The Faraday transport returns `Hash<String, String>` so Faraday callers do not need HTTPI types.
17
- * **`:attachments` now works with a user-supplied `:xml` envelope** ([#761](https://github.com/savonrb/savon/pull/761)). Multipart support shipped in 2.13.0 but only wrapped envelopes Savon built itself. When a caller passed their own `:xml`, attachments were silently dropped.
18
-
19
- ### Added
20
-
21
- * **Faraday `:cookies` option accepts a `String` or `Hash`.** Strings are used verbatim, Hashes are formatted as `"name=value; name=value"`. Round-trippable with the Faraday response shape.
22
- * **Three Nori response-parsing options exposed as Savon globals:** `:empty_tag_value` (default `nil`), `:convert_dashes_to_underscores` (default `true`), and `:scrub_xml` (default `true`). Defaults match Nori's own for backwards compatibility.
23
-
24
- ### Changed
25
-
26
- * **Minimum Nori version is now `~> 2.7`** (was `~> 2.4`). Needed for the new parsing options (`:empty_tag_value` arrived in Nori 2.6.0, `:scrub_xml` in 2.7.0). The 2.5–2.7 series also brings fixes callers benefit from automatically: invalid byte sequences parse instead of raising, REXML no longer turns `&lt;` inside CDATA into `<`, `xs:date`/`xs:time`/`xs:dateTime` typecasting was corrected, and Nori stopped monkey-patching `String` and `Object`.
27
- * **Faraday migration hints are now value-aware and verified.** Each hint prints the caller's actual option value and spells out the full gem/require/setup where needed. Fixed several incorrect examples and added tests to verify every hint.
28
-
29
- ### Deprecated
30
-
31
- * Deprecated the global and local `:multipart` options. They have been no-ops since v2.13.0. Specifically since commit 4e7ae5e. Savon detects multipart responses by checking the `Content-Type` header.
32
-
33
- ## [2.17.1] - 2026-05-21
34
-
35
- ### Fixed
36
-
37
- * [#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.
38
- * 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.
39
-
40
- ## [2.17.0] - 2026-05-19
41
-
42
- **Add opt-in Faraday transport**
43
-
44
- Callers who set `transport: :faraday` get a memoized `Faraday::Connection` via `client.faraday` and full control over middleware, SSL, auth, and timeouts. Callers who do not set this option see no behavior change. HTTPI remains the default for 2.x.
45
-
46
- ### Added
47
-
48
- * `transport: :faraday` global option. Defaults to `:httpi` (#992).
49
- * `client.faraday` returns a memoized `Faraday::Connection` for configuring middleware, SSL, auth, and timeouts when using the Faraday transport.
50
- * `Savon.client` raises if `transport: :faraday` is set but the faraday gem is not installed, or if any httpi-specific global option (`proxy`, timeouts, `ssl`, auth, `adapter`) is set alongside it. All conflicts are reported with their Faraday equivalents.
51
-
52
- ### Changed
53
-
54
- * Observers must return `Savon::Transport::Response` (or `nil`) instead of `HTTPI::Response`.
55
-
56
- ### Deprecated
57
-
58
- * The HTTPI transport (currently the default) and all HTTPI-specific global options enumerated in `Savon::FaradayMigrationHint::OPTIONS` (`proxy`, `open_timeout`, `read_timeout`, `write_timeout`, the `ssl_*` family, `basic_auth`, `digest_auth`, `ntlm`, `follow_redirects`, `adapter`) will be removed in 3.0. Migrate to `transport: :faraday`. `FaradayMigrationHint` shows the Faraday equivalent for each option.
59
- * Returning `HTTPI::Response` from observers emits a deprecation warning and will be removed in 3.0. Return `Savon::Transport::Response` instead.
60
-
61
- The Faraday transport unblocks:
62
-
63
- * redirect following for WSDL fetches via `faraday-follow-redirects` middleware (#1033, savonrb/wasabi#18)
64
- * digest authentication via `faraday-digestauth` middleware (#1021, savonrb/httpi#250)
65
- * proxy authentication with special characters in passwords (#941)
66
- * and setting an `Accept` header for WSDL requests from Rails apps (savonrb/wasabi#115)
67
-
68
- ## [2.16.0] - 2026-05-18
69
-
70
- **Restore compatibility**
71
-
72
- 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.
73
-
74
- ### Fixed
75
-
76
- * 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.
77
- * 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.
78
- * 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.
79
- * Raise a proper `SOAPFault` instead of a raw exception when `soap:Fault` contains invalid encoding (#923).
80
- * `SOAPFault.present?` was ignoring its `xml` argument and always operating on the instance's own body.
81
-
82
- ### Changed
83
-
84
- * Added Ruby 3.4 (#1024) and Ruby 4.0 (#1039) to the CI test matrix.
85
-
86
- ### Deprecated
87
-
88
- * `Savon::Response#hash` emits a deprecation warning on each call. Use `#full_hash` going forward. Will be removed in 3.0.
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
89
20
 
90
21
  ## 2.15.1 (2024-07-08)
91
22
 
@@ -1239,8 +1170,3 @@ Pay attention to the following list and read the updated Wiki: http://wiki.githu
1239
1170
  ## 0.5.0 (2009-11-29)
1240
1171
 
1241
1172
  * Complete rewrite and public release.
1242
-
1243
- [2.17.2]: https://github.com/savonrb/savon/compare/v2.17.1...v2.17.2
1244
- [2.17.1]: https://github.com/savonrb/savon/compare/v2.17.0...v2.17.1
1245
- [2.17.0]: https://github.com/savonrb/savon/compare/v2.16.0...v2.17.0
1246
- [2.16.0]: https://github.com/savonrb/savon/compare/v2.15.1...v2.16.0
data/README.md CHANGED
@@ -2,88 +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
  [![Ruby](https://github.com/savonrb/savon/actions/workflows/ci.yml/badge.svg)](https://github.com/savonrb/savon/actions/workflows/ci.yml)
6
9
  [![Gem Version](https://badge.fury.io/rb/savon.svg)](http://badge.fury.io/rb/savon)
10
+ [![Code Climate](https://codeclimate.com/github/savonrb/savon.svg)](https://codeclimate.com/github/savonrb/savon)
7
11
  [![Coverage Status](https://coveralls.io/repos/savonrb/savon/badge.svg)](https://coveralls.io/r/savonrb/savon)
8
12
 
9
- Savon is a SOAP client for Ruby. [SOAP is the protocol](https://www.w3.org/TR/soap/) spoken by many enterprise systems. 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.
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
- ```ruby
16
- gem 'savon', '~> 2.17'
17
+ Savon is available through [Rubygems](http://rubygems.org/gems/savon) and can be installed via:
18
+
19
+ ```
20
+ $ gem install savon
17
21
  ```
18
22
 
19
- ## Usage
23
+ or add it to your Gemfile like this:
20
24
 
21
- ```ruby
25
+ ```
26
+ gem 'savon', '~> 3.0.0'
27
+ ```
28
+
29
+ ## Usage example
30
+
31
+ ``` ruby
22
32
  require 'savon'
23
33
 
24
- # Point Savon to a local or remote WSDL document
25
- client = Savon.client(wsdl: 'https://service.example.com?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, :create_user]
44
+ # => [:find_user, :list_users]
30
45
 
31
- # Make a request and work with the response
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
- # 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
+ response.body
50
+ # => { find_user_response: { id: 42, name: 'Hoff' } }
39
51
  ```
40
52
 
41
- Enable logging to see the raw SOAP envelopes. That's probably the single most useful thing while getting a new integration working:
53
+ For more examples, you should check out the
54
+ [integration tests](https://github.com/savonrb/savon/tree/version2/spec/integration).
42
55
 
43
- ```ruby
44
- client = Savon.client(
45
- wsdl: 'https://service.example.com?wsdl',
46
- pretty_print_xml: true,
47
- log: true
48
- )
49
- ```
50
-
51
- ### Authentication
52
-
53
- Most enterprise services require authentication. Common options:
54
-
55
- ```ruby
56
- # HTTP basic auth
57
- Savon.client(wsdl: '...', basic_auth: ['user', 'secret'])
56
+ ## Upgrading from v2.x to v3.x
58
57
 
59
- # WS-Security (WSSE)
60
- Savon.client(wsdl: '...', wsse_auth: ['user', 'secret', :digest], wsse_timestamp: true)
61
- ```
62
-
63
- See [Authentication](https://savonrb.com/version2/globals.html) on the website for HTTP digest, NTLM, and certificate-based options.
58
+ See [UPGRADING.md](UPGRADING.md) for more information.
64
59
 
65
- ### Transport
60
+ ## Ruby version support
66
61
 
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.
62
+ Every savon release is tested with contemporary supported versions of ruby. Historical compatibility information:
68
63
 
69
- ## Ruby support
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
70
69
 
71
- Savon 2.x requires Ruby >= 3.0.0, kept as the lower bound for backward compatibility. Note that Ruby 3.0–3.3 are EOL or security-only. Ruby 3.4+ is the minimum version with active maintenance.
70
+ If you are running MRI 1.8.7, try a 2.6.x release.
72
71
 
73
- ## Versioning & stability
72
+ Most changes are not backported to older versions of savon, or unsupported ruby versions.
74
73
 
75
- Savon follows [Semantic Versioning 2.0.0](https://semver.org/spec/v2.0.0.html). The changelog format is [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
74
+ ## Running tests
76
75
 
77
- **The 2.x line is anchored on 2.12.1.** Every 2.x release is supposed to be safe to upgrade to from 2.12.1, and anything that worked in 2.12.1 keeps working. We do not remove or rename public APIs in the 2.x line. New behavior is opt-in and requires an explicit option change. If you found a problem with that, please let us know.
78
-
79
- We only soft-deprecate APIs we plan to remove. The `Deprecated` sections of the [changelog](CHANGELOG.md) list every API that is planned to be removed with version 3.0.
76
+ ```bash
77
+ $ bundle install
78
+ $ bundle exec rspec
79
+ ```
80
80
 
81
- Callers on 2.13.0–2.15.x may see specific post-2.12.1 behaviors restored to the 2.12.1 contract. This is intentional.
81
+ ## FAQ
82
82
 
83
- ## Known limitations
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
84
85
 
85
- **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.
86
86
 
87
- ## Contributing
87
+ ## Documentation
88
88
 
89
- See [CONTRIBUTING.md](CONTRIBUTING.md). MIT licensed.
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
- desc "Alias for spec task"
16
- task test: :spec
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.positive?
10
+ if block.arity > 0
11
11
  block.call(@target)
12
12
  else
13
- @original = eval("self", block.binding, __FILE__, __LINE__)
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
- }.freeze
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
- }.freeze
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: 2)
37
+ Nokogiri.XML(to_s).to_xml(:indent => 2)
39
38
  end
40
39
 
41
40
  def build_document
@@ -70,45 +69,35 @@ module Savon
70
69
  @body_attributes ||= @signature.nil? ? {} : @signature.body_attributes
71
70
  end
72
71
 
73
- # Returns the request body as a String. When the caller supplies a pre-built
74
- # envelope via the :xml local option it is used verbatim, but it must still
75
- # be wrapped in a multipart message when :attachments are present.
76
- # Otherwise the attachments are silently dropped.
77
72
  def to_s
78
- if @locals.include?(:xml)
79
- xml = @locals[:xml]
80
- @locals[:attachments] ? build_multipart_message(xml) : xml
81
- else
82
- build_document
83
- end
73
+ return @locals[:xml] if @locals.include? :xml
74
+ build_document
84
75
  end
85
76
 
86
77
  private
87
78
 
88
79
  def convert_type_definitions_to_hash
89
- @wsdl.type_definitions.each_with_object({}) do |(path, type), memo|
80
+ @wsdl.type_definitions.inject({}) do |memo, (path, type)|
90
81
  memo[path] = type
82
+ memo
91
83
  end
92
84
  end
93
85
 
94
86
  def convert_type_namespaces_to_hash
95
- @wsdl.type_namespaces.each_with_object({}) do |(path, uri), memo|
87
+ @wsdl.type_namespaces.inject({}) do |memo, (path, uri)|
96
88
  key, value = use_namespace(path, uri)
97
89
  memo[key] = value
90
+ memo
98
91
  end
99
92
  end
100
93
 
101
94
  def use_namespace(path, uri)
102
95
  @internal_namespace_count ||= 0
103
96
 
104
- unless (identifier = namespace_by_uri(uri))
105
- wsdl_identifier = @wsdl.document? ? @wsdl.parser.namespaces.key(uri) : nil
106
- # The prefix may already be taken by the target namespace or a user-supplied
107
- # :namespaces override - fall back to ins0, ins1... rather than overwriting it.
108
- wsdl_identifier = nil if wsdl_identifier && namespaces.key?("xmlns:#{wsdl_identifier}")
109
- identifier = wsdl_identifier || "ins#{@internal_namespace_count}"
97
+ unless identifier = namespace_by_uri(uri)
98
+ identifier = "ins#{@internal_namespace_count}"
110
99
  namespaces["xmlns:#{identifier}"] = uri
111
- @internal_namespace_count += 1 unless wsdl_identifier
100
+ @internal_namespace_count += 1
112
101
  end
113
102
 
114
103
  [path, identifier]
@@ -127,9 +116,21 @@ module Savon
127
116
  @globals[:namespace] || @wsdl.namespace
128
117
 
129
118
  # check env_namespace
130
- namespaces["xmlns#{env_namespace && env_namespace != '' ? ":#{env_namespace}" : ''}"] =
119
+ namespaces["xmlns#{env_namespace && env_namespace != "" ? ":#{env_namespace}" : ''}"] =
131
120
  SOAP_NAMESPACE[@globals[:soap_version]]
132
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
+
133
134
  namespaces
134
135
  end
135
136
  end
@@ -144,9 +145,8 @@ module Savon
144
145
 
145
146
  def namespaced_message_tag
146
147
  tag_name = message_tag
147
- return [tag_name] if @wsdl.document? && @wsdl.soap_input(@operation_name.to_sym).is_a?(Hash)
148
-
149
- 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
150
150
  [tag_name, message_attributes]
151
151
  elsif @used_namespaces[[tag_name.to_s]]
152
152
  [@used_namespaces[[tag_name.to_s]], tag_name, message_attributes]
@@ -164,7 +164,6 @@ module Savon
164
164
  message_tag = serialized_message_tag[1]
165
165
  @wsdl.soap_input(@operation_name.to_sym)[message_tag].each_pair do |message, type|
166
166
  break if @locals[:message].nil?
167
-
168
167
  message_locals = @locals[:message][StringUtils.snakecase(message).to_sym]
169
168
  message_content = Message.new(message_tag, namespace_identifier, @types, @used_namespaces, message_locals, :unqualified, @globals[:convert_request_keys_to], @globals[:unwrap]).to_s
170
169
  messages += "<#{message} xsi:type=\"#{type.join(':')}\">#{message_content}</#{message}>"
@@ -178,7 +177,7 @@ module Savon
178
177
  message_tag = wsdl_tag_name.keys.first if wsdl_tag_name.is_a?(Hash)
179
178
  message_tag ||= @locals[:message_tag]
180
179
  message_tag ||= wsdl_tag_name
181
- message_tag ||= Gyoku.xml_tag(@operation_name, key_converter: @globals[:convert_request_keys_to])
180
+ message_tag ||= Gyoku.xml_tag(@operation_name, :key_converter => @globals[:convert_request_keys_to])
182
181
 
183
182
  message_tag.to_sym
184
183
  end
@@ -188,7 +187,7 @@ module Savon
188
187
  end
189
188
 
190
189
  def body_message
191
- if @wsdl.document? && @wsdl.soap_input(@operation_name.to_sym).is_a?(Hash)
190
+ if @wsdl.document? and @wsdl.soap_input(@operation_name.to_sym).is_a?(Hash)
192
191
  serialized_messages
193
192
  else
194
193
  message.to_s
@@ -222,7 +221,7 @@ module Savon
222
221
 
223
222
  def builder
224
223
  builder = ::Builder::XmlMarkup.new
225
- builder.instruct!(:xml, encoding: @globals[:encoding])
224
+ builder.instruct!(:xml, :encoding => @globals[:encoding])
226
225
  builder
227
226
  end
228
227
 
@@ -255,7 +254,7 @@ module Savon
255
254
 
256
255
  # the mail.body.encoded algorithm reorders the parts, default order is [ "text/plain", "text/enriched", "text/html" ]
257
256
  # should redefine the sort order, because the soap request xml should be the first
258
- multipart_message.body.set_sort_order ["text/xml"]
257
+ multipart_message.body.set_sort_order [ "text/xml" ]
259
258
 
260
259
  multipart_message.body.encoded(multipart_message.content_transfer_encoding)
261
260
  end
@@ -270,10 +269,10 @@ module Savon
270
269
  end
271
270
  multipart_message.add_part xml_part
272
271
 
273
- # request.headers["Content-Type"] = "multipart/related; boundary=\"#{multipart_message.body.boundary}\"; type=\"text/xml\"; start=\"#{xml_part.content_id}\""
272
+ #request.headers["Content-Type"] = "multipart/related; boundary=\"#{multipart_message.body.boundary}\"; type=\"text/xml\"; start=\"#{xml_part.content_id}\""
274
273
  @multipart = {
275
274
  multipart_boundary: multipart_message.body.boundary,
276
- start: xml_part.content_id
275
+ start: xml_part.content_id,
277
276
  }
278
277
 
279
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/transport/httpi"
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.is_a? Hash
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, build_transport)
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 = @globals[:wsdl] if @globals.include? :wsdl
90
- @wsdl.endpoint = @globals[:endpoint] if @globals.include? :endpoint
91
- @wsdl.namespace = @globals[:namespace] if @globals.include? :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
- if @globals[:transport] == :faraday
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
- "Some code tries to initialize Savon with the #{object.inspect} (#{object.class}) \n" \
108
- "Savon 2 expects a Hash of options for creating a new client and executing requests.\n" \
109
- "Please read the updated documentation for version 2: http://savonrb.com/version2.html"
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