-
Notifications
You must be signed in to change notification settings - Fork 54
Expand file tree
/
Copy pathutil.rb
More file actions
169 lines (145 loc) · 5.11 KB
/
util.rb
File metadata and controls
169 lines (145 loc) · 5.11 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
require "uri"
require "http"
module LaunchDarkly
module Impl
module Util
def self.bool?(aObject)
[true,false].include? aObject
end
def self.current_time_millis
(Time.now.to_f * 1000).to_i
end
def self.default_http_headers(sdk_key, config)
ret = { "Authorization" => sdk_key, "User-Agent" => "RubyClient/" + LaunchDarkly::VERSION }
ret["X-LaunchDarkly-Instance-Id"] = config.instance_id unless config.instance_id.nil?
if config.wrapper_name
ret["X-LaunchDarkly-Wrapper"] = config.wrapper_name +
(config.wrapper_version ? "/" + config.wrapper_version : "")
end
app_value = application_header_value config.application
ret["X-LaunchDarkly-Tags"] = app_value unless app_value.nil? || app_value.empty?
ret
end
#
# Generate an HTTP Header value containing the application meta information (@see #application).
#
# @return [String]
#
def self.application_header_value(application)
parts = []
unless application[:id].empty?
parts << "application-id/#{application[:id]}"
end
unless application[:version].empty?
parts << "application-version/#{application[:version]}"
end
parts.join(" ")
end
#
# @param value [String]
# @param name [Symbol]
# @param logger [Logger]
# @return [String]
#
def self.validate_application_value(value, name, logger)
value = value.to_s
return "" if value.empty?
if value.length > 64
logger.warn { "Value of application[#{name}] was longer than 64 characters and was discarded" }
return ""
end
if /[^a-zA-Z0-9._-]/.match?(value)
logger.warn { "Value of application[#{name}] contained invalid characters and was discarded" }
return ""
end
value
end
#
# @param app [Hash]
# @param logger [Logger]
# @return [Hash]
#
def self.validate_application_info(app, logger)
{
id: validate_application_value(app[:id], :id, logger),
version: validate_application_value(app[:version], :version, logger),
}
end
#
# @param value [String, nil]
# @param logger [Logger]
# @return [String, nil]
#
def self.validate_payload_filter_key(value, logger)
return nil if value.nil?
return value if value.is_a?(String) && /^[a-zA-Z0-9][._\-a-zA-Z0-9]*$/.match?(value)
logger.warn {
"Invalid payload filter configured, full environment will be fetched. Ensure the filter key is not empty and was copied correctly from LaunchDarkly settings."
}
nil
end
#
# Append the payload filter key query parameter to the provided URI.
#
# @param uri [String]
# @param config [Config]
# @return [String]
#
def self.add_payload_filter_key(uri, config)
return uri if config.payload_filter_key.nil?
begin
parsed = URI.parse(uri)
new_query_params = URI.decode_www_form(String(parsed.query)) << ["filter", config.payload_filter_key]
parsed.query = URI.encode_www_form(new_query_params)
parsed.to_s
rescue URI::InvalidURIError
config.logger.warn { "[LDClient] URI could not be parsed. No filtering will be applied." }
uri
end
end
#
# Creates a new persistent HTTP client with the given configuration.
#
# @param http_config [LaunchDarkly::Impl::DataSystem::HttpConfigOptions] HTTP connection settings
# @return [HTTP::Client]
#
def self.new_http_client(http_config)
http_client_options = {}
if http_config.socket_factory
http_client_options[:socket_class] = http_config.socket_factory
end
proxy = URI.parse(http_config.base_uri).find_proxy
unless proxy.nil?
http_client_options[:proxy] = {
proxy_address: proxy.host,
proxy_port: proxy.port,
proxy_username: proxy.user,
proxy_password: proxy.password,
}
end
HTTP::Client.new(**http_client_options)
.timeout(
read: http_config.read_timeout,
connect: http_config.connect_timeout
)
.persistent(http_config.base_uri)
end
def self.log_exception(logger, message, exc)
logger.error { "[LDClient] #{message}: #{exc.inspect}" }
logger.debug { "[LDClient] Exception trace: #{exc.backtrace}" }
end
def self.http_error_recoverable?(status)
if status >= 400 && status < 500
status == 400 || status == 408 || status == 429
else
true
end
end
def self.http_error_message(status, context, recoverable_message)
desc = (status == 401 || status == 403) ? " (invalid SDK key)" : ""
message = http_error_recoverable?(status) ? recoverable_message : "giving up permanently"
"HTTP error #{status}#{desc} for #{context} - #{message}"
end
end
end
end