savon 2.2.0 → 2.12.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 +7 -0
- data/.gitignore +2 -0
- data/.travis.yml +20 -9
- data/CHANGELOG.md +157 -10
- data/CONTRIBUTING.md +1 -1
- data/Gemfile +10 -2
- data/README.md +38 -13
- data/donate.png +0 -0
- data/lib/savon/builder.rb +81 -15
- data/lib/savon/client.rb +6 -2
- data/lib/savon/core_ext/string.rb +0 -1
- data/lib/savon/header.rb +68 -17
- data/lib/savon/log_message.rb +7 -3
- data/lib/savon/message.rb +6 -7
- data/lib/savon/mock/expectation.rb +12 -2
- data/lib/savon/model.rb +4 -0
- data/lib/savon/operation.rb +45 -38
- data/lib/savon/options.rb +149 -22
- data/lib/savon/qualified_message.rb +31 -25
- data/lib/savon/request.rb +24 -4
- data/lib/savon/request_logger.rb +48 -0
- data/lib/savon/response.rb +35 -18
- data/lib/savon/soap_fault.rb +11 -11
- data/lib/savon/version.rb +1 -3
- data/savon.gemspec +12 -11
- data/spec/fixtures/response/empty_soap_fault.xml +13 -0
- data/spec/fixtures/response/f5.xml +39 -0
- data/spec/fixtures/response/no_body.xml +1 -0
- data/spec/fixtures/response/soap_fault_funky.xml +8 -0
- data/spec/fixtures/wsdl/brand.xml +624 -0
- data/spec/fixtures/wsdl/elements_in_types.xml +43 -0
- data/spec/fixtures/wsdl/no_message_tag.xml +1267 -0
- data/spec/fixtures/wsdl/vies.xml +176 -0
- data/spec/integration/centra_spec.rb +67 -0
- data/spec/integration/email_example_spec.rb +1 -1
- data/spec/integration/random_quote_spec.rb +23 -0
- data/spec/integration/stockquote_example_spec.rb +7 -1
- data/spec/integration/support/application.rb +1 -1
- data/spec/integration/zipcode_example_spec.rb +1 -1
- data/spec/savon/builder_spec.rb +50 -0
- data/spec/savon/client_spec.rb +78 -0
- data/spec/savon/core_ext/string_spec.rb +9 -9
- data/spec/savon/features/message_tag_spec.rb +5 -0
- data/spec/savon/http_error_spec.rb +2 -2
- data/spec/savon/log_message_spec.rb +18 -1
- data/spec/savon/message_spec.rb +70 -0
- data/spec/savon/mock_spec.rb +31 -0
- data/spec/savon/model_spec.rb +28 -0
- data/spec/savon/operation_spec.rb +69 -3
- data/spec/savon/options_spec.rb +515 -87
- data/spec/savon/qualified_message_spec.rb +101 -0
- data/spec/savon/request_logger_spec.rb +37 -0
- data/spec/savon/request_spec.rb +85 -10
- data/spec/savon/response_spec.rb +118 -27
- data/spec/savon/soap_fault_spec.rb +25 -5
- data/spec/savon/softlayer_spec.rb +27 -0
- data/spec/spec_helper.rb +5 -2
- data/spec/support/adapters.rb +48 -0
- data/spec/support/integration.rb +1 -1
- metadata +76 -93
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?
|
@@ -41,6 +41,10 @@ module Savon
|
|
41
41
|
@wsdl.service_name
|
42
42
|
end
|
43
43
|
|
44
|
+
def build_request(operation_name, locals = {}, &block)
|
45
|
+
operation(operation_name).request(locals, &block)
|
46
|
+
end
|
47
|
+
|
44
48
|
private
|
45
49
|
|
46
50
|
def set_globals(globals, block)
|
@@ -56,7 +60,7 @@ module Savon
|
|
56
60
|
@wsdl.document = @globals[:wsdl] if @globals.include? :wsdl
|
57
61
|
@wsdl.endpoint = @globals[:endpoint] if @globals.include? :endpoint
|
58
62
|
@wsdl.namespace = @globals[:namespace] if @globals.include? :namespace
|
59
|
-
@wsdl.
|
63
|
+
@wsdl.adapter = @globals[:adapter] if @globals.include? :adapter
|
60
64
|
|
61
65
|
@wsdl.request = WSDLRequest.new(@globals).build
|
62
66
|
end
|
data/lib/savon/header.rb
CHANGED
@@ -1,41 +1,92 @@
|
|
1
1
|
require "akami"
|
2
2
|
require "gyoku"
|
3
|
+
require "securerandom"
|
3
4
|
|
4
5
|
module Savon
|
5
6
|
class Header
|
6
7
|
|
7
8
|
def initialize(globals, locals)
|
8
|
-
@
|
9
|
-
|
10
|
-
@
|
9
|
+
@gyoku_options = { :key_converter => globals[:convert_request_keys_to] }
|
10
|
+
|
11
|
+
@wsse_auth = locals[:wsse_auth].nil? ? globals[:wsse_auth] : locals[:wsse_auth]
|
12
|
+
@wsse_timestamp = locals[:wsse_timestamp].nil? ? globals[:wsse_timestamp] : locals[:wsse_timestamp]
|
13
|
+
@wsse_signature = locals[:wsse_signature].nil? ? globals[:wsse_signature] : locals[:wsse_signature]
|
14
|
+
|
15
|
+
@global_header = globals[:soap_header]
|
16
|
+
@local_header = locals[:soap_header]
|
17
|
+
|
18
|
+
@globals = globals
|
19
|
+
@locals = locals
|
20
|
+
|
21
|
+
@header = build
|
11
22
|
end
|
12
23
|
|
24
|
+
attr_reader :local_header, :global_header, :gyoku_options,
|
25
|
+
:wsse_auth, :wsse_timestamp, :wsse_signature
|
26
|
+
|
13
27
|
def empty?
|
14
|
-
|
28
|
+
@header.empty?
|
15
29
|
end
|
16
30
|
|
17
31
|
def to_s
|
18
|
-
|
19
|
-
|
20
|
-
gyoku_options = { :key_converter => @globals[:convert_request_keys_to] }
|
21
|
-
@header = (Hash === header ? Gyoku.xml(header, gyoku_options) : header) + wsse_header
|
32
|
+
@header
|
22
33
|
end
|
23
34
|
|
24
35
|
private
|
25
36
|
|
26
|
-
def
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
37
|
+
def build
|
38
|
+
build_header + build_wsa_header + build_wsse_header
|
39
|
+
end
|
40
|
+
|
41
|
+
def build_header
|
42
|
+
header =
|
43
|
+
if global_header.kind_of?(Hash) && local_header.kind_of?(Hash)
|
44
|
+
global_header.merge(local_header)
|
45
|
+
elsif local_header
|
46
|
+
local_header
|
47
|
+
else
|
48
|
+
global_header
|
49
|
+
end
|
50
|
+
|
51
|
+
convert_to_xml(header)
|
31
52
|
end
|
32
53
|
|
33
|
-
def
|
34
|
-
|
54
|
+
def build_wsse_header
|
55
|
+
wsse_header = akami
|
56
|
+
wsse_header.respond_to?(:to_xml) ? wsse_header.to_xml : ""
|
35
57
|
end
|
36
58
|
|
37
|
-
def
|
38
|
-
|
59
|
+
def build_wsa_header
|
60
|
+
return '' unless @globals[:use_wsa_headers]
|
61
|
+
convert_to_xml({
|
62
|
+
'wsa:Action' => @locals[:soap_action],
|
63
|
+
'wsa:To' => @globals[:endpoint],
|
64
|
+
'wsa:MessageID' => "urn:uuid:#{SecureRandom.uuid}",
|
65
|
+
attributes!: {
|
66
|
+
'wsa:MessageID' => {
|
67
|
+
"xmlns:wsa" => "http://schemas.xmlsoap.org/ws/2004/08/addressing"
|
68
|
+
}
|
69
|
+
}
|
70
|
+
})
|
71
|
+
end
|
72
|
+
|
73
|
+
def convert_to_xml(hash_or_string)
|
74
|
+
if hash_or_string.kind_of? Hash
|
75
|
+
Gyoku.xml(hash_or_string, gyoku_options)
|
76
|
+
else
|
77
|
+
hash_or_string.to_s
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
def akami
|
82
|
+
wsse = Akami.wsse
|
83
|
+
wsse.credentials(*wsse_auth) if wsse_auth
|
84
|
+
wsse.timestamp = wsse_timestamp if wsse_timestamp
|
85
|
+
if wsse_signature && wsse_signature.have_document?
|
86
|
+
wsse.signature = wsse_signature
|
87
|
+
end
|
88
|
+
|
89
|
+
wsse
|
39
90
|
end
|
40
91
|
|
41
92
|
end
|
data/lib/savon/log_message.rb
CHANGED
@@ -35,13 +35,17 @@ module Savon
|
|
35
35
|
end
|
36
36
|
|
37
37
|
def apply_filter!(document, filter)
|
38
|
-
|
39
|
-
|
38
|
+
if filter.instance_of? Proc
|
39
|
+
filter.call document
|
40
|
+
else
|
41
|
+
document.xpath("//*[local-name()='#{filter}']").each do |node|
|
42
|
+
node.content = "***FILTERED***"
|
43
|
+
end
|
40
44
|
end
|
41
45
|
end
|
42
46
|
|
43
47
|
def nokogiri_options
|
44
|
-
@pretty_print ? { :indent => 2 } : {}
|
48
|
+
@pretty_print ? { :indent => 2 } : { :save_with => Nokogiri::XML::Node::SaveOptions::AS_XML }
|
45
49
|
end
|
46
50
|
|
47
51
|
end
|
data/lib/savon/message.rb
CHANGED
@@ -4,8 +4,8 @@ require "gyoku"
|
|
4
4
|
module Savon
|
5
5
|
class Message
|
6
6
|
|
7
|
-
def initialize(
|
8
|
-
@
|
7
|
+
def initialize(message_tag, namespace_identifier, types, used_namespaces, message, element_form_default, key_converter, unwrap)
|
8
|
+
@message_tag = message_tag
|
9
9
|
@namespace_identifier = namespace_identifier
|
10
10
|
@types = types
|
11
11
|
@used_namespaces = used_namespaces
|
@@ -13,22 +13,21 @@ module Savon
|
|
13
13
|
@message = message
|
14
14
|
@element_form_default = element_form_default
|
15
15
|
@key_converter = key_converter
|
16
|
+
@unwrap = unwrap
|
16
17
|
end
|
17
18
|
|
18
19
|
def to_s
|
19
20
|
return @message.to_s unless @message.kind_of? Hash
|
20
21
|
|
21
22
|
if @element_form_default == :qualified
|
22
|
-
|
23
|
-
# XXX: there is no `@request_key_converter` instance variable!
|
24
|
-
# the third argument is therefore always `nil`. [dh, 2013-03-09]
|
25
|
-
@message = QualifiedMessage.new(@types, @used_namespaces, @request_key_converter).to_hash(@message, [translated_operation_name])
|
23
|
+
@message = QualifiedMessage.new(@types, @used_namespaces, @key_converter).to_hash(@message, [@message_tag.to_s])
|
26
24
|
end
|
27
25
|
|
28
26
|
gyoku_options = {
|
29
27
|
:element_form_default => @element_form_default,
|
30
28
|
:namespace => @namespace_identifier,
|
31
|
-
:key_converter => @key_converter
|
29
|
+
:key_converter => @key_converter,
|
30
|
+
:unwrap => @unwrap
|
32
31
|
}
|
33
32
|
|
34
33
|
Gyoku.xml(@message, gyoku_options)
|
@@ -54,7 +54,8 @@ module Savon
|
|
54
54
|
end
|
55
55
|
|
56
56
|
def verify_message!
|
57
|
-
|
57
|
+
return if @expected[:message].eql? :any
|
58
|
+
unless equals_except_any(@expected[:message], @actual[:message])
|
58
59
|
expected_message = " with this message: #{@expected[:message].inspect}" if @expected[:message]
|
59
60
|
expected_message ||= " with no message."
|
60
61
|
|
@@ -62,9 +63,18 @@ module Savon
|
|
62
63
|
actual_message ||= " with no message."
|
63
64
|
|
64
65
|
raise ExpectationError, "Expected a request to the #{@expected[:operation_name].inspect} operation\n#{expected_message}\n" \
|
65
|
-
|
66
|
+
"Received a request to the #{@actual[:operation_name].inspect} operation\n#{actual_message}"
|
66
67
|
end
|
67
68
|
end
|
68
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
|
69
79
|
end
|
70
80
|
end
|
data/lib/savon/model.rb
CHANGED
data/lib/savon/operation.rb
CHANGED
@@ -3,7 +3,8 @@ require "savon/block_interface"
|
|
3
3
|
require "savon/request"
|
4
4
|
require "savon/builder"
|
5
5
|
require "savon/response"
|
6
|
-
require "savon/
|
6
|
+
require "savon/request_logger"
|
7
|
+
require "savon/http_error"
|
7
8
|
|
8
9
|
module Savon
|
9
10
|
class Operation
|
@@ -22,6 +23,8 @@ module Savon
|
|
22
23
|
raise UnknownOperationError, "Unable to find SOAP operation: #{operation_name.inspect}\n" \
|
23
24
|
"Operations provided by your service: #{wsdl.soap_actions.inspect}"
|
24
25
|
end
|
26
|
+
rescue Wasabi::Resolver::HTTPError => e
|
27
|
+
raise HTTPError.new(e.response)
|
25
28
|
end
|
26
29
|
|
27
30
|
def self.ensure_name_is_symbol!(operation_name)
|
@@ -35,6 +38,8 @@ module Savon
|
|
35
38
|
@name = name
|
36
39
|
@wsdl = wsdl
|
37
40
|
@globals = globals
|
41
|
+
|
42
|
+
@logger = RequestLogger.new(globals)
|
38
43
|
end
|
39
44
|
|
40
45
|
def build(locals = {}, &block)
|
@@ -46,15 +51,38 @@ module Savon
|
|
46
51
|
builder = build(locals, &block)
|
47
52
|
|
48
53
|
response = Savon.notify_observers(@name, builder, @globals, @locals)
|
49
|
-
response ||=
|
54
|
+
response ||= call_with_logging build_request(builder)
|
50
55
|
|
51
56
|
raise_expected_httpi_response! unless response.kind_of?(HTTPI::Response)
|
52
57
|
|
53
|
-
|
58
|
+
create_response(response)
|
59
|
+
end
|
60
|
+
|
61
|
+
def request(locals = {}, &block)
|
62
|
+
builder = build(locals, &block)
|
63
|
+
build_request(builder)
|
54
64
|
end
|
55
65
|
|
56
66
|
private
|
57
67
|
|
68
|
+
def create_response(response)
|
69
|
+
if multipart_supported?
|
70
|
+
Multipart::Response.new(response, @globals, @locals)
|
71
|
+
else
|
72
|
+
Response.new(response, @globals, @locals)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def multipart_supported?
|
77
|
+
return false unless @globals[:multipart] || @locals[:multipart]
|
78
|
+
|
79
|
+
if Savon.const_defined? :Multipart
|
80
|
+
true
|
81
|
+
else
|
82
|
+
raise 'Unable to find Savon::Multipart. Make sure the savon-multipart gem is installed and loaded.'
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
58
86
|
def set_locals(locals, block)
|
59
87
|
locals = LocalOptions.new(locals)
|
60
88
|
BlockInterface.new(locals).evaluate(block) if block
|
@@ -62,18 +90,18 @@ module Savon
|
|
62
90
|
@locals = locals
|
63
91
|
end
|
64
92
|
|
65
|
-
def
|
66
|
-
|
67
|
-
response = HTTPI.post(request)
|
68
|
-
log_response(response) if log?
|
69
|
-
|
70
|
-
response
|
93
|
+
def call_with_logging(request)
|
94
|
+
@logger.log(request) { HTTPI.post(request, @globals[:adapter]) }
|
71
95
|
end
|
72
96
|
|
73
97
|
def build_request(builder)
|
98
|
+
@locals[:soap_action] ||= soap_action
|
99
|
+
@globals[:endpoint] ||= endpoint
|
100
|
+
|
74
101
|
request = SOAPRequest.new(@globals).build(
|
75
102
|
:soap_action => soap_action,
|
76
|
-
:cookies => @locals[:cookies]
|
103
|
+
:cookies => @locals[:cookies],
|
104
|
+
:headers => @locals[:headers]
|
77
105
|
)
|
78
106
|
|
79
107
|
request.url = endpoint
|
@@ -99,34 +127,13 @@ module Savon
|
|
99
127
|
end
|
100
128
|
|
101
129
|
def endpoint
|
102
|
-
@globals[:endpoint] || @wsdl.endpoint
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
end
|
110
|
-
|
111
|
-
def log_response(response)
|
112
|
-
logger.info "SOAP response (status #{response.code})"
|
113
|
-
logger.debug body_to_log(response.body)
|
114
|
-
end
|
115
|
-
|
116
|
-
def headers_to_log(headers)
|
117
|
-
headers.map { |key, value| "#{key}: #{value}" }.join(", ")
|
118
|
-
end
|
119
|
-
|
120
|
-
def body_to_log(body)
|
121
|
-
LogMessage.new(body, @globals[:filters], @globals[:pretty_print_xml]).to_s
|
122
|
-
end
|
123
|
-
|
124
|
-
def logger
|
125
|
-
@globals[:logger]
|
126
|
-
end
|
127
|
-
|
128
|
-
def log?
|
129
|
-
@globals[:log]
|
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
@@ -35,25 +35,63 @@ module Savon
|
|
35
35
|
def method_missing(option, _)
|
36
36
|
raise UnknownOptionError, "Unknown #{option_type} option: #{option.inspect}"
|
37
37
|
end
|
38
|
+
end
|
39
|
+
|
40
|
+
module SharedOptions
|
41
|
+
# WSSE auth credentials for Akami.
|
42
|
+
# Local will override the global wsse_auth value, e.g.
|
43
|
+
# global == [user, pass] && local == [user2, pass2] => [user2, pass2]
|
44
|
+
# global == [user, pass] && local == false => false
|
45
|
+
# global == [user, pass] && local == nil => [user, pass]
|
46
|
+
def wsse_auth(*credentials)
|
47
|
+
credentials.flatten!
|
48
|
+
if credentials.size == 1
|
49
|
+
@options[:wsse_auth] = credentials.first
|
50
|
+
else
|
51
|
+
@options[:wsse_auth] = credentials
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
# Instruct Akami to enable wsu:Timestamp headers.
|
56
|
+
# Local will override the global wsse_timestamp value, e.g.
|
57
|
+
# global == true && local == true => true
|
58
|
+
# global == true && local == false => false
|
59
|
+
# global == true && local == nil => true
|
60
|
+
def wsse_timestamp(timestamp = true)
|
61
|
+
@options[:wsse_timestamp] = timestamp
|
62
|
+
end
|
38
63
|
|
64
|
+
def wsse_signature(signature)
|
65
|
+
@options[:wsse_signature] = signature
|
66
|
+
end
|
39
67
|
end
|
40
68
|
|
41
69
|
class GlobalOptions < Options
|
70
|
+
include SharedOptions
|
42
71
|
|
43
72
|
def initialize(options = {})
|
44
73
|
@option_type = :global
|
45
74
|
|
46
75
|
defaults = {
|
47
|
-
:encoding
|
48
|
-
:soap_version
|
49
|
-
:namespaces
|
50
|
-
:logger
|
51
|
-
:log
|
52
|
-
:filters
|
53
|
-
:pretty_print_xml
|
54
|
-
:raise_errors
|
55
|
-
:strip_namespaces
|
56
|
-
:
|
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
|
57
95
|
}
|
58
96
|
|
59
97
|
options = defaults.merge(options)
|
@@ -72,6 +110,11 @@ module Savon
|
|
72
110
|
@options[:wsdl] = wsdl_address
|
73
111
|
end
|
74
112
|
|
113
|
+
# set different host for actions in WSDL
|
114
|
+
def host(host)
|
115
|
+
@options[:host] = host
|
116
|
+
end
|
117
|
+
|
75
118
|
# SOAP endpoint.
|
76
119
|
def endpoint(endpoint)
|
77
120
|
@options[:endpoint] = endpoint
|
@@ -94,7 +137,7 @@ module Savon
|
|
94
137
|
|
95
138
|
# Proxy server to use for all requests.
|
96
139
|
def proxy(proxy)
|
97
|
-
@options[:proxy] = proxy
|
140
|
+
@options[:proxy] = proxy unless proxy.nil?
|
98
141
|
end
|
99
142
|
|
100
143
|
# A Hash of HTTP headers.
|
@@ -117,12 +160,12 @@ module Savon
|
|
117
160
|
@options[:encoding] = encoding
|
118
161
|
end
|
119
162
|
|
120
|
-
# The global SOAP header. Expected to be a Hash.
|
163
|
+
# The global SOAP header. Expected to be a Hash or responding to #to_s.
|
121
164
|
def soap_header(header)
|
122
165
|
@options[:soap_header] = header
|
123
166
|
end
|
124
167
|
|
125
|
-
# Sets whether elements should be :qualified or unqualified.
|
168
|
+
# Sets whether elements should be :qualified or :unqualified.
|
126
169
|
# If you need to use this option, please open an issue and make
|
127
170
|
# sure to add your WSDL document for debugging.
|
128
171
|
def element_form_default(element_form_default)
|
@@ -154,6 +197,7 @@ module Savon
|
|
154
197
|
|
155
198
|
# The logger to use. Defaults to a Savon::Logger instance.
|
156
199
|
def logger(logger)
|
200
|
+
HTTPI.logger = logger
|
157
201
|
@options[:logger] = logger
|
158
202
|
end
|
159
203
|
|
@@ -194,6 +238,11 @@ module Savon
|
|
194
238
|
@options[:ssl_cert_key_file] = file
|
195
239
|
end
|
196
240
|
|
241
|
+
# Sets the cert key to use.
|
242
|
+
def ssl_cert_key(key)
|
243
|
+
@options[:ssl_cert_key] = key
|
244
|
+
end
|
245
|
+
|
197
246
|
# Sets the cert key password to use.
|
198
247
|
def ssl_cert_key_password(password)
|
199
248
|
@options[:ssl_cert_key_password] = password
|
@@ -204,11 +253,35 @@ module Savon
|
|
204
253
|
@options[:ssl_cert_file] = file
|
205
254
|
end
|
206
255
|
|
256
|
+
# Sets the cert to use.
|
257
|
+
def ssl_cert(cert)
|
258
|
+
@options[:ssl_cert] = cert
|
259
|
+
end
|
260
|
+
|
207
261
|
# Sets the ca cert file to use.
|
208
262
|
def ssl_ca_cert_file(file)
|
209
263
|
@options[:ssl_ca_cert_file] = file
|
210
264
|
end
|
211
265
|
|
266
|
+
# Sets the ca cert to use.
|
267
|
+
def ssl_ca_cert(cert)
|
268
|
+
@options[:ssl_ca_cert] = cert
|
269
|
+
end
|
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
|
284
|
+
|
212
285
|
# HTTP basic auth credentials.
|
213
286
|
def basic_auth(*credentials)
|
214
287
|
@options[:basic_auth] = credentials.flatten
|
@@ -219,14 +292,9 @@ module Savon
|
|
219
292
|
@options[:digest_auth] = credentials.flatten
|
220
293
|
end
|
221
294
|
|
222
|
-
#
|
223
|
-
def
|
224
|
-
@options[:
|
225
|
-
end
|
226
|
-
|
227
|
-
# Instruct Akami to enable wsu:Timestamp headers.
|
228
|
-
def wsse_timestamp(*timestamp)
|
229
|
-
@options[:wsse_timestamp] = timestamp.flatten
|
295
|
+
# NTLM auth credentials.
|
296
|
+
def ntlm(*credentials)
|
297
|
+
@options[:ntlm] = credentials.flatten
|
230
298
|
end
|
231
299
|
|
232
300
|
# Instruct Nori whether to strip namespaces from XML nodes.
|
@@ -234,33 +302,84 @@ module Savon
|
|
234
302
|
@options[:strip_namespaces] = strip_namespaces
|
235
303
|
end
|
236
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
|
+
|
237
310
|
# Tell Gyoku how to convert Hash key Symbols to XML tags.
|
238
311
|
# Accepts one of :lower_camelcase, :camelcase, :upcase, or :none.
|
239
312
|
def convert_request_keys_to(converter)
|
240
313
|
@options[:convert_request_keys_to] = converter
|
241
314
|
end
|
242
315
|
|
316
|
+
# Tell Gyoku to unwrap Array of Hashes
|
317
|
+
# Accepts a boolean, default to false
|
318
|
+
def unwrap(unwrap)
|
319
|
+
@options[:unwrap] = unwrap
|
320
|
+
end
|
321
|
+
|
243
322
|
# Tell Nori how to convert XML tags from the SOAP response into Hash keys.
|
244
323
|
# Accepts a lambda or a block which receives an XML tag and returns a Hash key.
|
245
324
|
# Defaults to convert tags to snakecase Symbols.
|
246
325
|
def convert_response_tags_to(converter = nil, &block)
|
247
326
|
@options[:convert_response_tags_to] = block || converter
|
248
327
|
end
|
328
|
+
|
329
|
+
# Tell Nori how to convert XML attributes on tags from the SOAP response into Hash keys.
|
330
|
+
# Accepts a lambda or a block which receives an XML tag and returns a Hash key.
|
331
|
+
# Defaults to doing nothing
|
332
|
+
def convert_attributes_to(converter = nil, &block)
|
333
|
+
@options[:convert_attributes_to] = block || converter
|
334
|
+
end
|
335
|
+
|
336
|
+
# Instruct Savon to create a multipart response if available.
|
337
|
+
def multipart(multipart)
|
338
|
+
@options[:multipart] = multipart
|
339
|
+
end
|
340
|
+
|
341
|
+
# Instruct Savon what HTTPI adapter it should use instead of default
|
342
|
+
def adapter(adapter)
|
343
|
+
@options[:adapter] = adapter
|
344
|
+
end
|
345
|
+
|
346
|
+
# Enable inclusion of WS-Addressing headers.
|
347
|
+
def use_wsa_headers(use)
|
348
|
+
@options[:use_wsa_headers] = use
|
349
|
+
end
|
350
|
+
|
351
|
+
def no_message_tag(bool)
|
352
|
+
@options[:no_message_tag] = bool
|
353
|
+
end
|
354
|
+
|
355
|
+
# Instruct requests to follow HTTP redirects.
|
356
|
+
def follow_redirects(follow_redirects)
|
357
|
+
@options[:follow_redirects] = follow_redirects
|
358
|
+
end
|
249
359
|
end
|
250
360
|
|
251
361
|
class LocalOptions < Options
|
362
|
+
include SharedOptions
|
252
363
|
|
253
364
|
def initialize(options = {})
|
254
365
|
@option_type = :local
|
255
366
|
|
256
367
|
defaults = {
|
257
368
|
:advanced_typecasting => true,
|
258
|
-
:response_parser => :nokogiri
|
369
|
+
:response_parser => :nokogiri,
|
370
|
+
:multipart => false
|
259
371
|
}
|
260
372
|
|
261
373
|
super defaults.merge(options)
|
262
374
|
end
|
263
375
|
|
376
|
+
# The local SOAP header. Expected to be a Hash or respond to #to_s.
|
377
|
+
# Will be merged with the global SOAP header if both are Hashes.
|
378
|
+
# Otherwise the local option will be prefered.
|
379
|
+
def soap_header(header)
|
380
|
+
@options[:soap_header] = header
|
381
|
+
end
|
382
|
+
|
264
383
|
# The SOAP message to send. Expected to be a Hash or a String.
|
265
384
|
def message(message)
|
266
385
|
@options[:message] = message
|
@@ -302,5 +421,13 @@ module Savon
|
|
302
421
|
@options[:response_parser] = parser
|
303
422
|
end
|
304
423
|
|
424
|
+
# Instruct Savon to create a multipart response if available.
|
425
|
+
def multipart(multipart)
|
426
|
+
@options[:multipart] = multipart
|
427
|
+
end
|
428
|
+
|
429
|
+
def headers(headers)
|
430
|
+
@options[:headers] = headers
|
431
|
+
end
|
305
432
|
end
|
306
433
|
end
|