workato-connector-sdk 0.1.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/LICENSE.md +20 -0
- data/README.md +1093 -0
- data/exe/workato +5 -0
- data/lib/workato/cli/edit_command.rb +71 -0
- data/lib/workato/cli/exec_command.rb +191 -0
- data/lib/workato/cli/generate_command.rb +105 -0
- data/lib/workato/cli/generators/connector_generator.rb +94 -0
- data/lib/workato/cli/generators/master_key_generator.rb +56 -0
- data/lib/workato/cli/main.rb +142 -0
- data/lib/workato/cli/push_command.rb +208 -0
- data/lib/workato/connector/sdk/account_properties.rb +60 -0
- data/lib/workato/connector/sdk/action.rb +88 -0
- data/lib/workato/connector/sdk/block_invocation_refinements.rb +30 -0
- data/lib/workato/connector/sdk/connector.rb +230 -0
- data/lib/workato/connector/sdk/dsl/account_property.rb +15 -0
- data/lib/workato/connector/sdk/dsl/call.rb +17 -0
- data/lib/workato/connector/sdk/dsl/error.rb +15 -0
- data/lib/workato/connector/sdk/dsl/http.rb +60 -0
- data/lib/workato/connector/sdk/dsl/lookup_table.rb +15 -0
- data/lib/workato/connector/sdk/dsl/time.rb +21 -0
- data/lib/workato/connector/sdk/dsl/workato_code_lib.rb +105 -0
- data/lib/workato/connector/sdk/dsl/workato_schema.rb +15 -0
- data/lib/workato/connector/sdk/dsl.rb +46 -0
- data/lib/workato/connector/sdk/errors.rb +30 -0
- data/lib/workato/connector/sdk/lookup_tables.rb +62 -0
- data/lib/workato/connector/sdk/object_definitions.rb +74 -0
- data/lib/workato/connector/sdk/operation.rb +217 -0
- data/lib/workato/connector/sdk/request.rb +399 -0
- data/lib/workato/connector/sdk/settings.rb +130 -0
- data/lib/workato/connector/sdk/summarize.rb +61 -0
- data/lib/workato/connector/sdk/trigger.rb +96 -0
- data/lib/workato/connector/sdk/version.rb +9 -0
- data/lib/workato/connector/sdk/workato_schemas.rb +37 -0
- data/lib/workato/connector/sdk/xml.rb +35 -0
- data/lib/workato/connector/sdk.rb +58 -0
- data/lib/workato/extension/array.rb +124 -0
- data/lib/workato/extension/case_sensitive_headers.rb +51 -0
- data/lib/workato/extension/currency.rb +15 -0
- data/lib/workato/extension/date.rb +14 -0
- data/lib/workato/extension/enumerable.rb +55 -0
- data/lib/workato/extension/extra_chain_cert.rb +40 -0
- data/lib/workato/extension/hash.rb +13 -0
- data/lib/workato/extension/integer.rb +17 -0
- data/lib/workato/extension/nil_class.rb +17 -0
- data/lib/workato/extension/object.rb +38 -0
- data/lib/workato/extension/phone.rb +14 -0
- data/lib/workato/extension/string.rb +268 -0
- data/lib/workato/extension/symbol.rb +13 -0
- data/lib/workato/extension/time.rb +13 -0
- data/lib/workato/testing/vcr_encrypted_cassette_serializer.rb +38 -0
- data/lib/workato/testing/vcr_multipart_body_matcher.rb +32 -0
- data/lib/workato-connector-sdk.rb +3 -0
- data/templates/.rspec.erb +3 -0
- data/templates/Gemfile.erb +10 -0
- data/templates/connector.rb.erb +37 -0
- data/templates/spec/action_spec.rb.erb +36 -0
- data/templates/spec/connector_spec.rb.erb +18 -0
- data/templates/spec/method_spec.rb.erb +13 -0
- data/templates/spec/object_definition_spec.rb.erb +18 -0
- data/templates/spec/pick_list_spec.rb.erb +13 -0
- data/templates/spec/spec_helper.rb.erb +38 -0
- data/templates/spec/trigger_spec.rb.erb +61 -0
- metadata +372 -0
@@ -0,0 +1,61 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Workato
|
4
|
+
module Connector
|
5
|
+
module Sdk
|
6
|
+
class Summarize
|
7
|
+
ARRAY_SUMMARIZATION_LIMIT = 100
|
8
|
+
STRING_SUMMARIZATION_LIMIT = 1024
|
9
|
+
|
10
|
+
def initialize(data:, paths:)
|
11
|
+
@paths = paths
|
12
|
+
@data = data
|
13
|
+
end
|
14
|
+
|
15
|
+
def call
|
16
|
+
return data if paths.blank?
|
17
|
+
|
18
|
+
summarized = data
|
19
|
+
paths.each do |path|
|
20
|
+
steps = path.split('.')
|
21
|
+
if above_summarization_limit?(summarized.dig(*steps))
|
22
|
+
summarized = data.deep_dup if summarized.equal?(data)
|
23
|
+
apply_summarization_limit(summarized, steps)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
summarized
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
attr_reader :data,
|
33
|
+
:paths
|
34
|
+
|
35
|
+
def above_summarization_limit?(candidate)
|
36
|
+
candidate.is_a?(::Array) && candidate.length > ARRAY_SUMMARIZATION_LIMIT ||
|
37
|
+
candidate.is_a?(::String) && candidate.length > STRING_SUMMARIZATION_LIMIT
|
38
|
+
end
|
39
|
+
|
40
|
+
def apply_summarization_limit(summarized, steps)
|
41
|
+
container = if steps.length > 1
|
42
|
+
summarized.dig(*steps[0..-2])
|
43
|
+
else
|
44
|
+
summarized
|
45
|
+
end
|
46
|
+
candidate = container[steps.last]
|
47
|
+
case candidate
|
48
|
+
when Array
|
49
|
+
candidate[(ARRAY_SUMMARIZATION_LIMIT - 2)..-2] =
|
50
|
+
"... #{candidate.length - ARRAY_SUMMARIZATION_LIMIT} items ..."
|
51
|
+
when String
|
52
|
+
candidate[(STRING_SUMMARIZATION_LIMIT - 1)..-1] =
|
53
|
+
"... #{candidate.length - STRING_SUMMARIZATION_LIMIT} characters ..."
|
54
|
+
else
|
55
|
+
candidate
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,96 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'securerandom'
|
4
|
+
|
5
|
+
module Workato
|
6
|
+
module Connector
|
7
|
+
module Sdk
|
8
|
+
class Trigger < Operation
|
9
|
+
using BlockInvocationRefinements
|
10
|
+
|
11
|
+
def initialize(trigger:, connection: {}, methods: {}, settings: {}, object_definitions: nil)
|
12
|
+
super(
|
13
|
+
operation: trigger,
|
14
|
+
connection: connection,
|
15
|
+
methods: methods,
|
16
|
+
settings: settings,
|
17
|
+
object_definitions: object_definitions
|
18
|
+
)
|
19
|
+
end
|
20
|
+
|
21
|
+
def poll_page(settings = nil, input = {}, closure = nil, extended_input_schema = [],
|
22
|
+
extended_output_schema = [])
|
23
|
+
poll_proc = trigger[:poll]
|
24
|
+
output = execute(
|
25
|
+
settings,
|
26
|
+
{ input: input, closure: closure },
|
27
|
+
extended_input_schema,
|
28
|
+
extended_output_schema
|
29
|
+
) do |connection, payload, eis, eos|
|
30
|
+
instance_exec(connection, payload[:input], payload[:closure], eis, eos, &poll_proc)
|
31
|
+
end
|
32
|
+
output[:events] = ::Array.wrap(output[:events]).reverse!.uniq(&trigger[:dedup])
|
33
|
+
output[:next_poll] = output[:next_poll].presence || closure
|
34
|
+
output
|
35
|
+
end
|
36
|
+
|
37
|
+
def poll(settings = nil, input = {}, closure = nil, extended_input_schema = [], extended_output_schema = [])
|
38
|
+
events = []
|
39
|
+
|
40
|
+
loop do
|
41
|
+
output = poll_page(settings, input, closure, extended_input_schema, extended_output_schema)
|
42
|
+
events = output[:events] + events
|
43
|
+
closure = output[:next_poll]
|
44
|
+
|
45
|
+
break unless output[:can_poll_more]
|
46
|
+
end
|
47
|
+
|
48
|
+
{
|
49
|
+
events: events.uniq(&trigger[:dedup]),
|
50
|
+
can_poll_more: false,
|
51
|
+
next_poll: closure
|
52
|
+
}.with_indifferent_access
|
53
|
+
end
|
54
|
+
|
55
|
+
def dedup(input = {})
|
56
|
+
trigger[:dedup].call(input)
|
57
|
+
end
|
58
|
+
|
59
|
+
def webhook_notification(input = {}, payload = {}, extended_input_schema = [],
|
60
|
+
extended_output_schema = [], headers = {}, params = {})
|
61
|
+
Dsl::WithDsl.execute(
|
62
|
+
input.with_indifferent_access,
|
63
|
+
payload.with_indifferent_access,
|
64
|
+
extended_input_schema.map(&:with_indifferent_access),
|
65
|
+
extended_output_schema.map(&:with_indifferent_access),
|
66
|
+
headers.with_indifferent_access,
|
67
|
+
params.with_indifferent_access,
|
68
|
+
&trigger[:webhook_notification]
|
69
|
+
)
|
70
|
+
end
|
71
|
+
|
72
|
+
def webhook_subscribe(webhook_url = '', settings = nil, input = {}, recipe_id = SecureRandom.uuid)
|
73
|
+
webhook_subscribe_proc = trigger[:webhook_subscribe]
|
74
|
+
execute(settings, { input: input, webhook_url: webhook_url, recipe_id: recipe_id }) do |connection, payload|
|
75
|
+
instance_exec(
|
76
|
+
payload[:webhook_url],
|
77
|
+
connection,
|
78
|
+
payload[:input],
|
79
|
+
payload[:recipe_id],
|
80
|
+
&webhook_subscribe_proc
|
81
|
+
)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def webhook_unsubscribe(webhook_subscribe_output = {})
|
86
|
+
webhook_unsubscribe_proc = trigger[:webhook_unsubscribe]
|
87
|
+
execute(nil, webhook_subscribe_output) do |_connection, input|
|
88
|
+
instance_exec(input, &webhook_unsubscribe_proc)
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
alias trigger operation
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'json'
|
4
|
+
|
5
|
+
module Workato
|
6
|
+
module Connector
|
7
|
+
module Sdk
|
8
|
+
class WorkatoSchemas
|
9
|
+
include Singleton
|
10
|
+
|
11
|
+
class << self
|
12
|
+
def from_json(path = DEFAULT_SCHEMAS_PATH)
|
13
|
+
load_data(JSON.parse(File.read(path)))
|
14
|
+
end
|
15
|
+
|
16
|
+
delegate :find,
|
17
|
+
:load_data,
|
18
|
+
to: :instance
|
19
|
+
end
|
20
|
+
|
21
|
+
def load_data(data)
|
22
|
+
@schemas_by_id ||= {}.with_indifferent_access
|
23
|
+
@schemas_by_id.merge!(data.stringify_keys)
|
24
|
+
end
|
25
|
+
|
26
|
+
def find(id)
|
27
|
+
unless @schemas_by_id
|
28
|
+
raise 'Workato Schemas are not initialized. ' \
|
29
|
+
'Init data by calling WorkatoSchemas.from_json or WorkatoSchemas.load_data'
|
30
|
+
end
|
31
|
+
|
32
|
+
@schemas_by_id.fetch(id.to_s)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'nokogiri'
|
4
|
+
|
5
|
+
module Workato
|
6
|
+
module Connector
|
7
|
+
module Sdk
|
8
|
+
module Xml
|
9
|
+
def self.parse_xml_to_hash(payload, strip_namespaces: false)
|
10
|
+
parse_options = Nokogiri::XML::ParseOptions.new.nonet
|
11
|
+
lazy_reader = Nokogiri::XML::Reader(payload, nil, nil, parse_options).to_enum.lazy
|
12
|
+
lazy_reader.each_with_object([{}]) do |node, ancestors|
|
13
|
+
ancestors.shift while ancestors.count > node.depth + 1
|
14
|
+
case node.node_type
|
15
|
+
when Nokogiri::XML::Reader::TYPE_ELEMENT
|
16
|
+
element = HashWithIndifferentAccess.new
|
17
|
+
node.attributes&.each do |name, value|
|
18
|
+
element["@#{strip_namespaces ? name[/(?:^xmlns:)?[^:]+$/] : name}"] = value
|
19
|
+
end
|
20
|
+
(ancestors.first[strip_namespaces ? node.name[/[^:]+$/] : node.name] ||= []).push(element)
|
21
|
+
ancestors.unshift(element)
|
22
|
+
when Nokogiri::XML::Reader::TYPE_TEXT, Nokogiri::XML::Reader::TYPE_CDATA
|
23
|
+
element = ancestors.first
|
24
|
+
if element.key?(:content!)
|
25
|
+
element[:content!] += node.value
|
26
|
+
else
|
27
|
+
element[:content!] = node.value
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end.last
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Workato
|
4
|
+
module Connector
|
5
|
+
module Sdk
|
6
|
+
DEFAULT_MASTER_KEY_ENV = 'WORKATO_CONNECTOR_MASTER_KEY'
|
7
|
+
DEFAULT_MASTER_KEY_PATH = 'master.key'
|
8
|
+
|
9
|
+
DEFAULT_CONNECTOR_PATH = 'connector.rb'
|
10
|
+
|
11
|
+
DEFAULT_SETTINGS_PATH = 'settings.yaml'
|
12
|
+
DEFAULT_ENCRYPTED_SETTINGS_PATH = 'settings.yaml.enc'
|
13
|
+
|
14
|
+
DEFAULT_ACCOUNT_PROPERTIES_PATH = 'account_properties.yaml'
|
15
|
+
DEFAULT_ENCRYPTED_ACCOUNT_PROPERTIES_PATH = 'account_properties.yaml.enc'
|
16
|
+
|
17
|
+
DEFAULT_LOOKUP_TABLES_PATH = 'lookup_tables.yaml'
|
18
|
+
|
19
|
+
DEFAULT_TIME_ZONE = 'Pacific Time (US & Canada)'
|
20
|
+
|
21
|
+
DEFAULT_SCHEMAS_PATH = 'workato_schemas.json'
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
# Global libs and monkey patches
|
27
|
+
require 'active_support/all'
|
28
|
+
require 'active_support/json'
|
29
|
+
require_relative '../extension/array'
|
30
|
+
require_relative '../extension/case_sensitive_headers'
|
31
|
+
require_relative '../extension/currency'
|
32
|
+
require_relative '../extension/date'
|
33
|
+
require_relative '../extension/enumerable'
|
34
|
+
require_relative '../extension/extra_chain_cert'
|
35
|
+
require_relative '../extension/hash'
|
36
|
+
require_relative '../extension/integer'
|
37
|
+
require_relative '../extension/nil_class'
|
38
|
+
require_relative '../extension/object'
|
39
|
+
require_relative '../extension/phone'
|
40
|
+
require_relative '../extension/string'
|
41
|
+
require_relative '../extension/symbol'
|
42
|
+
require_relative '../extension/time'
|
43
|
+
|
44
|
+
require_relative './sdk/account_properties'
|
45
|
+
require_relative './sdk/action'
|
46
|
+
require_relative './sdk/connector'
|
47
|
+
require_relative './sdk/dsl'
|
48
|
+
require_relative './sdk/errors'
|
49
|
+
require_relative './sdk/lookup_tables'
|
50
|
+
require_relative './sdk/object_definitions'
|
51
|
+
require_relative './sdk/operation'
|
52
|
+
require_relative './sdk/request'
|
53
|
+
require_relative './sdk/settings'
|
54
|
+
require_relative './sdk/summarize'
|
55
|
+
require_relative './sdk/trigger'
|
56
|
+
require_relative './sdk/version'
|
57
|
+
require_relative './sdk/workato_schemas'
|
58
|
+
require_relative './sdk/xml'
|
@@ -0,0 +1,124 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Workato
|
4
|
+
module Extension
|
5
|
+
module Array
|
6
|
+
def to_csv(options = {})
|
7
|
+
options ||= {}
|
8
|
+
multi_line = options[:multi_line]
|
9
|
+
multi_line = true if multi_line.nil?
|
10
|
+
options = options.dup
|
11
|
+
|
12
|
+
if multi_line && first.is_a?(::Array)
|
13
|
+
options[:multi_line] = false
|
14
|
+
map { |r| r.to_csv(options) }.join
|
15
|
+
else
|
16
|
+
options.delete(:multi_line)
|
17
|
+
super(options)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def ignored(*names)
|
22
|
+
reject { |field| names.include?(field[:name]) }
|
23
|
+
end
|
24
|
+
|
25
|
+
def only(*names)
|
26
|
+
select { |field| names.include?(field[:name]) }
|
27
|
+
end
|
28
|
+
|
29
|
+
def required(*names)
|
30
|
+
map { |field| names.include?(field[:name]) ? field.merge(optional: false) : field }
|
31
|
+
end
|
32
|
+
|
33
|
+
class ArrayWhere < SimpleDelegator
|
34
|
+
def initialize(list, options = {})
|
35
|
+
@_list = list
|
36
|
+
@_operations = []
|
37
|
+
@_resolved = false
|
38
|
+
where(options || {})
|
39
|
+
end
|
40
|
+
|
41
|
+
def where(options = {})
|
42
|
+
@_operations << [options] if options.present?
|
43
|
+
self
|
44
|
+
end
|
45
|
+
|
46
|
+
def not(options = {})
|
47
|
+
if options.present?
|
48
|
+
where(options)
|
49
|
+
@_operations.last << true
|
50
|
+
end
|
51
|
+
self
|
52
|
+
end
|
53
|
+
|
54
|
+
def self.parse_operation(key)
|
55
|
+
operation = key.to_s.match(/ *[><=!]={0,1} *\Z/)
|
56
|
+
stripped_key, operation = if operation.present?
|
57
|
+
[operation.pre_match, operation.to_s.strip]
|
58
|
+
else
|
59
|
+
[key.to_s, nil]
|
60
|
+
end
|
61
|
+
keys = stripped_key.split_strip_compact('.')
|
62
|
+
keys = keys.map(&:to_sym) if key.is_a?(::Symbol)
|
63
|
+
[keys, operation]
|
64
|
+
end
|
65
|
+
|
66
|
+
def self.coerce_operands(lhs_name, lhs, rhs, operation)
|
67
|
+
if operation == 'include?'
|
68
|
+
lhs, rhs = rhs, lhs
|
69
|
+
end
|
70
|
+
|
71
|
+
if operation.match?(/[><]/) || %w[match? include?].include?(operation)
|
72
|
+
raise "The '#{lhs_name}' is nil" if lhs.nil?
|
73
|
+
raise "Can't compare '#{lhs_name}' with nil" if rhs.nil?
|
74
|
+
end
|
75
|
+
|
76
|
+
if lhs.is_a?(::Numeric) && rhs.try(:is_number?)
|
77
|
+
rhs = rhs.is_int? ? rhs.to_i : rhs.to_f
|
78
|
+
elsif rhs.is_a?(::Numeric) && lhs.try(:is_number?)
|
79
|
+
lhs = lhs.is_int? ? lhs.to_i : lhs.to_f
|
80
|
+
end
|
81
|
+
[lhs, rhs]
|
82
|
+
end
|
83
|
+
|
84
|
+
def self.nested_attr(item, keys)
|
85
|
+
keys.reduce(item) do |obj, key|
|
86
|
+
obj[key] unless obj.nil?
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
def self.match?(operations, item)
|
91
|
+
operations.all? do |args, negate|
|
92
|
+
result = args.all? do |key, value|
|
93
|
+
keys, operation = parse_operation(key)
|
94
|
+
compared = nested_attr(item, keys)
|
95
|
+
if operation.blank?
|
96
|
+
operation = case value
|
97
|
+
when ::Array, Range
|
98
|
+
'include?'
|
99
|
+
when Regexp
|
100
|
+
'match?'
|
101
|
+
else
|
102
|
+
'=='
|
103
|
+
end
|
104
|
+
end
|
105
|
+
lhs, rhs = coerce_operands(keys.join('.'), compared, value, operation)
|
106
|
+
lhs.send(operation, rhs)
|
107
|
+
end
|
108
|
+
negate ? !result : result
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
def __getobj__
|
113
|
+
return super if @_resolved
|
114
|
+
|
115
|
+
filtered = @_list.select { |item| self.class.match?(@_operations, item) }
|
116
|
+
@_resolved = true
|
117
|
+
__setobj__(filtered)
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
Array.prepend(Workato::Extension::Array)
|
@@ -0,0 +1,51 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'rest-client'
|
4
|
+
require 'net/http'
|
5
|
+
|
6
|
+
module Workato
|
7
|
+
module Extension
|
8
|
+
module CaseSensitiveHeaders
|
9
|
+
module Net
|
10
|
+
module HTTPHeader
|
11
|
+
attr_accessor :case_sensitive_headers
|
12
|
+
|
13
|
+
def capitalize(modified_name)
|
14
|
+
return super if case_sensitive_headers.blank?
|
15
|
+
|
16
|
+
original_name = case_sensitive_headers.keys.find { |name| name.downcase == modified_name }
|
17
|
+
original_name.presence || super
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
::Net::HTTPHeader.prepend Net::HTTPHeader
|
23
|
+
::Net::HTTPGenericRequest.prepend Net::HTTPHeader
|
24
|
+
|
25
|
+
module RestClient
|
26
|
+
module Request
|
27
|
+
attr_accessor :case_sensitive_headers
|
28
|
+
|
29
|
+
def processed_headers
|
30
|
+
return @processed_headers if case_sensitive_headers.blank?
|
31
|
+
return case_sensitive_headers if @processed_headers.blank?
|
32
|
+
|
33
|
+
@processed_headers.merge(case_sensitive_headers)
|
34
|
+
end
|
35
|
+
|
36
|
+
def execute(&block)
|
37
|
+
# With 2.0.0+, net/http accepts URI objects in requests and handles wrapping
|
38
|
+
# IPv6 addresses in [] for use in the Host request header.
|
39
|
+
net_http_request = net_http_request_class(method).new(uri, processed_headers)
|
40
|
+
net_http_request.case_sensitive_headers = case_sensitive_headers
|
41
|
+
transmit(uri, net_http_request, payload, &block)
|
42
|
+
ensure
|
43
|
+
payload&.close
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
::RestClient::Request.prepend RestClient::Request
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|