From aaf222f256949222a4c357f6360493ed94b88f15 Mon Sep 17 00:00:00 2001 From: Brandon Keepers Date: Mon, 4 Dec 2023 16:14:44 -0500 Subject: [PATCH 1/3] Include client framework versions in API requests --- lib/flipper/adapters/http/client.rb | 15 +++++++++++++ spec/flipper/adapters/http_spec.rb | 34 +++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+) diff --git a/lib/flipper/adapters/http/client.rb b/lib/flipper/adapters/http/client.rb index c1ecc4bde..a333cdf2c 100644 --- a/lib/flipper/adapters/http/client.rb +++ b/lib/flipper/adapters/http/client.rb @@ -14,6 +14,12 @@ class Client HTTPS_SCHEME = "https".freeze + CLIENT_FRAMEWORKS = { + rails: -> { Rails.version if defined?(Rails) }, + sinatra: -> { Sinatra::VERSION if defined?(Sinatra) }, + hanami: -> { Hanami::VERSION if defined?(Hanami) }, + } + attr_reader :uri, :headers attr_reader :basic_auth_username, :basic_auth_password attr_reader :read_timeout, :open_timeout, :write_timeout, :max_retries, :debug_output @@ -93,6 +99,11 @@ def build_request(http_method, uri, headers, options) body = options[:body] request = http_method.new(uri.request_uri) request.initialize_http_header(request_headers) + + client_frameworks.each do |framework, version| + request.add_field("Client-Framework", [framework, version].join("=")) + end + request.body = body if body if @basic_auth_username && @basic_auth_password @@ -101,6 +112,10 @@ def build_request(http_method, uri, headers, options) request end + + def client_frameworks + CLIENT_FRAMEWORKS.transform_values(&:call).select { |_, version| version } + end end end end diff --git a/spec/flipper/adapters/http_spec.rb b/spec/flipper/adapters/http_spec.rb index 71addd929..7dbb1828a 100644 --- a/spec/flipper/adapters/http_spec.rb +++ b/spec/flipper/adapters/http_spec.rb @@ -90,6 +90,40 @@ adapter.get(flipper[:feature_panel]) end + it "sends framework versions" do + stub_const("Rails", Struct.new(:version).new("7.1.0")) + stub_const("Sinatra::VERSION", "3.1.0") + stub_const("Hanami::VERSION", "0.7.2") + + headers = { + "Client-Framework" => ["rails=7.1.0", "sinatra=3.1.0", "hanami=0.7.2"] + } + + stub_request(:get, "http://app.com/flipper/features/feature_panel") + .with(headers: headers) + .to_return(status: 404, body: "", headers: {}) + + adapter = described_class.new(url: 'http://app.com/flipper') + adapter.get(flipper[:feature_panel]) + end + + it "does not send undefined framework versions" do + stub_const("Rails", Struct.new(:version).new("7.1.0")) + stub_const("Sinatra::VERSION", "3.1.0") + + headers = { + "Client-Framework" => ["rails=7.1.0", "sinatra=3.1.0"] + } + + stub_request(:get, "http://app.com/flipper/features/feature_panel") + .with(headers: headers) + .to_return(status: 404, body: "", headers: {}) + + adapter = described_class.new(url: 'http://app.com/flipper') + adapter.get(flipper[:feature_panel]) + end + + describe "#get" do it "raises error when not successful response" do stub_request(:get, "http://app.com/flipper/features/feature_panel") From 774d975246e359299a5fed34178ad326af4e1fc1 Mon Sep 17 00:00:00 2001 From: Brandon Keepers Date: Mon, 4 Dec 2023 16:34:22 -0500 Subject: [PATCH 2/3] Fix telemetry error by using webmock headers matcher --- spec/flipper/cloud/telemetry/submitter_spec.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/flipper/cloud/telemetry/submitter_spec.rb b/spec/flipper/cloud/telemetry/submitter_spec.rb index d6ce8c518..5f3f4fbf5 100644 --- a/spec/flipper/cloud/telemetry/submitter_spec.rb +++ b/spec/flipper/cloud/telemetry/submitter_spec.rb @@ -58,10 +58,10 @@ 'User-Agent' => "Flipper HTTP Adapter v#{Flipper::VERSION}", } stub_request(:post, "https://www.flippercloud.io/adapter/telemetry"). - with { |request| + with(headers: expected_headers) { |request| gunzipped = Flipper::Typecast.from_gzip(request.body) body = Flipper::Typecast.from_json(gunzipped) - body == expected_body && request.headers == expected_headers + body == expected_body }.to_return(status: 200, body: "{}", headers: {}) subject.call(enabled_metrics) end From b7c7043012c9a7d9a57f0e448040ebc79fed7e05 Mon Sep 17 00:00:00 2001 From: Brandon Keepers Date: Mon, 4 Dec 2023 16:36:41 -0500 Subject: [PATCH 3/3] Rescue framework detection to ensure it never breaks --- lib/flipper/adapters/http/client.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/flipper/adapters/http/client.rb b/lib/flipper/adapters/http/client.rb index a333cdf2c..cb8d5a872 100644 --- a/lib/flipper/adapters/http/client.rb +++ b/lib/flipper/adapters/http/client.rb @@ -114,7 +114,7 @@ def build_request(http_method, uri, headers, options) end def client_frameworks - CLIENT_FRAMEWORKS.transform_values(&:call).select { |_, version| version } + CLIENT_FRAMEWORKS.transform_values { |detect| detect.call rescue nil }.select { |_, version| version } end end end