optimizely-sdk 3.5.0.pre.beta → 3.5.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 033cd0357752fc0d52193944412f2a3029924e3ffdc650848924fe9d9a9ce6ee
4
- data.tar.gz: 4e7949391d0a41b832c21f8835158345966edf63949256c15436321683927678
3
+ metadata.gz: c89ea6be1aa10ab05c2d47e74ebe054987e6fc0e08b85417a63b579d80f2fac4
4
+ data.tar.gz: 1f35f5d10017780db25f46e270d64010d0dc5e245bd4b183ae1da8ee1dfb060d
5
5
  SHA512:
6
- metadata.gz: 79a434d80add6804f3722dc4d616d2533f263601a80a41d357ac1766d099f79eae6a6429eb945a198a0689ce6e2525fd6f44d2b308a1e7a0d470fe184d89e28b
7
- data.tar.gz: 73735c47d0e2ed58a26de0b7a8fb25d8167f45e1f4535aeb90f4fe95fb0fd5733dbcf614efe4d4d8af4ee0b3d5080953224c2f2a8fee80380e521a97c1a310e8
6
+ metadata.gz: d2fd93c8952496d3feb12ec4dd8fb8ced95f7123a94447b646b14e157cdaf82af65adfc193943a6efc7ff77069d4600d5006728c876f9ff0d06d9116ad2c58a1
7
+ data.tar.gz: a5ffc4c7db14a01e4bc7741eca6c636b6f41e755a7256fae64703e5241bd6ade20190c8f0b83bdc37d7cb18277439659ce09faa68388c7e74db2d6d3463d470a
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright 2020, Optimizely and contributors
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+ #
17
+ #
18
+
19
+ module Optimizely
20
+ class ProxyConfig
21
+ attr_reader :host, :port, :username, :password
22
+
23
+ def initialize(host, port = nil, username = nil, password = nil)
24
+ # host - DNS name or IP address of proxy
25
+ # port - port to use to acess the proxy
26
+ # username - username if authorization is required
27
+ # password - password if authorization is required
28
+ @host = host
29
+ @port = port
30
+ @username = username
31
+ @password = password
32
+ end
33
+ end
34
+ end
@@ -52,6 +52,7 @@ module Optimizely
52
52
  # skip_json_validation - Optional boolean param which allows skipping JSON schema
53
53
  # validation upon object invocation. By default JSON schema validation will be performed.
54
54
  # datafile_access_token - access token used to fetch private datafiles
55
+ # proxy_config - Optional proxy config instancea to configure making web requests through a proxy server.
55
56
  def initialize(
56
57
  sdk_key: nil,
57
58
  url: nil,
@@ -65,7 +66,8 @@ module Optimizely
65
66
  error_handler: nil,
66
67
  skip_json_validation: false,
67
68
  notification_center: nil,
68
- datafile_access_token: nil
69
+ datafile_access_token: nil,
70
+ proxy_config: nil
69
71
  )
70
72
  @logger = logger || NoOpLogger.new
71
73
  @error_handler = error_handler || NoOpErrorHandler.new
@@ -86,6 +88,7 @@ module Optimizely
86
88
  # Start async scheduler in the end to avoid race condition where scheduler executes
87
89
  # callback which makes use of variables not yet initialized by the main thread.
88
90
  @async_scheduler.start! if start_by_default == true
91
+ @proxy_config = proxy_config
89
92
  @stopped = false
90
93
  end
91
94
 
@@ -148,18 +151,20 @@ module Optimizely
148
151
  end
149
152
 
150
153
  def request_config
151
- @logger.log(
152
- Logger::DEBUG,
153
- "Fetching datafile from #{@datafile_url}"
154
- )
155
- begin
156
- headers = {}
157
- headers['Content-Type'] = 'application/json'
158
- headers['If-Modified-Since'] = @last_modified if @last_modified
159
- headers['Authorization'] = "Bearer #{@access_token}" unless @access_token.nil?
154
+ @logger.log(Logger::DEBUG, "Fetching datafile from #{@datafile_url}")
155
+ headers = {}
156
+ headers['Content-Type'] = 'application/json'
157
+ headers['If-Modified-Since'] = @last_modified if @last_modified
158
+ headers['Authorization'] = "Bearer #{@access_token}" unless @access_token.nil?
159
+
160
+ # Cleaning headers before logging to avoid exposing authorization token
161
+ cleansed_headers = {}
162
+ headers.each { |key, value| cleansed_headers[key] = key == 'Authorization' ? '********' : value }
163
+ @logger.log(Logger::DEBUG, "Datafile request headers: #{cleansed_headers}")
160
164
 
165
+ begin
161
166
  response = Helpers::HttpUtils.make_request(
162
- @datafile_url, :get, nil, headers, Helpers::Constants::CONFIG_MANAGER['REQUEST_TIMEOUT']
167
+ @datafile_url, :get, nil, headers, Helpers::Constants::CONFIG_MANAGER['REQUEST_TIMEOUT'], @proxy_config
163
168
  )
164
169
  rescue StandardError => e
165
170
  @logger.log(
@@ -169,6 +174,9 @@ module Optimizely
169
174
  return nil
170
175
  end
171
176
 
177
+ response_code = response.code.to_i
178
+ @logger.log(Logger::DEBUG, "Datafile response status code #{response_code}")
179
+
172
180
  # Leave datafile and config unchanged if it has not been modified.
173
181
  if response.code == '304'
174
182
  @logger.log(
@@ -178,9 +186,14 @@ module Optimizely
178
186
  return
179
187
  end
180
188
 
181
- @last_modified = response[Helpers::Constants::HTTP_HEADERS['LAST_MODIFIED']]
182
-
183
- config = DatafileProjectConfig.create(response.body, @logger, @error_handler, @skip_json_validation) if response.body
189
+ if response_code >= 200 && response_code < 400
190
+ @logger.log(Logger::DEBUG, 'Successfully fetched datafile, generating Project config')
191
+ config = DatafileProjectConfig.create(response.body, @logger, @error_handler, @skip_json_validation)
192
+ @last_modified = response[Helpers::Constants::HTTP_HEADERS['LAST_MODIFIED']]
193
+ @logger.log(Logger::DEBUG, "Saved last modified header value from response: #{@last_modified}.")
194
+ else
195
+ @logger.log(Logger::DEBUG, "Datafile fetch failed, status: #{response.code}, message: #{response.message}")
196
+ end
184
197
 
185
198
  config
186
199
  end
@@ -29,9 +29,10 @@ module Optimizely
29
29
  # @api constants
30
30
  REQUEST_TIMEOUT = 10
31
31
 
32
- def initialize(logger: nil, error_handler: nil)
32
+ def initialize(logger: nil, error_handler: nil, proxy_config: nil)
33
33
  @logger = logger || NoOpLogger.new
34
34
  @error_handler = error_handler || NoOpErrorHandler.new
35
+ @proxy_config = proxy_config
35
36
  end
36
37
 
37
38
  # Dispatch the event being represented by the Event object.
@@ -39,7 +40,7 @@ module Optimizely
39
40
  # @param event - Event object
40
41
  def dispatch_event(event)
41
42
  response = Helpers::HttpUtils.make_request(
42
- event.url, event.http_verb, event.params.to_json, event.headers, REQUEST_TIMEOUT
43
+ event.url, event.http_verb, event.params.to_json, event.headers, REQUEST_TIMEOUT, @proxy_config
43
44
  )
44
45
 
45
46
  error_msg = "Event failed to dispatch with response code: #{response.code}"
@@ -23,14 +23,10 @@ module Optimizely
23
23
  module HttpUtils
24
24
  module_function
25
25
 
26
- def make_request(url, http_method, request_body = nil, headers = {}, read_timeout = nil)
26
+ def make_request(url, http_method, request_body = nil, headers = {}, read_timeout = nil, proxy_config = nil)
27
27
  # makes http/https GET/POST request and returns response
28
-
28
+ #
29
29
  uri = URI.parse(url)
30
- http = Net::HTTP.new(uri.host, uri.port)
31
-
32
- http.read_timeout = read_timeout if read_timeout
33
- http.use_ssl = uri.scheme == 'https'
34
30
 
35
31
  if http_method == :get
36
32
  request = Net::HTTP::Get.new(uri.request_uri)
@@ -46,6 +42,21 @@ module Optimizely
46
42
  request[key] = val
47
43
  end
48
44
 
45
+ # do not try to make request with proxy unless we have at least a host
46
+ http_class = if proxy_config&.host
47
+ Net::HTTP::Proxy(
48
+ proxy_config.host,
49
+ proxy_config.port,
50
+ proxy_config.username,
51
+ proxy_config.password
52
+ )
53
+ else
54
+ Net::HTTP
55
+ end
56
+
57
+ http = http_class.new(uri.host, uri.port)
58
+ http.read_timeout = read_timeout if read_timeout
59
+ http.use_ssl = uri.scheme == 'https'
49
60
  http.request(request)
50
61
  end
51
62
  end
@@ -17,5 +17,5 @@
17
17
  #
18
18
  module Optimizely
19
19
  CLIENT_ENGINE = 'ruby-sdk'
20
- VERSION = '3.5.0-beta'
20
+ VERSION = '3.5.0'
21
21
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: optimizely-sdk
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.5.0.pre.beta
4
+ version: 3.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Optimizely
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-06-17 00:00:00.000000000 Z
11
+ date: 2020-07-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -135,6 +135,7 @@ files:
135
135
  - lib/optimizely/bucketer.rb
136
136
  - lib/optimizely/condition_tree_evaluator.rb
137
137
  - lib/optimizely/config/datafile_project_config.rb
138
+ - lib/optimizely/config/proxy_config.rb
138
139
  - lib/optimizely/config_manager/async_scheduler.rb
139
140
  - lib/optimizely/config_manager/http_project_config_manager.rb
140
141
  - lib/optimizely/config_manager/project_config_manager.rb
@@ -190,9 +191,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
190
191
  version: '0'
191
192
  required_rubygems_version: !ruby/object:Gem::Requirement
192
193
  requirements:
193
- - - ">"
194
+ - - ">="
194
195
  - !ruby/object:Gem::Version
195
- version: 1.3.1
196
+ version: '0'
196
197
  requirements: []
197
198
  rubygems_version: 3.0.3
198
199
  signing_key: