savon 2.10.1 → 2.12.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 18f0b7e0ce70c3e4875a47aec303544e0bddd385
4
- data.tar.gz: baff63ce5ef87a00e0b3737c69a31f86fdfa1694
2
+ SHA256:
3
+ metadata.gz: adc5b65f9ac22024b164dae28b0198a4269b97ab14afac694b946e7cef896d7e
4
+ data.tar.gz: 13138a12de62757d551a9114b2741501accbbad169a2a00a9dee7f439ad48a78
5
5
  SHA512:
6
- metadata.gz: 45cdba7801e11d255ebf71aa73a7fc8f56249b9a4e58362957326b99e1fedc7b6ef53c1ed543228626d56316fedfc94c151e6596cd09b84d832ab0834f5500de
7
- data.tar.gz: 1f8fdf10425799438c3be1619311360406756ffad3aa22007196227050f766ad2b021abbbc6a457e845c5e05ef157ab89c623612639189ff11d5db3bc16f0073
6
+ metadata.gz: 11e3b779fc0376993c46d6ab595e96896a5b0a7ea6f478d3ce93918ebfbd93ff14c4c5ac44c0080ce527c4e30e8615d559b373900acf35b96d2d67b1661b0f28
7
+ data.tar.gz: 0a8b5bcacf019b33eaafee305aee4f33c1733c26455d446738c28ad14567d69288c0f1cc0226f2e9c5304687a5b49a7011397465c16350b03b31370626014292
@@ -1,10 +1,26 @@
1
1
  # https://github.com/travis-ci/travis-ci/wiki/.travis.yml-options
2
2
  language: "ruby"
3
+
3
4
  script: "bundle exec rake --trace"
5
+
4
6
  rvm:
5
- - 2.0
6
- - 2.1
7
- - 2.2
8
- - jruby
7
+ - "2.5"
8
+ - "2.6"
9
+ - "2.7"
10
+
11
+ matrix:
12
+ include:
13
+ - name: "JRuby 9.2"
14
+ rvm: jruby-9.2.12.0
15
+ jdk: openjdk11
16
+ env: JAVA_OPTS="--add-opens java.base/java.security.cert=ALL-UNNAMED --add-opens java.base/java.security=ALL-UNNAMED"
17
+ - name: Rubinius
18
+ rvm: rbx-4
19
+ dist: trusty
20
+ allow_failures:
21
+ - name: Rubinius
22
+ - name: "JRuby 9.2"
23
+ fast_finish: true
24
+
9
25
  notifications:
10
26
  irc: "irc.freenode.org#savon"
@@ -1,8 +1,41 @@
1
- * 2.10.1 (2015-03-15)
1
+
2
+ ## 2.12.1 (2020-07-05)
3
+
4
+ * Fix: [#917](https://github.com/savonrb/savon/pull/917) elementFormDefault="qualified" regression
5
+ * Fix: [#875](https://github.com/savonrb/savon/pull/875) Fix detecting Soap 1.1 Fault when faultcode and faultstring are empty
6
+
7
+ # 2.12.0 (2018-01-16)
8
+
9
+ * Drop support for ruby 2.1 and below.
10
+ * Fix: [#822](https://github.com/savonrb/savon/pull/822) Raise correct error when SOAP envelope only contains a string
11
+ * Fix: [#833](https://github.com/savonrb/savon/pull/833) Fixes boolean handling regression introduced in 2.11.2
12
+ * Feature: [#794](https://github.com/savonrb/savon/pull/794), add global option ssl_ciphers.
13
+ * Feature: [#753](https://github.com/savonrb/savon/pull/753) Add headers configuration to WSDLRequest#build
14
+ * Feature: [#812](https://github.com/savonrb/savon/pull/812) Allow `proxy` option to be `nil`.
15
+ * Feature: [#838](https://github.com/savonrb/savon/pull/838) Added ssl_ca_path and ssl_cert_store to globals
16
+
17
+ # 2.11.2 (2017-08-03)
18
+ * Fix: [#676](https://github.com/savonrb/savon/pull/676) Fixes handling of `content!` and `attributes!`
19
+ * Fix: [#800](https://github.com/savonrb/savon/pull/800) Fix exception calling `SOAPFault#to_s` when http.body is empty
20
+ * Fix: [#757](https://github.com/savonrb/savon/pull/757) Logging: Use filter without automatic pretty printing
21
+ * Fix: [#771](https://github.com/savonrb/savon/pull/771) Restore support for cookies when using custom headers
22
+ * Feature: [#744](https://github.com/savonrb/savon/pull/744) Add support for rpc encoded wsdl
23
+ * Feature: [#742](https://github.com/savonrb/savon/pull/742) Add support for local request headers
24
+ * Feature: [#704](https://github.com/savonrb/savon/pull/704) Add possibility to pass attribute delete_namespace_attributes to Nori
25
+
26
+ # 2.11.1 (2015-05-27)
27
+
28
+ * Replace dependency on [uuid](https://rubygems.org/gems/uuid), using SecureRandom.uuid instead.
29
+
30
+ # 2.11.0 (2015-03-31)
31
+
32
+ * Formally drop support for 1.8.7.
33
+
34
+ # 2.10.1 (2015-03-15)
2
35
 
3
36
  * Feature: [#673](https://github.com/savonrb/savon/pull/673) Adds an :unwrap option that is passed to Gyoku.
4
37
 
5
- * 2.10.0 (2015-03-02)
38
+ # 2.10.0 (2015-03-02)
6
39
 
7
40
  * Fix: This reverts a purported "fix" to operation names.
8
41
 
data/Gemfile CHANGED
@@ -1,19 +1,13 @@
1
1
  source 'https://rubygems.org'
2
2
  gemspec
3
3
 
4
- gem "httpclient", "~> 2.3.4"
4
+ gem "httpclient", "~> 2.7.1"
5
5
 
6
6
  gem "simplecov", :require => false
7
7
  gem "coveralls", :require => false
8
- gem "uuid"
9
8
 
10
9
  platform :rbx do
11
- gem 'json'
12
10
  gem 'racc'
13
11
  gem 'rubysl'
14
12
  gem 'rubinius-coverage'
15
13
  end
16
-
17
- platform :jruby do
18
- gem 'json'
19
- end
data/README.md CHANGED
@@ -5,10 +5,10 @@ Heavy metal SOAP client
5
5
  [Documentation](http://savonrb.com) | [RDoc](http://rubydoc.info/gems/savon) |
6
6
  [Mailing list](https://groups.google.com/forum/#!forum/savonrb) | [Twitter](http://twitter.com/savonrb)
7
7
 
8
- [![Build Status](https://secure.travis-ci.org/savonrb/savon.png?branch=version2)](http://travis-ci.org/savonrb/savon)
9
- [![Gem Version](https://badge.fury.io/rb/savon.png)](http://badge.fury.io/rb/savon)
10
- [![Code Climate](https://codeclimate.com/github/savonrb/savon.png)](https://codeclimate.com/github/savonrb/savon)
11
- [![Coverage Status](https://coveralls.io/repos/savonrb/savon/badge.png?branch=version2)](https://coveralls.io/r/savonrb/savon)
8
+ [![Build Status](https://secure.travis-ci.org/savonrb/savon.svg?branch=master)](http://travis-ci.org/savonrb/savon)
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)
11
+ [![Coverage Status](https://coveralls.io/repos/savonrb/savon/badge.svg?branch=version2)](https://coveralls.io/r/savonrb/savon)
12
12
 
13
13
 
14
14
  ## Version 2
@@ -22,7 +22,7 @@ $ gem install savon
22
22
  or add it to your Gemfile like this:
23
23
 
24
24
  ```
25
- gem 'savon', '~> 2.8.0'
25
+ gem 'savon', '~> 2.12.0'
26
26
  ```
27
27
 
28
28
  ## Usage example
@@ -46,6 +46,19 @@ response.body
46
46
  For more examples, you should check out the
47
47
  [integration tests](https://github.com/savonrb/savon/tree/version2/spec/integration).
48
48
 
49
+ ## Ruby version support
50
+ * 2.12.x - MRI 2.2, 2.3, 2.4
51
+ * 2.11.x - MRI 2.0, 2.1, 2.2, and 2.3
52
+
53
+ If you are running MRI 1.8.7, try the 2.6.x branch.
54
+
55
+ ## Running tests
56
+
57
+ ```bash
58
+ $ bundle install
59
+ $ bundle exec rspec
60
+ ```
61
+
49
62
  ## FAQ
50
63
 
51
64
  * 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`.
@@ -36,18 +36,18 @@ module Savon
36
36
  end
37
37
 
38
38
  def build_document
39
- xml = tag(builder, :Envelope, namespaces_with_globals) do |xml|
39
+ xml_result = tag(builder, :Envelope, namespaces_with_globals) do |xml|
40
40
  tag(xml, :Header, header_attributes) { xml << header.to_s } unless header.empty?
41
41
  if @globals[:no_message_tag]
42
42
  tag(xml, :Body, body_attributes) { xml << message.to_s }
43
43
  else
44
- tag(xml, :Body, body_attributes) { xml.tag!(*namespaced_message_tag) { xml << message.to_s } }
44
+ tag(xml, :Body, body_attributes) { xml.tag!(*namespaced_message_tag) { xml << body_message } }
45
45
  end
46
46
  end
47
47
 
48
48
  # if we have a signature sign the document
49
49
  if @signature
50
- @signature.document = xml
50
+ @signature.document = xml_result
51
51
 
52
52
  2.times do
53
53
  @header = nil
@@ -61,10 +61,10 @@ module Savon
61
61
  end
62
62
  end
63
63
 
64
- xml = @signature.document
64
+ xml_result = @signature.document
65
65
  end
66
66
 
67
- xml
67
+ xml_result
68
68
  end
69
69
 
70
70
  def header_attributes
@@ -141,6 +141,7 @@ module Savon
141
141
 
142
142
  def namespaced_message_tag
143
143
  tag_name = message_tag
144
+ return [tag_name] if @wsdl.document? and @wsdl.soap_input(@operation_name.to_sym).is_a?(Hash)
144
145
  if namespace_identifier == nil
145
146
  [tag_name, message_attributes]
146
147
  elsif @used_namespaces[[tag_name.to_s]]
@@ -150,8 +151,25 @@ module Savon
150
151
  end
151
152
  end
152
153
 
154
+ def serialized_message_tag
155
+ [:wsdl, @wsdl.soap_input(@operation_name.to_sym).keys.first, {}]
156
+ end
157
+
158
+ def serialized_messages
159
+ messages = ""
160
+ message_tag = serialized_message_tag[1]
161
+ @wsdl.soap_input(@operation_name.to_sym)[message_tag].each_pair do |message, type|
162
+ break if @locals[:message].nil?
163
+ message_locals = @locals[:message][message.snakecase.to_sym]
164
+ message_content = Message.new(message_tag, namespace_identifier, @types, @used_namespaces, message_locals, :unqualified, @globals[:convert_request_keys_to], @globals[:unwrap]).to_s
165
+ messages << "<#{message} xsi:type=\"#{type.join(':')}\">#{message_content}</#{message}>"
166
+ end
167
+ messages
168
+ end
169
+
153
170
  def message_tag
154
- message_tag = @locals[:message_tag]
171
+ message_tag = @wsdl.soap_input(@operation_name.to_sym).keys.first if @wsdl.document? and @wsdl.soap_input(@operation_name.to_sym).is_a?(Hash)
172
+ message_tag ||= @locals[:message_tag]
155
173
  message_tag ||= @wsdl.soap_input(@operation_name.to_sym) if @wsdl.document?
156
174
  message_tag ||= Gyoku.xml_tag(@operation_name, :key_converter => @globals[:convert_request_keys_to])
157
175
 
@@ -162,6 +180,14 @@ module Savon
162
180
  @locals[:attributes] || {}
163
181
  end
164
182
 
183
+ def body_message
184
+ if @wsdl.document? and @wsdl.soap_input(@operation_name.to_sym).is_a?(Hash)
185
+ serialized_messages
186
+ else
187
+ message.to_s
188
+ end
189
+ end
190
+
165
191
  def message
166
192
  element_form_default = @globals[:element_form_default] || @wsdl.element_form_default
167
193
  # TODO: clean this up! [dh, 2012-12-17]
@@ -21,7 +21,7 @@ module Savon
21
21
  build_wsdl_document
22
22
  end
23
23
 
24
- attr_reader :globals
24
+ attr_reader :globals, :wsdl
25
25
 
26
26
  def operations
27
27
  raise_missing_wsdl_error! unless @wsdl.document?
@@ -60,7 +60,6 @@ module Savon
60
60
  @wsdl.document = @globals[:wsdl] if @globals.include? :wsdl
61
61
  @wsdl.endpoint = @globals[:endpoint] if @globals.include? :endpoint
62
62
  @wsdl.namespace = @globals[:namespace] if @globals.include? :namespace
63
- @wsdl.servicename = @globals[:servicename] if @globals.include? :servicename
64
63
  @wsdl.adapter = @globals[:adapter] if @globals.include? :adapter
65
64
 
66
65
  @wsdl.request = WSDLRequest.new(@globals).build
@@ -1,6 +1,6 @@
1
1
  require "akami"
2
2
  require "gyoku"
3
- require "uuid"
3
+ require "securerandom"
4
4
 
5
5
  module Savon
6
6
  class Header
@@ -61,7 +61,7 @@ module Savon
61
61
  convert_to_xml({
62
62
  'wsa:Action' => @locals[:soap_action],
63
63
  'wsa:To' => @globals[:endpoint],
64
- 'wsa:MessageID' => "urn:uuid:#{UUID.new.generate}",
64
+ 'wsa:MessageID' => "urn:uuid:#{SecureRandom.uuid}",
65
65
  attributes!: {
66
66
  'wsa:MessageID' => {
67
67
  "xmlns:wsa" => "http://schemas.xmlsoap.org/ws/2004/08/addressing"
@@ -45,7 +45,7 @@ module Savon
45
45
  end
46
46
 
47
47
  def nokogiri_options
48
- @pretty_print ? { :indent => 2 } : {}
48
+ @pretty_print ? { :indent => 2 } : { :save_with => Nokogiri::XML::Node::SaveOptions::AS_XML }
49
49
  end
50
50
 
51
51
  end
@@ -55,7 +55,7 @@ module Savon
55
55
 
56
56
  def verify_message!
57
57
  return if @expected[:message].eql? :any
58
- unless @expected[:message] === @actual[:message]
58
+ unless equals_except_any(@expected[:message], @actual[:message])
59
59
  expected_message = " with this message: #{@expected[:message].inspect}" if @expected[:message]
60
60
  expected_message ||= " with no message."
61
61
 
@@ -63,9 +63,18 @@ module Savon
63
63
  actual_message ||= " with no message."
64
64
 
65
65
  raise ExpectationError, "Expected a request to the #{@expected[:operation_name].inspect} operation\n#{expected_message}\n" \
66
- "Received a request to the #{@actual[:operation_name].inspect} operation\n#{actual_message}"
66
+ "Received a request to the #{@actual[:operation_name].inspect} operation\n#{actual_message}"
67
67
  end
68
68
  end
69
69
 
70
+ def equals_except_any(msg_expected, msg_real)
71
+ return true if msg_expected === msg_real
72
+ return false if (msg_expected.nil? || msg_real.nil?) # If both are nil has returned true
73
+ msg_expected.each do |key, expected_value|
74
+ next if (expected_value == :any && msg_real.include?(key))
75
+ return false if expected_value != msg_real[key]
76
+ end
77
+ return true
78
+ end
70
79
  end
71
80
  end
@@ -100,7 +100,8 @@ module Savon
100
100
 
101
101
  request = SOAPRequest.new(@globals).build(
102
102
  :soap_action => soap_action,
103
- :cookies => @locals[:cookies]
103
+ :cookies => @locals[:cookies],
104
+ :headers => @locals[:headers]
104
105
  )
105
106
 
106
107
  request.url = endpoint
@@ -126,7 +127,13 @@ module Savon
126
127
  end
127
128
 
128
129
  def endpoint
129
- @globals[:endpoint] || @wsdl.endpoint
130
+ @globals[:endpoint] || @wsdl.endpoint.tap do |url|
131
+ if @globals[:host]
132
+ host_url = URI.parse(@globals[:host])
133
+ url.host = host_url.host
134
+ url.port = host_url.port
135
+ end
136
+ end
130
137
  end
131
138
 
132
139
  def raise_expected_httpi_response!
@@ -73,23 +73,25 @@ module Savon
73
73
  @option_type = :global
74
74
 
75
75
  defaults = {
76
- :encoding => "UTF-8",
77
- :soap_version => 1,
78
- :namespaces => {},
79
- :logger => Logger.new($stdout),
80
- :log => false,
81
- :filters => [],
82
- :pretty_print_xml => false,
83
- :raise_errors => true,
84
- :strip_namespaces => true,
85
- :convert_response_tags_to => lambda { |tag| tag.snakecase.to_sym},
86
- :convert_attributes_to => lambda { |k,v| [k,v] },
87
- :multipart => false,
88
- :adapter => nil,
89
- :use_wsa_headers => false,
90
- :no_message_tag => false,
91
- :follow_redirects => false,
92
- :unwrap => false
76
+ :encoding => "UTF-8",
77
+ :soap_version => 1,
78
+ :namespaces => {},
79
+ :logger => Logger.new($stdout),
80
+ :log => false,
81
+ :filters => [],
82
+ :pretty_print_xml => false,
83
+ :raise_errors => true,
84
+ :strip_namespaces => true,
85
+ :delete_namespace_attributes => false,
86
+ :convert_response_tags_to => lambda { |tag| tag.snakecase.to_sym},
87
+ :convert_attributes_to => lambda { |k,v| [k,v] },
88
+ :multipart => false,
89
+ :adapter => nil,
90
+ :use_wsa_headers => false,
91
+ :no_message_tag => false,
92
+ :follow_redirects => false,
93
+ :unwrap => false,
94
+ :host => nil
93
95
  }
94
96
 
95
97
  options = defaults.merge(options)
@@ -108,6 +110,11 @@ module Savon
108
110
  @options[:wsdl] = wsdl_address
109
111
  end
110
112
 
113
+ # set different host for actions in WSDL
114
+ def host(host)
115
+ @options[:host] = host
116
+ end
117
+
111
118
  # SOAP endpoint.
112
119
  def endpoint(endpoint)
113
120
  @options[:endpoint] = endpoint
@@ -130,7 +137,7 @@ module Savon
130
137
 
131
138
  # Proxy server to use for all requests.
132
139
  def proxy(proxy)
133
- @options[:proxy] = proxy
140
+ @options[:proxy] = proxy unless proxy.nil?
134
141
  end
135
142
 
136
143
  # A Hash of HTTP headers.
@@ -261,6 +268,19 @@ module Savon
261
268
  @options[:ssl_ca_cert] = cert
262
269
  end
263
270
 
271
+ def ssl_ciphers(ciphers)
272
+ @options[:ssl_ciphers] = ciphers
273
+ end
274
+
275
+ # Sets the ca cert path.
276
+ def ssl_ca_cert_path(path)
277
+ @options[:ssl_ca_cert_path] = path
278
+ end
279
+
280
+ # Sets the ssl cert store.
281
+ def ssl_cert_store(store)
282
+ @options[:ssl_cert_store] = store
283
+ end
264
284
 
265
285
  # HTTP basic auth credentials.
266
286
  def basic_auth(*credentials)
@@ -282,6 +302,11 @@ module Savon
282
302
  @options[:strip_namespaces] = strip_namespaces
283
303
  end
284
304
 
305
+ # Instruct Nori whether to delete namespace attributes from XML nodes.
306
+ def delete_namespace_attributes(delete_namespace_attributes)
307
+ @options[:delete_namespace_attributes] = delete_namespace_attributes
308
+ end
309
+
285
310
  # Tell Gyoku how to convert Hash key Symbols to XML tags.
286
311
  # Accepts one of :lower_camelcase, :camelcase, :upcase, or :none.
287
312
  def convert_request_keys_to(converter)
@@ -400,5 +425,9 @@ module Savon
400
425
  def multipart(multipart)
401
426
  @options[:multipart] = multipart
402
427
  end
428
+
429
+ def headers(headers)
430
+ @options[:headers] = headers
431
+ end
403
432
  end
404
433
  end
@@ -2,49 +2,50 @@ require "gyoku"
2
2
 
3
3
  module Savon
4
4
  class QualifiedMessage
5
-
6
5
  def initialize(types, used_namespaces, key_converter)
7
- @types = types
6
+ @types = types
8
7
  @used_namespaces = used_namespaces
9
- @key_converter = key_converter
8
+ @key_converter = key_converter
10
9
  end
11
10
 
12
11
  def to_hash(hash, path)
13
12
  return hash unless hash
14
- return hash.map { |value| to_hash(value, path) } if hash.kind_of?(Array)
15
- return hash.to_s unless hash.kind_of? Hash
16
-
17
- hash.inject({}) do |newhash, (key, value)|
18
- if key == :order!
19
- add_namespaces_to_values(value, path)
20
- newhash.merge(key => value)
13
+ return hash.map { |value| to_hash(value, path) } if hash.is_a?(Array)
14
+ return hash.to_s unless hash.is_a?(Hash)
15
+
16
+ hash.each_with_object({}) do |(key, value), newhash|
17
+ case key
18
+ when :order!
19
+ newhash[key] = add_namespaces_to_values(value, path)
20
+ when :attributes!, :content!
21
+ newhash[key] = to_hash(value, path)
21
22
  else
22
- translated_key = Gyoku.xml_tag(key, :key_converter => @key_converter).to_s
23
- translated_key << "!" if key[-1] == "!"
24
- newpath = path + [translated_key]
25
-
26
- if @used_namespaces[newpath]
27
- newhash.merge(
28
- "#{@used_namespaces[newpath]}:#{translated_key}" =>
29
- to_hash(value, @types[newpath] ? [@types[newpath]] : newpath)
30
- )
23
+ if key.to_s =~ /!$/
24
+ newhash[key] = value
31
25
  else
32
- newhash.merge(translated_key => value)
26
+ translated_key = translate_tag(key)
27
+ newkey = add_namespaces_to_values(key, path).first
28
+ newpath = path + [translated_key]
29
+ newhash[newkey] = to_hash(value, @types[newpath] ? [@types[newpath]] : newpath)
33
30
  end
34
31
  end
32
+ newhash
35
33
  end
36
34
  end
37
35
 
38
36
  private
39
37
 
40
- def add_namespaces_to_values(values, path)
41
- values.collect! { |value|
42
- camelcased_value = Gyoku.xml_tag(value, :key_converter => @key_converter)
43
- namespace_path = path + [camelcased_value.to_s]
44
- namespace = @used_namespaces[namespace_path]
45
- "#{namespace.blank? ? '' : namespace + ":"}#{camelcased_value}"
46
- }
38
+ def translate_tag(key)
39
+ Gyoku.xml_tag(key, :key_converter => @key_converter).to_s
47
40
  end
48
41
 
42
+ def add_namespaces_to_values(values, path)
43
+ Array(values).collect do |value|
44
+ translated_value = translate_tag(value)
45
+ namespace_path = path + [translated_value]
46
+ namespace = @used_namespaces[namespace_path]
47
+ namespace.blank? ? value : "#{namespace}:#{translated_value}"
48
+ end
49
+ end
49
50
  end
50
51
  end