savon 2.17.4 → 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 +4 -4
- data/CHANGELOG.md +17 -115
- data/README.md +52 -52
- data/Rakefile +2 -6
- data/lib/savon/block_interface.rb +4 -3
- data/lib/savon/builder.rb +37 -60
- data/lib/savon/client.rb +13 -44
- data/lib/savon/header.rb +40 -87
- data/lib/savon/http_error.rb +9 -9
- data/lib/savon/log_message.rb +3 -2
- data/lib/savon/message.rb +7 -6
- data/lib/savon/mock/expectation.rb +24 -38
- data/lib/savon/mock/spec_helper.rb +11 -7
- data/lib/savon/mock.rb +0 -1
- data/lib/savon/model.rb +25 -25
- data/lib/savon/operation.rb +92 -112
- data/lib/savon/options.rb +175 -276
- data/lib/savon/qualified_message.rb +1 -2
- data/lib/savon/request.rb +147 -0
- data/lib/savon/request_logger.rb +57 -0
- data/lib/savon/response.rb +31 -45
- data/lib/savon/soap_fault.rb +6 -6
- data/lib/savon/string_utils.rb +4 -3
- data/lib/savon/version.rb +1 -2
- data/lib/savon.rb +11 -2
- metadata +130 -71
- data/lib/savon/addressing.rb +0 -60
- data/lib/savon/effective_options.rb +0 -124
- data/lib/savon/faraday_migration_hint.rb +0 -186
- data/lib/savon/transport/faraday.rb +0 -101
- data/lib/savon/transport/httpi.rb +0 -138
- data/lib/savon/transport/logging.rb +0 -60
- data/lib/savon/transport/response.rb +0 -73
|
@@ -1,186 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require "uri"
|
|
4
|
-
|
|
5
|
-
module Savon
|
|
6
|
-
# Formats the replacement Faraday setup for one HTTPI-only option.
|
|
7
|
-
class FaradayMigrationHint
|
|
8
|
-
VALUE_AWARE_OPTIONS = %i[
|
|
9
|
-
proxy
|
|
10
|
-
open_timeout
|
|
11
|
-
read_timeout
|
|
12
|
-
write_timeout
|
|
13
|
-
ssl_version
|
|
14
|
-
ssl_min_version
|
|
15
|
-
ssl_max_version
|
|
16
|
-
ssl_verify_mode
|
|
17
|
-
ssl_cert_key_file
|
|
18
|
-
ssl_cert_file
|
|
19
|
-
ssl_ca_cert_file
|
|
20
|
-
ssl_ciphers
|
|
21
|
-
ssl_ca_cert_path
|
|
22
|
-
adapter
|
|
23
|
-
].freeze
|
|
24
|
-
|
|
25
|
-
STATIC_HINTS = {
|
|
26
|
-
ssl_cert_key: "client.faraday.ssl.client_key = key",
|
|
27
|
-
ssl_cert_key_password: [
|
|
28
|
-
"key = OpenSSL::PKey.read(File.read(key_path), password)",
|
|
29
|
-
"client.faraday.ssl.client_key = key"
|
|
30
|
-
],
|
|
31
|
-
ssl_cert: "client.faraday.ssl.client_cert = cert",
|
|
32
|
-
ssl_ca_cert: [
|
|
33
|
-
"store = OpenSSL::X509::Store.new",
|
|
34
|
-
"store.set_default_paths",
|
|
35
|
-
"store.add_cert(cert)",
|
|
36
|
-
"client.faraday.ssl.cert_store = store"
|
|
37
|
-
],
|
|
38
|
-
ssl_cert_store: "client.faraday.ssl.cert_store = store",
|
|
39
|
-
basic_auth: "client.faraday.request :authorization, :basic, user, pass",
|
|
40
|
-
digest_auth: [
|
|
41
|
-
"gem 'faraday-digestauth'",
|
|
42
|
-
"require 'faraday/digestauth'",
|
|
43
|
-
"client.faraday.request :digest, user, pass"
|
|
44
|
-
],
|
|
45
|
-
ntlm: [
|
|
46
|
-
"gem 'faraday-ntlm_auth'",
|
|
47
|
-
"require 'faraday/ntlm_auth'",
|
|
48
|
-
"client.faraday.adapter :net_http_persistent",
|
|
49
|
-
"client.faraday.request :ntlm_auth, auth: [user, pass, domain]"
|
|
50
|
-
],
|
|
51
|
-
follow_redirects: [
|
|
52
|
-
"gem 'faraday-follow_redirects'",
|
|
53
|
-
"require 'faraday/follow_redirects'",
|
|
54
|
-
"client.faraday.response :follow_redirects"
|
|
55
|
-
]
|
|
56
|
-
}.freeze
|
|
57
|
-
|
|
58
|
-
OPTIONS = (VALUE_AWARE_OPTIONS + STATIC_HINTS.keys).freeze
|
|
59
|
-
|
|
60
|
-
def initialize(option, value)
|
|
61
|
-
@option = option
|
|
62
|
-
@value = value
|
|
63
|
-
end
|
|
64
|
-
|
|
65
|
-
def message
|
|
66
|
-
hint = hint_lines
|
|
67
|
-
return " #{option} - Use: #{hint}" unless hint.is_a?(Array)
|
|
68
|
-
|
|
69
|
-
" #{option} - Use:\n#{hint.map { |line| " #{line}" }.join("\n")}"
|
|
70
|
-
end
|
|
71
|
-
|
|
72
|
-
private
|
|
73
|
-
|
|
74
|
-
attr_reader :option, :value
|
|
75
|
-
|
|
76
|
-
def hint_lines
|
|
77
|
-
case option
|
|
78
|
-
when :proxy
|
|
79
|
-
"client.faraday.proxy = #{redacted_proxy_value}"
|
|
80
|
-
when :open_timeout, :read_timeout, :write_timeout
|
|
81
|
-
"client.faraday.options.#{option} = #{value.inspect}"
|
|
82
|
-
when :ssl_version, :ssl_min_version, :ssl_max_version
|
|
83
|
-
ssl_version_hint
|
|
84
|
-
when :ssl_verify_mode
|
|
85
|
-
ssl_verify_mode_hint
|
|
86
|
-
when :ssl_cert_key_file
|
|
87
|
-
ssl_cert_key_file_hint
|
|
88
|
-
when :ssl_cert_file
|
|
89
|
-
ssl_cert_file_hint
|
|
90
|
-
when :ssl_ca_cert_file
|
|
91
|
-
"client.faraday.ssl.ca_file = #{value.inspect}"
|
|
92
|
-
when :ssl_ciphers
|
|
93
|
-
"client.faraday.ssl.ciphers = #{value.inspect}"
|
|
94
|
-
when :ssl_ca_cert_path
|
|
95
|
-
"client.faraday.ssl.ca_path = #{value.inspect}"
|
|
96
|
-
when :adapter
|
|
97
|
-
adapter_hint
|
|
98
|
-
else
|
|
99
|
-
STATIC_HINTS.fetch(option)
|
|
100
|
-
end
|
|
101
|
-
end
|
|
102
|
-
|
|
103
|
-
def redacted_proxy_value
|
|
104
|
-
uri = URI.parse(value.to_s)
|
|
105
|
-
return value.inspect unless uri.absolute? && uri.host
|
|
106
|
-
|
|
107
|
-
redacted = uri.dup
|
|
108
|
-
redacted.userinfo = "..." if redacted.userinfo
|
|
109
|
-
redacted.path = "" if redacted.respond_to?(:path=)
|
|
110
|
-
redacted.query = nil if redacted.respond_to?(:query=)
|
|
111
|
-
redacted.fragment = nil if redacted.respond_to?(:fragment=)
|
|
112
|
-
redacted.to_s.inspect
|
|
113
|
-
rescue URI::InvalidURIError
|
|
114
|
-
'"[redacted proxy URL]"'
|
|
115
|
-
end
|
|
116
|
-
|
|
117
|
-
def ssl_version_hint
|
|
118
|
-
faraday_option = {
|
|
119
|
-
ssl_version: "version",
|
|
120
|
-
ssl_min_version: "min_version",
|
|
121
|
-
ssl_max_version: "max_version"
|
|
122
|
-
}.fetch(option)
|
|
123
|
-
|
|
124
|
-
"client.faraday.ssl.#{faraday_option} = #{value.inspect}"
|
|
125
|
-
end
|
|
126
|
-
|
|
127
|
-
def ssl_cert_key_file_hint
|
|
128
|
-
[
|
|
129
|
-
"key = OpenSSL::PKey.read(File.read(#{value.inspect}))",
|
|
130
|
-
"client.faraday.ssl.client_key = key"
|
|
131
|
-
]
|
|
132
|
-
end
|
|
133
|
-
|
|
134
|
-
def ssl_cert_file_hint
|
|
135
|
-
[
|
|
136
|
-
"cert = OpenSSL::X509::Certificate.new(File.read(#{value.inspect}))",
|
|
137
|
-
"client.faraday.ssl.client_cert = cert"
|
|
138
|
-
]
|
|
139
|
-
end
|
|
140
|
-
|
|
141
|
-
def adapter_hint
|
|
142
|
-
case value
|
|
143
|
-
when :net_http
|
|
144
|
-
"client.faraday.adapter :net_http"
|
|
145
|
-
when :httpclient
|
|
146
|
-
[
|
|
147
|
-
"gem 'faraday-httpclient'",
|
|
148
|
-
"require 'faraday/httpclient'",
|
|
149
|
-
"client.faraday.adapter :httpclient"
|
|
150
|
-
]
|
|
151
|
-
when :excon
|
|
152
|
-
[
|
|
153
|
-
"gem 'faraday-excon'",
|
|
154
|
-
"require 'faraday/excon'",
|
|
155
|
-
"client.faraday.adapter :excon"
|
|
156
|
-
]
|
|
157
|
-
when :net_http_persistent
|
|
158
|
-
[
|
|
159
|
-
"gem 'faraday-net_http_persistent'",
|
|
160
|
-
"require 'faraday/net_http_persistent'",
|
|
161
|
-
"client.faraday.adapter :net_http_persistent"
|
|
162
|
-
]
|
|
163
|
-
else
|
|
164
|
-
[
|
|
165
|
-
"choose and install a Faraday adapter matching #{value.inspect}",
|
|
166
|
-
"client.faraday.adapter :net_http"
|
|
167
|
-
]
|
|
168
|
-
end
|
|
169
|
-
end
|
|
170
|
-
|
|
171
|
-
def ssl_verify_mode_hint
|
|
172
|
-
case value
|
|
173
|
-
when :none
|
|
174
|
-
"client.faraday.ssl.verify_mode = OpenSSL::SSL::VERIFY_NONE"
|
|
175
|
-
when :peer
|
|
176
|
-
"client.faraday.ssl.verify_mode = OpenSSL::SSL::VERIFY_PEER"
|
|
177
|
-
when :fail_if_no_peer_cert
|
|
178
|
-
"client.faraday.ssl.verify_mode = OpenSSL::SSL::VERIFY_FAIL_IF_NO_PEER_CERT"
|
|
179
|
-
when :client_once
|
|
180
|
-
"client.faraday.ssl.verify_mode = OpenSSL::SSL::VERIFY_CLIENT_ONCE"
|
|
181
|
-
else
|
|
182
|
-
"client.faraday.ssl.verify_mode = OpenSSL::SSL::VERIFY_PEER or OpenSSL::SSL::VERIFY_NONE"
|
|
183
|
-
end
|
|
184
|
-
end
|
|
185
|
-
end
|
|
186
|
-
end
|
|
@@ -1,101 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require "savon/transport/logging"
|
|
4
|
-
require "savon/transport/response"
|
|
5
|
-
|
|
6
|
-
module Savon
|
|
7
|
-
module Transport
|
|
8
|
-
# Faraday-backed HTTP transport for the opt-in Faraday path.
|
|
9
|
-
#
|
|
10
|
-
# Encapsulates everything Faraday-specific:
|
|
11
|
-
# * header assembly (SOAP + global + local + cookies)
|
|
12
|
-
# * request execution via the caller-configured Faraday::Connection
|
|
13
|
-
#
|
|
14
|
-
# Transport-level concerns (SSL, auth, proxy, timeouts, middleware) are
|
|
15
|
-
# the caller's responsibility via client.faraday before any call is made.
|
|
16
|
-
class Faraday
|
|
17
|
-
include Logging
|
|
18
|
-
|
|
19
|
-
# @param connection [Faraday::Connection] the memoized connection from client.faraday
|
|
20
|
-
# @param globals [Savon::GlobalOptions] the client-level options
|
|
21
|
-
def initialize(connection, globals)
|
|
22
|
-
@connection = connection
|
|
23
|
-
@globals = globals
|
|
24
|
-
end
|
|
25
|
-
|
|
26
|
-
# Assembles headers, executes the POST via the Faraday connection, and
|
|
27
|
-
# returns a Transport::Response. Logs the outbound request and inbound
|
|
28
|
-
# response when logging is enabled.
|
|
29
|
-
#
|
|
30
|
-
# @param url [String] the SOAP endpoint URL
|
|
31
|
-
# @param soap_headers [Hash] SOAP-level headers (Content-Type, SOAPAction, etc.)
|
|
32
|
-
# @param body [String] the serialized SOAP envelope
|
|
33
|
-
# @param locals [Savon::LocalOptions] per-request options
|
|
34
|
-
# @return [Transport::Response]
|
|
35
|
-
def post(url, soap_headers, body, locals)
|
|
36
|
-
headers = build_headers(soap_headers, locals)
|
|
37
|
-
|
|
38
|
-
log_request(url, headers, body) if log?
|
|
39
|
-
|
|
40
|
-
faraday_response = @connection.post(url, body, headers)
|
|
41
|
-
response = normalize_response(faraday_response)
|
|
42
|
-
|
|
43
|
-
log_response(response) if log?
|
|
44
|
-
response
|
|
45
|
-
end
|
|
46
|
-
|
|
47
|
-
# Normalizes a native Faraday::Response into a Transport::Response.
|
|
48
|
-
#
|
|
49
|
-
# @param faraday_response [Faraday::Response]
|
|
50
|
-
# @return [Transport::Response]
|
|
51
|
-
def normalize_response(faraday_response)
|
|
52
|
-
Response.from_faraday(faraday_response)
|
|
53
|
-
end
|
|
54
|
-
|
|
55
|
-
# Parses Set-Cookie headers into a Hash of name => value. Accepts both
|
|
56
|
-
# the Array and String form. Attributes after the first ';' are discarded.
|
|
57
|
-
def self.parse_cookies(headers)
|
|
58
|
-
raw = headers["set-cookie"] || headers["Set-Cookie"]
|
|
59
|
-
return {} unless raw
|
|
60
|
-
|
|
61
|
-
raw_array = raw.is_a?(Array) ? raw : raw.split(/,\s*/)
|
|
62
|
-
raw_array.each_with_object({}) do |cookie_str, hash|
|
|
63
|
-
name_value = cookie_str.split(";", 2).first.to_s.strip
|
|
64
|
-
name, value = name_value.split("=", 2)
|
|
65
|
-
hash[name] = value if name && !name.empty?
|
|
66
|
-
end
|
|
67
|
-
end
|
|
68
|
-
|
|
69
|
-
private
|
|
70
|
-
|
|
71
|
-
# Merges all header sources in precedence order:
|
|
72
|
-
# locals[:headers] > globals[:headers] > soap_headers
|
|
73
|
-
# Appends Cookie from locals[:cookies].
|
|
74
|
-
def build_headers(soap_headers, locals)
|
|
75
|
-
headers = {}
|
|
76
|
-
headers.merge!(@globals[:headers]) if @globals.include?(:headers)
|
|
77
|
-
headers.merge!(locals[:headers]) if locals.include?(:headers)
|
|
78
|
-
|
|
79
|
-
# soap_headers are lowest priority
|
|
80
|
-
soap_headers.each do |k, v| headers[k] ||= v end
|
|
81
|
-
|
|
82
|
-
cookie_header = format_cookies(locals[:cookies])
|
|
83
|
-
headers["Cookie"] = cookie_header if cookie_header
|
|
84
|
-
|
|
85
|
-
headers
|
|
86
|
-
end
|
|
87
|
-
|
|
88
|
-
# Builds the Cookie header from a given value.
|
|
89
|
-
# Accepts:
|
|
90
|
-
# * String - passed through verbatim
|
|
91
|
-
# * Hash - formatted as "name=value; name=value" (browser style)
|
|
92
|
-
# Returns nil when no cookies were supplied.
|
|
93
|
-
def format_cookies(cookies)
|
|
94
|
-
return nil if cookies.nil?
|
|
95
|
-
return cookies if cookies.is_a?(String)
|
|
96
|
-
|
|
97
|
-
cookies.map { |name, value| "#{name}=#{value}" }.join("; ")
|
|
98
|
-
end
|
|
99
|
-
end
|
|
100
|
-
end
|
|
101
|
-
end
|
|
@@ -1,138 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require "httpi"
|
|
4
|
-
require "savon/transport/logging"
|
|
5
|
-
require "savon/transport/response"
|
|
6
|
-
|
|
7
|
-
module Savon
|
|
8
|
-
module Transport
|
|
9
|
-
# HTTPI-backed HTTP transport for the default HTTP path.
|
|
10
|
-
#
|
|
11
|
-
# Encapsulates everything HTTPI-specific:
|
|
12
|
-
# * header assembly
|
|
13
|
-
# * proxy/SSL/auth/timeout configuration
|
|
14
|
-
# * request execution
|
|
15
|
-
class HTTPI
|
|
16
|
-
include Logging
|
|
17
|
-
|
|
18
|
-
# @param globals [Savon::GlobalOptions] the client-level options
|
|
19
|
-
def initialize(globals)
|
|
20
|
-
@globals = globals
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
# Assembles and executes a SOAP request, returning a Transport::Response.
|
|
24
|
-
# Logs the outbound request and inbound response when logging is enabled.
|
|
25
|
-
#
|
|
26
|
-
# @param url [String] the SOAP endpoint URL
|
|
27
|
-
# @param soap_headers [Hash] SOAP-level headers
|
|
28
|
-
# @param body [String] the serialized SOAP envelope
|
|
29
|
-
# @param locals [Savon::LocalOptions] per-request options
|
|
30
|
-
# @return [Transport::Response]
|
|
31
|
-
def post(url, soap_headers, body, locals)
|
|
32
|
-
http_request = to_httpi_request(url, soap_headers, body, locals)
|
|
33
|
-
|
|
34
|
-
log_request(http_request.url, http_request.headers, http_request.body) if log?
|
|
35
|
-
|
|
36
|
-
httpi_response = ::HTTPI.post(http_request, @globals[:adapter])
|
|
37
|
-
response = normalize_response(httpi_response)
|
|
38
|
-
|
|
39
|
-
log_response(response) if log?
|
|
40
|
-
response
|
|
41
|
-
end
|
|
42
|
-
|
|
43
|
-
# Normalizes a native HTTPI::Response into a Transport::Response.
|
|
44
|
-
#
|
|
45
|
-
# @param httpi_response [HTTPI::Response]
|
|
46
|
-
# @return [Transport::Response]
|
|
47
|
-
def normalize_response(httpi_response)
|
|
48
|
-
Response.from_httpi(httpi_response)
|
|
49
|
-
end
|
|
50
|
-
|
|
51
|
-
# Builds a fully-configured HTTPI::Request.
|
|
52
|
-
#
|
|
53
|
-
# @param url [String] the SOAP endpoint URL
|
|
54
|
-
# @param soap_headers [Hash] SOAP-level headers
|
|
55
|
-
# @param body [String] the serialized SOAP envelope
|
|
56
|
-
# @param locals [Savon::LocalOptions] per-request options
|
|
57
|
-
# @return [HTTPI::Request]
|
|
58
|
-
def to_httpi_request(url, soap_headers, body, locals)
|
|
59
|
-
headers = {}
|
|
60
|
-
headers.merge!(@globals[:headers]) if @globals.include?(:headers)
|
|
61
|
-
headers.merge!(locals[:headers]) if locals.include?(:headers)
|
|
62
|
-
|
|
63
|
-
# soap_headers are lowest priority
|
|
64
|
-
soap_headers.each do |k, v| headers[k] ||= v end
|
|
65
|
-
|
|
66
|
-
http_request = ::HTTPI::Request.new
|
|
67
|
-
http_request.url = url
|
|
68
|
-
http_request.body = body
|
|
69
|
-
http_request.headers = headers
|
|
70
|
-
http_request.set_cookies(locals[:cookies]) if locals[:cookies]
|
|
71
|
-
configure_http_request(http_request)
|
|
72
|
-
http_request
|
|
73
|
-
end
|
|
74
|
-
|
|
75
|
-
# Returns a configured HTTPI::Request for Wasabi's WSDL resolver.
|
|
76
|
-
# Applies global headers and all transport-level options and
|
|
77
|
-
# leaves the rest to Wasabi.
|
|
78
|
-
#
|
|
79
|
-
# @return [HTTPI::Request]
|
|
80
|
-
def wsdl_request
|
|
81
|
-
http_request = ::HTTPI::Request.new
|
|
82
|
-
http_request.headers = @globals[:headers].dup if @globals.include?(:headers)
|
|
83
|
-
configure_http_request(http_request)
|
|
84
|
-
http_request
|
|
85
|
-
end
|
|
86
|
-
|
|
87
|
-
private
|
|
88
|
-
|
|
89
|
-
def configure_http_request(http_request)
|
|
90
|
-
configure_proxy(http_request)
|
|
91
|
-
configure_timeouts(http_request)
|
|
92
|
-
configure_ssl(http_request)
|
|
93
|
-
configure_auth(http_request)
|
|
94
|
-
configure_redirect_handling(http_request)
|
|
95
|
-
end
|
|
96
|
-
|
|
97
|
-
def configure_proxy(http_request)
|
|
98
|
-
http_request.proxy = @globals[:proxy] if @globals.include?(:proxy)
|
|
99
|
-
end
|
|
100
|
-
|
|
101
|
-
def configure_timeouts(http_request)
|
|
102
|
-
http_request.open_timeout = @globals[:open_timeout] if @globals.include?(:open_timeout)
|
|
103
|
-
http_request.read_timeout = @globals[:read_timeout] if @globals.include?(:read_timeout)
|
|
104
|
-
http_request.write_timeout = @globals[:write_timeout] if @globals.include?(:write_timeout)
|
|
105
|
-
end
|
|
106
|
-
|
|
107
|
-
# Configures SSL on the HTTPI::Request from all ssl globals.
|
|
108
|
-
# SSL option reference: https://github.com/savonrb/httpi/blob/main/lib/httpi/auth/ssl.rb
|
|
109
|
-
def configure_ssl(http_request)
|
|
110
|
-
ssl = http_request.auth.ssl
|
|
111
|
-
ssl.ssl_version = @globals[:ssl_version] if @globals.include?(:ssl_version)
|
|
112
|
-
ssl.min_version = @globals[:ssl_min_version] if @globals.include?(:ssl_min_version)
|
|
113
|
-
ssl.max_version = @globals[:ssl_max_version] if @globals.include?(:ssl_max_version)
|
|
114
|
-
ssl.verify_mode = @globals[:ssl_verify_mode] if @globals.include?(:ssl_verify_mode)
|
|
115
|
-
ssl.ciphers = @globals[:ssl_ciphers] if @globals.include?(:ssl_ciphers)
|
|
116
|
-
ssl.cert_key_file = @globals[:ssl_cert_key_file] if @globals.include?(:ssl_cert_key_file)
|
|
117
|
-
ssl.cert_key = @globals[:ssl_cert_key] if @globals.include?(:ssl_cert_key)
|
|
118
|
-
ssl.cert_file = @globals[:ssl_cert_file] if @globals.include?(:ssl_cert_file)
|
|
119
|
-
ssl.cert = @globals[:ssl_cert] if @globals.include?(:ssl_cert)
|
|
120
|
-
ssl.ca_cert_file = @globals[:ssl_ca_cert_file] if @globals.include?(:ssl_ca_cert_file)
|
|
121
|
-
ssl.ca_cert_path = @globals[:ssl_ca_cert_path] if @globals.include?(:ssl_ca_cert_path)
|
|
122
|
-
ssl.ca_cert = @globals[:ssl_ca_cert] if @globals.include?(:ssl_ca_cert)
|
|
123
|
-
ssl.cert_store = @globals[:ssl_cert_store] if @globals.include?(:ssl_cert_store)
|
|
124
|
-
ssl.cert_key_password = @globals[:ssl_cert_key_password] if @globals.include?(:ssl_cert_key_password)
|
|
125
|
-
end
|
|
126
|
-
|
|
127
|
-
def configure_auth(http_request)
|
|
128
|
-
http_request.auth.basic(*@globals[:basic_auth]) if @globals.include?(:basic_auth)
|
|
129
|
-
http_request.auth.digest(*@globals[:digest_auth]) if @globals.include?(:digest_auth)
|
|
130
|
-
http_request.auth.ntlm(*@globals[:ntlm]) if @globals.include?(:ntlm)
|
|
131
|
-
end
|
|
132
|
-
|
|
133
|
-
def configure_redirect_handling(http_request)
|
|
134
|
-
http_request.follow_redirect = @globals[:follow_redirects] if @globals.include?(:follow_redirects)
|
|
135
|
-
end
|
|
136
|
-
end
|
|
137
|
-
end
|
|
138
|
-
end
|
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require "savon/log_message"
|
|
4
|
-
|
|
5
|
-
module Savon
|
|
6
|
-
module Transport
|
|
7
|
-
# Shared logging behaviour for HTTP transports.
|
|
8
|
-
#
|
|
9
|
-
# Expects the including class to expose @globals (Savon::GlobalOptions)
|
|
10
|
-
# so that log level, filters, and pretty-print settings can be accessed.
|
|
11
|
-
#
|
|
12
|
-
# log_request and log_response are intentionally private so that each
|
|
13
|
-
# transport drives them from its own post method.
|
|
14
|
-
module Logging
|
|
15
|
-
private
|
|
16
|
-
|
|
17
|
-
def log?
|
|
18
|
-
@globals[:log]
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
def log_headers?
|
|
22
|
-
@globals[:log_headers]
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
def logger
|
|
26
|
-
@globals[:logger]
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
# Logs the outbound request at INFO (URL and optional headers)
|
|
30
|
-
# and DEBUG (filtered/pretty-printed body).
|
|
31
|
-
#
|
|
32
|
-
# @param url [String] the SOAP endpoint URL
|
|
33
|
-
# @param headers [Hash] request headers
|
|
34
|
-
# @param body [String] the serialized SOAP envelope
|
|
35
|
-
def log_request(url, headers, body)
|
|
36
|
-
logger.info do "SOAP request: #{url}" end
|
|
37
|
-
logger.info { headers_to_log(headers) } if log_headers?
|
|
38
|
-
logger.debug { body_to_log(body) }
|
|
39
|
-
end
|
|
40
|
-
|
|
41
|
-
# Logs the inbound response at INFO (status line)
|
|
42
|
-
# and DEBUG (headers and filtered/pretty-printed body).
|
|
43
|
-
#
|
|
44
|
-
# @param response [Transport::Response]
|
|
45
|
-
def log_response(response)
|
|
46
|
-
logger.info do "SOAP response (status #{response.code})" end
|
|
47
|
-
logger.debug { headers_to_log(response.headers) } if log_headers?
|
|
48
|
-
logger.debug { body_to_log(response.body) }
|
|
49
|
-
end
|
|
50
|
-
|
|
51
|
-
def headers_to_log(headers)
|
|
52
|
-
headers.map { |key, value| "#{key}: #{value}" }.join("\n")
|
|
53
|
-
end
|
|
54
|
-
|
|
55
|
-
def body_to_log(body)
|
|
56
|
-
LogMessage.new(body, @globals[:filters], @globals[:pretty_print_xml]).to_s
|
|
57
|
-
end
|
|
58
|
-
end
|
|
59
|
-
end
|
|
60
|
-
end
|
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require "httpi"
|
|
4
|
-
require "savon/transport/faraday"
|
|
5
|
-
|
|
6
|
-
module Savon
|
|
7
|
-
module Transport
|
|
8
|
-
# Transport-agnostic HTTP response value object.
|
|
9
|
-
#
|
|
10
|
-
# Every transport produces a Transport::Response so that higher-level code
|
|
11
|
-
# never depends on transport-specific code. Immutable once constructed.
|
|
12
|
-
#
|
|
13
|
-
# The shape of #cookies is transport-specific: HTTPI responses expose an
|
|
14
|
-
# Array of HTTPI::Cookie, while Faraday responses expose a plain Hash so
|
|
15
|
-
# Faraday users do not depend on HTTPI types.
|
|
16
|
-
class Response
|
|
17
|
-
# Builds a Response from an HTTPI::Response.
|
|
18
|
-
#
|
|
19
|
-
# @param httpi_response [HTTPI::Response]
|
|
20
|
-
# @return [Transport::Response]
|
|
21
|
-
def self.from_httpi(httpi_response)
|
|
22
|
-
new(
|
|
23
|
-
httpi_response.code,
|
|
24
|
-
httpi_response.headers,
|
|
25
|
-
httpi_response.body,
|
|
26
|
-
cookies: ::HTTPI::Cookie.list_from_headers(httpi_response.headers)
|
|
27
|
-
)
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
-
# Builds a Response from a Faraday::Response.
|
|
31
|
-
#
|
|
32
|
-
# @param faraday_response [Faraday::Response]
|
|
33
|
-
# @return [Transport::Response]
|
|
34
|
-
def self.from_faraday(faraday_response)
|
|
35
|
-
new(
|
|
36
|
-
faraday_response.status,
|
|
37
|
-
faraday_response.headers.to_h,
|
|
38
|
-
faraday_response.body,
|
|
39
|
-
cookies: Savon::Transport::Faraday.parse_cookies(faraday_response.headers)
|
|
40
|
-
)
|
|
41
|
-
end
|
|
42
|
-
|
|
43
|
-
# @param code [Integer] HTTP status code
|
|
44
|
-
# @param headers [Hash] response headers
|
|
45
|
-
# @param body [String] response body
|
|
46
|
-
# @param cookies [Object] parsed cookies in a transport-specific shape
|
|
47
|
-
def initialize(code, headers, body, cookies: nil)
|
|
48
|
-
@code = code
|
|
49
|
-
@headers = headers
|
|
50
|
-
@body = body
|
|
51
|
-
@cookies = cookies
|
|
52
|
-
end
|
|
53
|
-
|
|
54
|
-
# Returns the HTTP status code.
|
|
55
|
-
attr_reader :code
|
|
56
|
-
|
|
57
|
-
# Returns the response headers hash.
|
|
58
|
-
attr_reader :headers
|
|
59
|
-
|
|
60
|
-
# Returns the response body string.
|
|
61
|
-
attr_reader :body
|
|
62
|
-
|
|
63
|
-
# Returns the parsed cookies in a transport-specific shape.
|
|
64
|
-
# See class-level docs.
|
|
65
|
-
attr_reader :cookies
|
|
66
|
-
|
|
67
|
-
# Returns true when the HTTP status code indicates an error (>= 300).
|
|
68
|
-
def error?
|
|
69
|
-
@code >= 300
|
|
70
|
-
end
|
|
71
|
-
end
|
|
72
|
-
end
|
|
73
|
-
end
|