savon 2.11.0 → 2.11.2

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
2
  SHA1:
3
- metadata.gz: 0909b11e5dac2bc60b3e2e15f8bf614dff389309
4
- data.tar.gz: bbf115546c00147d8703abada768abd1fa5b1abe
3
+ metadata.gz: ee16983ffafe63866c9a55e2f87082982882442b
4
+ data.tar.gz: 031a0b620818fa9242fa6df79d716dc2d5fb0795
5
5
  SHA512:
6
- metadata.gz: ae80080f90960964cf8f71f017193bf454fa5027f6607076942c9144c2cc2bfd1d7ea4d8afcc3013e1fc4a1170588b8693a654f6c0a8d714c61777aa5b48fe37
7
- data.tar.gz: f05c5afce92f799b1cf96c019f51e7cb224f6364e4c82677cfdffd9b1a49de149879c0099b0f535b50257fd8e83b188e62e36e9bb6bfb7bf3a6f45aa8236ad7d
6
+ metadata.gz: 32d112e59f45ec6b6f1c65f54c33030c99ae2e2c931ce476d0c62cceb7715d62772164b0f7e182ab691a8b47d8cfeb7c83140986743f3e134e91040d099905a6
7
+ data.tar.gz: 0d73626cde6c3ccec91b090f0d30cb1f6031b5fdc88834e1874719f0e269ae62c5a4e9402e863a45e7fb64c176b58f6ff8bb5296a2e13d1ddd28bb1133c9af0d
data/.travis.yml CHANGED
@@ -1,10 +1,19 @@
1
1
  # https://github.com/travis-ci/travis-ci/wiki/.travis.yml-options
2
2
  language: "ruby"
3
+ sudo: false
4
+ before_install:
5
+ - gem install bundler
3
6
  script: "bundle exec rake --trace"
4
7
  rvm:
5
- - 2.0
6
- - 2.1
7
- - 2.2
8
+ - 2.0.0
9
+ - 2.1.8
10
+ - 2.2.4
11
+ - 2.3.0
8
12
  - jruby
13
+ - rbx-2
14
+ matrix:
15
+ allow_failures:
16
+ - rvm: rbx-2
17
+ fast_finish: true
9
18
  notifications:
10
19
  irc: "irc.freenode.org#savon"
data/CHANGELOG.md CHANGED
@@ -1,3 +1,16 @@
1
+ # 2.11.2 (2017-08-03)
2
+ * Fix: [#676](https://github.com/savonrb/savon/pull/676) Fixes handling of `content!` and `attributes!`
3
+ * Fix: [#800](https://github.com/savonrb/savon/pull/800) Fix exception calling `SOAPFault#to_s` when http.body is empty
4
+ * Fix: [#757](https://github.com/savonrb/savon/pull/757) Logging: Use filter without automatic pretty printing
5
+ * Fix: [#771](https://github.com/savonrb/savon/pull/771) Restore support for cookies when using custom headers
6
+ * Feature: [#744](https://github.com/savonrb/savon/pull/744) Add support for rpc encoded wsdl
7
+ * Feature: [#742](https://github.com/savonrb/savon/pull/742) Add support for local request headers
8
+ * Feature: [#704](https://github.com/savonrb/savon/pull/704) Add possibility to pass attribute delete_namespace_attributes to Nori
9
+
10
+ # 2.11.1 (2015-05-27)
11
+
12
+ * Replace dependency on [uuid](https://rubygems.org/gems/uuid), using SecureRandom.uuid instead.
13
+
1
14
  # 2.11.0 (2015-03-31)
2
15
 
3
16
  * Formally drop support for 1.8.7.
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=master)](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.10.0'
25
+ gem 'savon', '~> 2.11.1'
26
26
  ```
27
27
 
28
28
  ## Usage example
data/lib/savon/builder.rb CHANGED
@@ -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]
data/lib/savon/client.rb CHANGED
@@ -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
data/lib/savon/header.rb CHANGED
@@ -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!
data/lib/savon/options.rb CHANGED
@@ -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
@@ -282,6 +289,11 @@ module Savon
282
289
  @options[:strip_namespaces] = strip_namespaces
283
290
  end
284
291
 
292
+ # Instruct Nori whether to delete namespace attributes from XML nodes.
293
+ def delete_namespace_attributes(delete_namespace_attributes)
294
+ @options[:delete_namespace_attributes] = delete_namespace_attributes
295
+ end
296
+
285
297
  # Tell Gyoku how to convert Hash key Symbols to XML tags.
286
298
  # Accepts one of :lower_camelcase, :camelcase, :upcase, or :none.
287
299
  def convert_request_keys_to(converter)
@@ -400,5 +412,9 @@ module Savon
400
412
  def multipart(multipart)
401
413
  @options[:multipart] = multipart
402
414
  end
415
+
416
+ def headers(headers)
417
+ @options[:headers] = headers
418
+ end
403
419
  end
404
420
  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
- 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)
12
+ return unless hash
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, 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
data/lib/savon/request.rb CHANGED
@@ -72,9 +72,9 @@ module Savon
72
72
 
73
73
  def build(options = {})
74
74
  configure_proxy
75
- configure_cookies options[:cookies]
76
75
  configure_timeouts
77
- configure_headers options[:soap_action]
76
+ configure_headers options[:soap_action], options[:headers]
77
+ configure_cookies options[:cookies]
78
78
  configure_ssl
79
79
  configure_auth
80
80
  configure_redirect_handling
@@ -88,8 +88,9 @@ module Savon
88
88
  @http_request.set_cookies(cookies) if cookies
89
89
  end
90
90
 
91
- def configure_headers(soap_action)
91
+ def configure_headers(soap_action, headers)
92
92
  @http_request.headers = @globals[:headers] if @globals.include? :headers
93
+ @http_request.headers.merge!(headers) if headers
93
94
  @http_request.headers["SOAPAction"] ||= %{"#{soap_action}"} if soap_action
94
95
  @http_request.headers["Content-Type"] ||= CONTENT_TYPE[@globals[:soap_version]] % @globals[:encoding]
95
96
  end
@@ -98,11 +98,12 @@ module Savon
98
98
  return @nori if @nori
99
99
 
100
100
  nori_options = {
101
- :strip_namespaces => @globals[:strip_namespaces],
102
- :convert_tags_to => @globals[:convert_response_tags_to],
103
- :convert_attributes_to => @globals[:convert_attributes_to],
104
- :advanced_typecasting => @locals[:advanced_typecasting],
105
- :parser => @locals[:response_parser]
101
+ :delete_namespace_attributes => @globals[:delete_namespace_attributes],
102
+ :strip_namespaces => @globals[:strip_namespaces],
103
+ :convert_tags_to => @globals[:convert_response_tags_to],
104
+ :convert_attributes_to => @globals[:convert_attributes_to],
105
+ :advanced_typecasting => @locals[:advanced_typecasting],
106
+ :parser => @locals[:response_parser]
106
107
  }
107
108
 
108
109
  non_nil_nori_options = nori_options.reject { |_, value| value.nil? }
@@ -27,7 +27,7 @@ module Savon
27
27
 
28
28
  def to_hash
29
29
  parsed = nori.parse(xml || http.body)
30
- nori.find(parsed, 'Envelope', 'Body')
30
+ nori.find(parsed, 'Envelope', 'Body') || {}
31
31
  end
32
32
 
33
33
  private
data/lib/savon/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Savon
2
- VERSION = '2.11.0'
2
+ VERSION = '2.11.2'
3
3
  end
data/savon.gemspec CHANGED
@@ -22,7 +22,6 @@ Gem::Specification.new do |s|
22
22
  s.add_dependency "wasabi", "~> 3.4"
23
23
  s.add_dependency "akami", "~> 1.2"
24
24
  s.add_dependency "gyoku", "~> 1.2"
25
- s.add_dependency "uuid", "~> 2.3.7"
26
25
  s.add_dependency "builder", ">= 2.1.2"
27
26
  s.add_dependency "nokogiri", ">= 1.4.0"
28
27