savon-ng-1.6 2.4.0
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 +13 -0
- data/.travis.yml +15 -0
- data/.yardopts +6 -0
- data/CHANGELOG.md +1024 -0
- data/CONTRIBUTING.md +46 -0
- data/Gemfile +8 -0
- data/LICENSE +20 -0
- data/README.md +81 -0
- data/Rakefile +14 -0
- data/donate.png +0 -0
- data/lib/savon/block_interface.rb +26 -0
- data/lib/savon/builder.rb +166 -0
- data/lib/savon/client.rb +88 -0
- data/lib/savon/core_ext/string.rb +29 -0
- data/lib/savon/header.rb +70 -0
- data/lib/savon/http_error.rb +27 -0
- data/lib/savon/log_message.rb +48 -0
- data/lib/savon/message.rb +36 -0
- data/lib/savon/mock/expectation.rb +71 -0
- data/lib/savon/mock/spec_helper.rb +62 -0
- data/lib/savon/mock.rb +5 -0
- data/lib/savon/model.rb +80 -0
- data/lib/savon/operation.rb +127 -0
- data/lib/savon/options.rb +330 -0
- data/lib/savon/qualified_message.rb +49 -0
- data/lib/savon/request.rb +89 -0
- data/lib/savon/request_logger.rb +48 -0
- data/lib/savon/response.rb +112 -0
- data/lib/savon/soap_fault.rb +48 -0
- data/lib/savon/version.rb +5 -0
- data/lib/savon.rb +27 -0
- data/savon.gemspec +47 -0
- data/spec/fixtures/gzip/message.gz +0 -0
- data/spec/fixtures/response/another_soap_fault.xml +14 -0
- data/spec/fixtures/response/authentication.xml +14 -0
- data/spec/fixtures/response/header.xml +13 -0
- data/spec/fixtures/response/list.xml +18 -0
- data/spec/fixtures/response/multi_ref.xml +39 -0
- data/spec/fixtures/response/soap_fault.xml +8 -0
- data/spec/fixtures/response/soap_fault12.xml +18 -0
- data/spec/fixtures/response/taxcloud.xml +1 -0
- data/spec/fixtures/ssl/client_cert.pem +16 -0
- data/spec/fixtures/ssl/client_encrypted_key.pem +30 -0
- data/spec/fixtures/ssl/client_encrypted_key_cert.pem +24 -0
- data/spec/fixtures/ssl/client_key.pem +15 -0
- data/spec/fixtures/wsdl/authentication.xml +63 -0
- data/spec/fixtures/wsdl/betfair.xml +2981 -0
- data/spec/fixtures/wsdl/edialog.xml +15416 -0
- data/spec/fixtures/wsdl/interhome.xml +2137 -0
- data/spec/fixtures/wsdl/lower_camel.xml +52 -0
- data/spec/fixtures/wsdl/multiple_namespaces.xml +92 -0
- data/spec/fixtures/wsdl/multiple_types.xml +60 -0
- data/spec/fixtures/wsdl/taxcloud.xml +934 -0
- data/spec/fixtures/wsdl/team_software.xml +1 -0
- data/spec/fixtures/wsdl/vies.xml +176 -0
- data/spec/fixtures/wsdl/wasmuth.xml +153 -0
- data/spec/integration/email_example_spec.rb +32 -0
- data/spec/integration/ratp_example_spec.rb +28 -0
- data/spec/integration/stockquote_example_spec.rb +28 -0
- data/spec/integration/support/application.rb +82 -0
- data/spec/integration/support/server.rb +84 -0
- data/spec/integration/temperature_example_spec.rb +46 -0
- data/spec/integration/zipcode_example_spec.rb +42 -0
- data/spec/savon/builder_spec.rb +86 -0
- data/spec/savon/client_spec.rb +193 -0
- data/spec/savon/core_ext/string_spec.rb +37 -0
- data/spec/savon/features/message_tag_spec.rb +61 -0
- data/spec/savon/http_error_spec.rb +49 -0
- data/spec/savon/log_message_spec.rb +33 -0
- data/spec/savon/message_spec.rb +40 -0
- data/spec/savon/mock_spec.rb +157 -0
- data/spec/savon/model_spec.rb +154 -0
- data/spec/savon/observers_spec.rb +92 -0
- data/spec/savon/operation_spec.rb +211 -0
- data/spec/savon/options_spec.rb +772 -0
- data/spec/savon/request_spec.rb +493 -0
- data/spec/savon/response_spec.rb +258 -0
- data/spec/savon/soap_fault_spec.rb +126 -0
- data/spec/spec_helper.rb +30 -0
- data/spec/support/endpoint.rb +25 -0
- data/spec/support/fixture.rb +39 -0
- data/spec/support/integration.rb +9 -0
- data/spec/support/stdout.rb +25 -0
- metadata +308 -0
@@ -0,0 +1,71 @@
|
|
1
|
+
require "httpi"
|
2
|
+
|
3
|
+
module Savon
|
4
|
+
class MockExpectation
|
5
|
+
|
6
|
+
def initialize(operation_name)
|
7
|
+
@expected = { :operation_name => operation_name }
|
8
|
+
@actual = nil
|
9
|
+
end
|
10
|
+
|
11
|
+
def with(locals)
|
12
|
+
@expected[:message] = locals[:message]
|
13
|
+
self
|
14
|
+
end
|
15
|
+
|
16
|
+
def returns(response)
|
17
|
+
response = { :code => 200, :headers => {}, :body => response } if response.kind_of?(String)
|
18
|
+
@response = response
|
19
|
+
self
|
20
|
+
end
|
21
|
+
|
22
|
+
def actual(operation_name, builder, globals, locals)
|
23
|
+
@actual = {
|
24
|
+
:operation_name => operation_name,
|
25
|
+
:message => locals[:message]
|
26
|
+
}
|
27
|
+
end
|
28
|
+
|
29
|
+
def verify!
|
30
|
+
unless @actual
|
31
|
+
raise ExpectationError, "Expected a request to the #{@expected[:operation_name].inspect} operation, " \
|
32
|
+
"but no request was executed."
|
33
|
+
end
|
34
|
+
|
35
|
+
verify_operation_name!
|
36
|
+
verify_message!
|
37
|
+
end
|
38
|
+
|
39
|
+
def response!
|
40
|
+
unless @response
|
41
|
+
raise ExpectationError, "This expectation was not set up with a response."
|
42
|
+
end
|
43
|
+
|
44
|
+
HTTPI::Response.new(@response[:code], @response[:headers], @response[:body])
|
45
|
+
end
|
46
|
+
|
47
|
+
private
|
48
|
+
|
49
|
+
def verify_operation_name!
|
50
|
+
unless @expected[:operation_name] == @actual[:operation_name]
|
51
|
+
raise ExpectationError, "Expected a request to the #{@expected[:operation_name].inspect} operation.\n" \
|
52
|
+
"Received a request to the #{@actual[:operation_name].inspect} operation instead."
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def verify_message!
|
57
|
+
return if @expected[:message] == :any
|
58
|
+
unless @expected[:message] == @actual[:message]
|
59
|
+
expected_message = " with this message: #{@expected[:message].inspect}" if @expected[:message]
|
60
|
+
expected_message ||= " with no message."
|
61
|
+
|
62
|
+
actual_message = " with this message: #{@actual[:message].inspect}" if @actual[:message]
|
63
|
+
actual_message ||= " with no message."
|
64
|
+
|
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}"
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
end
|
71
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
require "savon/mock"
|
2
|
+
|
3
|
+
module Savon
|
4
|
+
module SpecHelper
|
5
|
+
|
6
|
+
class Interface
|
7
|
+
|
8
|
+
def mock!
|
9
|
+
Savon.observers << self
|
10
|
+
end
|
11
|
+
|
12
|
+
def unmock!
|
13
|
+
Savon.observers.clear
|
14
|
+
end
|
15
|
+
|
16
|
+
def expects(operation_name)
|
17
|
+
expectation = MockExpectation.new(operation_name)
|
18
|
+
expectations << expectation
|
19
|
+
expectation
|
20
|
+
end
|
21
|
+
|
22
|
+
def expectations
|
23
|
+
@expectations ||= []
|
24
|
+
end
|
25
|
+
|
26
|
+
def notify(operation_name, builder, globals, locals)
|
27
|
+
expectation = expectations.shift
|
28
|
+
|
29
|
+
if expectation
|
30
|
+
expectation.actual(operation_name, builder, globals, locals)
|
31
|
+
|
32
|
+
expectation.verify!
|
33
|
+
expectation.response!
|
34
|
+
else
|
35
|
+
raise ExpectationError, "Unexpected request to the #{operation_name.inspect} operation."
|
36
|
+
end
|
37
|
+
rescue ExpectationError
|
38
|
+
@expectations.clear
|
39
|
+
raise
|
40
|
+
end
|
41
|
+
|
42
|
+
def verify!
|
43
|
+
return if expectations.empty?
|
44
|
+
expectations.each(&:verify!)
|
45
|
+
rescue ExpectationError
|
46
|
+
@expectations.clear
|
47
|
+
raise
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
51
|
+
|
52
|
+
def savon
|
53
|
+
@savon ||= Interface.new
|
54
|
+
end
|
55
|
+
|
56
|
+
def verify_mocks_for_rspec
|
57
|
+
super if defined? super
|
58
|
+
savon.verify!
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
62
|
+
end
|
data/lib/savon/mock.rb
ADDED
data/lib/savon/model.rb
ADDED
@@ -0,0 +1,80 @@
|
|
1
|
+
module Savon
|
2
|
+
module Model
|
3
|
+
|
4
|
+
def self.extended(base)
|
5
|
+
base.setup
|
6
|
+
end
|
7
|
+
|
8
|
+
def setup
|
9
|
+
class_operation_module
|
10
|
+
instance_operation_module
|
11
|
+
end
|
12
|
+
|
13
|
+
# Accepts one or more SOAP operations and generates both class and instance methods named
|
14
|
+
# after the given operations. Each generated method accepts an optional SOAP message Hash.
|
15
|
+
def operations(*operations)
|
16
|
+
operations.each do |operation|
|
17
|
+
define_class_operation(operation)
|
18
|
+
define_instance_operation(operation)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
# Defines a class-level SOAP operation.
|
25
|
+
def define_class_operation(operation)
|
26
|
+
class_operation_module.module_eval %{
|
27
|
+
def #{operation.to_s.snakecase}(locals = {})
|
28
|
+
client.call #{operation.inspect}, locals
|
29
|
+
end
|
30
|
+
}
|
31
|
+
end
|
32
|
+
|
33
|
+
# Defines an instance-level SOAP operation.
|
34
|
+
def define_instance_operation(operation)
|
35
|
+
instance_operation_module.module_eval %{
|
36
|
+
def #{operation.to_s.snakecase}(locals = {})
|
37
|
+
self.class.#{operation.to_s.snakecase} locals
|
38
|
+
end
|
39
|
+
}
|
40
|
+
end
|
41
|
+
|
42
|
+
# Class methods.
|
43
|
+
def class_operation_module
|
44
|
+
@class_operation_module ||= Module.new {
|
45
|
+
|
46
|
+
def client(globals = {})
|
47
|
+
@client ||= Savon::Client.new(globals)
|
48
|
+
rescue InitializationError
|
49
|
+
raise_initialization_error!
|
50
|
+
end
|
51
|
+
|
52
|
+
def global(option, *value)
|
53
|
+
client.globals[option] = value
|
54
|
+
end
|
55
|
+
|
56
|
+
def raise_initialization_error!
|
57
|
+
raise InitializationError,
|
58
|
+
"Expected the model to be initialized with either a WSDL document or the SOAP endpoint and target namespace options.\n" \
|
59
|
+
"Make sure to setup the model by calling the .client class method before calling the .global method.\n\n" \
|
60
|
+
"client(wsdl: '/Users/me/project/service.wsdl') # to use a local WSDL document\n" \
|
61
|
+
"client(wsdl: 'http://example.com?wsdl') # to use a remote WSDL document\n" \
|
62
|
+
"client(endpoint: 'http://example.com', namespace: 'http://v1.example.com') # if you don't have a WSDL document"
|
63
|
+
end
|
64
|
+
|
65
|
+
}.tap { |mod| extend(mod) }
|
66
|
+
end
|
67
|
+
|
68
|
+
# Instance methods.
|
69
|
+
def instance_operation_module
|
70
|
+
@instance_operation_module ||= Module.new {
|
71
|
+
|
72
|
+
def client
|
73
|
+
self.class.client
|
74
|
+
end
|
75
|
+
|
76
|
+
}.tap { |mod| include(mod) }
|
77
|
+
end
|
78
|
+
|
79
|
+
end
|
80
|
+
end
|
@@ -0,0 +1,127 @@
|
|
1
|
+
require "savon/options"
|
2
|
+
require "savon/block_interface"
|
3
|
+
require "savon/request"
|
4
|
+
require "savon/builder"
|
5
|
+
require "savon/response"
|
6
|
+
require "savon/request_logger"
|
7
|
+
|
8
|
+
module Savon
|
9
|
+
class Operation
|
10
|
+
|
11
|
+
def self.create(operation_name, wsdl, globals)
|
12
|
+
if wsdl.document?
|
13
|
+
ensure_name_is_symbol! operation_name
|
14
|
+
ensure_exists! operation_name, wsdl
|
15
|
+
end
|
16
|
+
|
17
|
+
new(operation_name, wsdl, globals)
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.ensure_exists!(operation_name, wsdl)
|
21
|
+
unless wsdl.soap_actions.include? operation_name
|
22
|
+
raise UnknownOperationError, "Unable to find SOAP operation: #{operation_name.inspect}\n" \
|
23
|
+
"Operations provided by your service: #{wsdl.soap_actions.inspect}"
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.ensure_name_is_symbol!(operation_name)
|
28
|
+
unless operation_name.kind_of? Symbol
|
29
|
+
raise ArgumentError, "Expected the first parameter (the name of the operation to call) to be a symbol\n" \
|
30
|
+
"Actual: #{operation_name.inspect} (#{operation_name.class})"
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def initialize(name, wsdl, globals)
|
35
|
+
@name = name
|
36
|
+
@wsdl = wsdl
|
37
|
+
@globals = globals
|
38
|
+
|
39
|
+
@logger = RequestLogger.new(globals)
|
40
|
+
end
|
41
|
+
|
42
|
+
def build(locals = {}, &block)
|
43
|
+
set_locals(locals, block)
|
44
|
+
Builder.new(@name, @wsdl, @globals, @locals)
|
45
|
+
end
|
46
|
+
|
47
|
+
def call(locals = {}, &block)
|
48
|
+
builder = build(locals, &block)
|
49
|
+
|
50
|
+
response = Savon.notify_observers(@name, builder, @globals, @locals)
|
51
|
+
response ||= call_with_logging build_request(builder)
|
52
|
+
|
53
|
+
raise_expected_httpi_response! unless response.kind_of?(HTTPI::Response)
|
54
|
+
|
55
|
+
create_response(response)
|
56
|
+
end
|
57
|
+
|
58
|
+
private
|
59
|
+
|
60
|
+
def create_response(response)
|
61
|
+
if multipart_supported?
|
62
|
+
Multipart::Response.new(response, @globals, @locals)
|
63
|
+
else
|
64
|
+
Response.new(response, @globals, @locals)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def multipart_supported?
|
69
|
+
return false unless @globals[:multipart] || @locals[:multipart]
|
70
|
+
|
71
|
+
if Savon.const_defined? :Multipart
|
72
|
+
true
|
73
|
+
else
|
74
|
+
raise 'Unable to find Savon::Multipart. Make sure the savon-multipart gem is installed and loaded.'
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
def set_locals(locals, block)
|
79
|
+
locals = LocalOptions.new(locals)
|
80
|
+
BlockInterface.new(locals).evaluate(block) if block
|
81
|
+
|
82
|
+
@locals = locals
|
83
|
+
end
|
84
|
+
|
85
|
+
def call_with_logging(request)
|
86
|
+
@logger.log(request) { HTTPI.post(request) }
|
87
|
+
end
|
88
|
+
|
89
|
+
def build_request(builder)
|
90
|
+
request = SOAPRequest.new(@globals).build(
|
91
|
+
:soap_action => soap_action,
|
92
|
+
:cookies => @locals[:cookies]
|
93
|
+
)
|
94
|
+
|
95
|
+
request.url = endpoint
|
96
|
+
request.body = builder.to_s
|
97
|
+
|
98
|
+
# TODO: could HTTPI do this automatically in case the header
|
99
|
+
# was not specified manually? [dh, 2013-01-04]
|
100
|
+
request.headers["Content-Length"] = request.body.bytesize.to_s
|
101
|
+
|
102
|
+
request
|
103
|
+
end
|
104
|
+
|
105
|
+
def soap_action
|
106
|
+
# soap_action explicitly set to something falsy
|
107
|
+
return if @locals.include?(:soap_action) && !@locals[:soap_action]
|
108
|
+
|
109
|
+
# get the soap_action from local options
|
110
|
+
soap_action = @locals[:soap_action]
|
111
|
+
# with no local option, but a wsdl, ask it for the soap_action
|
112
|
+
soap_action ||= @wsdl.soap_action(@name.to_sym) if @wsdl.document?
|
113
|
+
# if there is no soap_action up to this point, fallback to a simple default
|
114
|
+
soap_action ||= Gyoku.xml_tag(@name, :key_converter => @globals[:convert_request_keys_to])
|
115
|
+
end
|
116
|
+
|
117
|
+
def endpoint
|
118
|
+
@globals[:endpoint] || @wsdl.endpoint
|
119
|
+
end
|
120
|
+
|
121
|
+
def raise_expected_httpi_response!
|
122
|
+
raise Error, "Observers need to return an HTTPI::Response to mock " \
|
123
|
+
"the request or nil to execute the request."
|
124
|
+
end
|
125
|
+
|
126
|
+
end
|
127
|
+
end
|
@@ -0,0 +1,330 @@
|
|
1
|
+
require "logger"
|
2
|
+
require "httpi"
|
3
|
+
|
4
|
+
module Savon
|
5
|
+
class Options
|
6
|
+
|
7
|
+
def initialize(options = {})
|
8
|
+
@options = {}
|
9
|
+
assign options
|
10
|
+
end
|
11
|
+
|
12
|
+
attr_reader :option_type
|
13
|
+
|
14
|
+
def [](option)
|
15
|
+
@options[option]
|
16
|
+
end
|
17
|
+
|
18
|
+
def []=(option, value)
|
19
|
+
value = [value].flatten
|
20
|
+
self.send(option, *value)
|
21
|
+
end
|
22
|
+
|
23
|
+
def include?(option)
|
24
|
+
@options.key? option
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def assign(options)
|
30
|
+
options.each do |option, value|
|
31
|
+
self.send(option, value)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def method_missing(option, _)
|
36
|
+
raise UnknownOptionError, "Unknown #{option_type} option: #{option.inspect}"
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
|
41
|
+
class GlobalOptions < Options
|
42
|
+
|
43
|
+
def initialize(options = {})
|
44
|
+
@option_type = :global
|
45
|
+
|
46
|
+
defaults = {
|
47
|
+
:encoding => "UTF-8",
|
48
|
+
:soap_version => 1,
|
49
|
+
:namespaces => {},
|
50
|
+
:logger => Logger.new($stdout),
|
51
|
+
:log => true,
|
52
|
+
:filters => [],
|
53
|
+
:pretty_print_xml => false,
|
54
|
+
:raise_errors => true,
|
55
|
+
:strip_namespaces => true,
|
56
|
+
:convert_response_tags_to => lambda { |tag| tag.snakecase.to_sym},
|
57
|
+
:multipart => false,
|
58
|
+
}
|
59
|
+
|
60
|
+
options = defaults.merge(options)
|
61
|
+
|
62
|
+
# this option is a shortcut on the logger which needs to be set
|
63
|
+
# before it can be modified to set the option.
|
64
|
+
delayed_level = options.delete(:log_level)
|
65
|
+
|
66
|
+
super(options)
|
67
|
+
|
68
|
+
log_level(delayed_level) unless delayed_level.nil?
|
69
|
+
end
|
70
|
+
|
71
|
+
# Location of the local or remote WSDL document.
|
72
|
+
def wsdl(wsdl_address)
|
73
|
+
@options[:wsdl] = wsdl_address
|
74
|
+
end
|
75
|
+
|
76
|
+
# SOAP endpoint.
|
77
|
+
def endpoint(endpoint)
|
78
|
+
@options[:endpoint] = endpoint
|
79
|
+
end
|
80
|
+
|
81
|
+
# Target namespace.
|
82
|
+
def namespace(namespace)
|
83
|
+
@options[:namespace] = namespace
|
84
|
+
end
|
85
|
+
|
86
|
+
# The namespace identifer.
|
87
|
+
def namespace_identifier(identifier)
|
88
|
+
@options[:namespace_identifier] = identifier
|
89
|
+
end
|
90
|
+
|
91
|
+
# Namespaces for the SOAP envelope.
|
92
|
+
def namespaces(namespaces)
|
93
|
+
@options[:namespaces] = namespaces
|
94
|
+
end
|
95
|
+
|
96
|
+
# Proxy server to use for all requests.
|
97
|
+
def proxy(proxy)
|
98
|
+
@options[:proxy] = proxy
|
99
|
+
end
|
100
|
+
|
101
|
+
# A Hash of HTTP headers.
|
102
|
+
def headers(headers)
|
103
|
+
@options[:headers] = headers
|
104
|
+
end
|
105
|
+
|
106
|
+
# Open timeout in seconds.
|
107
|
+
def open_timeout(open_timeout)
|
108
|
+
@options[:open_timeout] = open_timeout
|
109
|
+
end
|
110
|
+
|
111
|
+
# Read timeout in seconds.
|
112
|
+
def read_timeout(read_timeout)
|
113
|
+
@options[:read_timeout] = read_timeout
|
114
|
+
end
|
115
|
+
|
116
|
+
# The encoding to use. Defaults to "UTF-8".
|
117
|
+
def encoding(encoding)
|
118
|
+
@options[:encoding] = encoding
|
119
|
+
end
|
120
|
+
|
121
|
+
# The global SOAP header. Expected to be a Hash or responding to #to_s.
|
122
|
+
def soap_header(header)
|
123
|
+
@options[:soap_header] = header
|
124
|
+
end
|
125
|
+
|
126
|
+
# Sets whether elements should be :qualified or unqualified.
|
127
|
+
# If you need to use this option, please open an issue and make
|
128
|
+
# sure to add your WSDL document for debugging.
|
129
|
+
def element_form_default(element_form_default)
|
130
|
+
@options[:element_form_default] = element_form_default
|
131
|
+
end
|
132
|
+
|
133
|
+
# Can be used to change the SOAP envelope namespace identifier.
|
134
|
+
# If you need to use this option, please open an issue and make
|
135
|
+
# sure to add your WSDL document for debugging.
|
136
|
+
def env_namespace(env_namespace)
|
137
|
+
@options[:env_namespace] = env_namespace
|
138
|
+
end
|
139
|
+
|
140
|
+
# Changes the SOAP version to 1 or 2.
|
141
|
+
def soap_version(soap_version)
|
142
|
+
@options[:soap_version] = soap_version
|
143
|
+
end
|
144
|
+
|
145
|
+
# Whether or not to raise SOAP fault and HTTP errors.
|
146
|
+
def raise_errors(raise_errors)
|
147
|
+
@options[:raise_errors] = raise_errors
|
148
|
+
end
|
149
|
+
|
150
|
+
# Whether or not to log.
|
151
|
+
def log(log)
|
152
|
+
HTTPI.log = log
|
153
|
+
@options[:log] = log
|
154
|
+
end
|
155
|
+
|
156
|
+
# The logger to use. Defaults to a Savon::Logger instance.
|
157
|
+
def logger(logger)
|
158
|
+
@options[:logger] = logger
|
159
|
+
end
|
160
|
+
|
161
|
+
# Changes the Logger's log level.
|
162
|
+
def log_level(level)
|
163
|
+
levels = { :debug => 0, :info => 1, :warn => 2, :error => 3, :fatal => 4 }
|
164
|
+
|
165
|
+
unless levels.include? level
|
166
|
+
raise ArgumentError, "Invalid log level: #{level.inspect}\n" \
|
167
|
+
"Expected one of: #{levels.keys.inspect}"
|
168
|
+
end
|
169
|
+
|
170
|
+
@options[:logger].level = levels[level]
|
171
|
+
end
|
172
|
+
|
173
|
+
# A list of XML tags to filter from logged SOAP messages.
|
174
|
+
def filters(*filters)
|
175
|
+
@options[:filters] = filters.flatten
|
176
|
+
end
|
177
|
+
|
178
|
+
# Whether to pretty print request and response XML log messages.
|
179
|
+
def pretty_print_xml(pretty_print_xml)
|
180
|
+
@options[:pretty_print_xml] = pretty_print_xml
|
181
|
+
end
|
182
|
+
|
183
|
+
# Specifies the SSL version to use.
|
184
|
+
def ssl_version(version)
|
185
|
+
@options[:ssl_version] = version
|
186
|
+
end
|
187
|
+
|
188
|
+
# Whether and how to to verify the connection.
|
189
|
+
def ssl_verify_mode(verify_mode)
|
190
|
+
@options[:ssl_verify_mode] = verify_mode
|
191
|
+
end
|
192
|
+
|
193
|
+
# Sets the cert key file to use.
|
194
|
+
def ssl_cert_key_file(file)
|
195
|
+
@options[:ssl_cert_key_file] = file
|
196
|
+
end
|
197
|
+
|
198
|
+
# Sets the cert key password to use.
|
199
|
+
def ssl_cert_key_password(password)
|
200
|
+
@options[:ssl_cert_key_password] = password
|
201
|
+
end
|
202
|
+
|
203
|
+
# Sets the cert file to use.
|
204
|
+
def ssl_cert_file(file)
|
205
|
+
@options[:ssl_cert_file] = file
|
206
|
+
end
|
207
|
+
|
208
|
+
# Sets the ca cert file to use.
|
209
|
+
def ssl_ca_cert_file(file)
|
210
|
+
@options[:ssl_ca_cert_file] = file
|
211
|
+
end
|
212
|
+
|
213
|
+
# HTTP basic auth credentials.
|
214
|
+
def basic_auth(*credentials)
|
215
|
+
@options[:basic_auth] = credentials.flatten
|
216
|
+
end
|
217
|
+
|
218
|
+
# HTTP digest auth credentials.
|
219
|
+
def digest_auth(*credentials)
|
220
|
+
@options[:digest_auth] = credentials.flatten
|
221
|
+
end
|
222
|
+
|
223
|
+
# NTLM auth credentials.
|
224
|
+
def ntlm(*credentials)
|
225
|
+
@options[:ntlm] = credentials.flatten
|
226
|
+
end
|
227
|
+
|
228
|
+
# WSSE auth credentials for Akami.
|
229
|
+
def wsse_auth(*credentials)
|
230
|
+
@options[:wsse_auth] = credentials.flatten
|
231
|
+
end
|
232
|
+
|
233
|
+
# Instruct Akami to enable wsu:Timestamp headers.
|
234
|
+
def wsse_timestamp(*timestamp)
|
235
|
+
@options[:wsse_timestamp] = timestamp.flatten
|
236
|
+
end
|
237
|
+
|
238
|
+
# Instruct Nori whether to strip namespaces from XML nodes.
|
239
|
+
def strip_namespaces(strip_namespaces)
|
240
|
+
@options[:strip_namespaces] = strip_namespaces
|
241
|
+
end
|
242
|
+
|
243
|
+
# Tell Gyoku how to convert Hash key Symbols to XML tags.
|
244
|
+
# Accepts one of :lower_camelcase, :camelcase, :upcase, or :none.
|
245
|
+
def convert_request_keys_to(converter)
|
246
|
+
@options[:convert_request_keys_to] = converter
|
247
|
+
end
|
248
|
+
|
249
|
+
# Tell Nori how to convert XML tags from the SOAP response into Hash keys.
|
250
|
+
# Accepts a lambda or a block which receives an XML tag and returns a Hash key.
|
251
|
+
# Defaults to convert tags to snakecase Symbols.
|
252
|
+
def convert_response_tags_to(converter = nil, &block)
|
253
|
+
@options[:convert_response_tags_to] = block || converter
|
254
|
+
end
|
255
|
+
|
256
|
+
# Instruct Savon to create a multipart response if available.
|
257
|
+
def multipart(multipart)
|
258
|
+
@options[:multipart] = multipart
|
259
|
+
end
|
260
|
+
end
|
261
|
+
|
262
|
+
class LocalOptions < Options
|
263
|
+
|
264
|
+
def initialize(options = {})
|
265
|
+
@option_type = :local
|
266
|
+
|
267
|
+
defaults = {
|
268
|
+
:advanced_typecasting => true,
|
269
|
+
:response_parser => :nokogiri,
|
270
|
+
:multipart => false
|
271
|
+
}
|
272
|
+
|
273
|
+
super defaults.merge(options)
|
274
|
+
end
|
275
|
+
|
276
|
+
# The local SOAP header. Expected to be a Hash or respond to #to_s.
|
277
|
+
# Will be merged with the global SOAP header if both are Hashes.
|
278
|
+
# Otherwise the local option will be prefered.
|
279
|
+
def soap_header(header)
|
280
|
+
@options[:soap_header] = header
|
281
|
+
end
|
282
|
+
|
283
|
+
# The SOAP message to send. Expected to be a Hash or a String.
|
284
|
+
def message(message)
|
285
|
+
@options[:message] = message
|
286
|
+
end
|
287
|
+
|
288
|
+
# SOAP message tag (formerly known as SOAP input tag). If it's not set, Savon retrieves the name from
|
289
|
+
# the WSDL document (if available). Otherwise, Gyoku converts the operation name into an XML element.
|
290
|
+
def message_tag(message_tag)
|
291
|
+
@options[:message_tag] = message_tag
|
292
|
+
end
|
293
|
+
|
294
|
+
# Attributes for the SOAP message tag.
|
295
|
+
def attributes(attributes)
|
296
|
+
@options[:attributes] = attributes
|
297
|
+
end
|
298
|
+
|
299
|
+
# Value of the SOAPAction HTTP header.
|
300
|
+
def soap_action(soap_action)
|
301
|
+
@options[:soap_action] = soap_action
|
302
|
+
end
|
303
|
+
|
304
|
+
# Cookies to be used for the next request.
|
305
|
+
def cookies(cookies)
|
306
|
+
@options[:cookies] = cookies
|
307
|
+
end
|
308
|
+
|
309
|
+
# The SOAP request XML to send. Expected to be a String.
|
310
|
+
def xml(xml)
|
311
|
+
@options[:xml] = xml
|
312
|
+
end
|
313
|
+
|
314
|
+
# Instruct Nori to use advanced typecasting.
|
315
|
+
def advanced_typecasting(advanced)
|
316
|
+
@options[:advanced_typecasting] = advanced
|
317
|
+
end
|
318
|
+
|
319
|
+
# Instruct Nori to use :rexml or :nokogiri to parse the response.
|
320
|
+
def response_parser(parser)
|
321
|
+
@options[:response_parser] = parser
|
322
|
+
end
|
323
|
+
|
324
|
+
# Instruct Savon to create a multipart response if available.
|
325
|
+
def multipart(multipart)
|
326
|
+
@options[:multipart] = multipart
|
327
|
+
end
|
328
|
+
|
329
|
+
end
|
330
|
+
end
|