Skip to content

Commit 0456edb

Browse files
authored
Add source field to user-agent header (stripe#1874)
1 parent c40f8c1 commit 0456edb

2 files changed

Lines changed: 57 additions & 1 deletion

File tree

lib/stripe/api_requestor.rb

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
# frozen_string_literal: true
22

3+
require "digest"
4+
require "socket"
35
require "stripe/instrumentation"
46

57
module Stripe
@@ -1066,6 +1068,31 @@ def dup_from_response_headers(headers)
10661068
# in so that we can generate a rich user agent header to help debug
10671069
# integrations.
10681070
class SystemProfiler
1071+
UNAME_HASH = begin
1072+
parts = []
1073+
parts << if RUBY_PLATFORM.match?(/mswin|mingw|cygwin/)
1074+
begin
1075+
`ver 2>NUL`.strip
1076+
rescue StandardError
1077+
""
1078+
end
1079+
else
1080+
begin
1081+
`uname -a 2>/dev/null`.strip
1082+
rescue StandardError
1083+
""
1084+
end
1085+
end
1086+
parts << begin
1087+
Socket.gethostname
1088+
rescue StandardError
1089+
""
1090+
end
1091+
Digest::MD5.hexdigest(parts.join(" "))
1092+
rescue StandardError
1093+
""
1094+
end
1095+
10691096
AI_AGENTS = [
10701097
# aiAgents: The beginning of the section generated from our OpenAPI spec
10711098
%w[ANTIGRAVITY_CLI_ALIAS antigravity],
@@ -1101,7 +1128,10 @@ def self.user_agent
11011128
engine: defined?(RUBY_ENGINE) ? RUBY_ENGINE : "",
11021129
}.delete_if { |_k, v| v.nil? }
11031130

1104-
ua[:platform] = RUBY_PLATFORM if Stripe.enable_telemetry?
1131+
if Stripe.enable_telemetry?
1132+
ua[:platform] = RUBY_PLATFORM
1133+
ua[:source] = UNAME_HASH unless UNAME_HASH.empty?
1134+
end
11051135

11061136
ai_agent = detect_ai_agent
11071137
ua[:ai_agent] = ai_agent unless ai_agent.empty?

test/stripe/api_requestor_test.rb

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1799,6 +1799,32 @@ class SystemProfilerTest < Test::Unit::TestCase
17991799
ensure
18001800
Stripe.enable_telemetry = false
18011801
end
1802+
1803+
should "omit source when UNAME_HASH is empty" do
1804+
original = APIRequestor::SystemProfiler::UNAME_HASH
1805+
APIRequestor::SystemProfiler.send(:remove_const, :UNAME_HASH)
1806+
APIRequestor::SystemProfiler.const_set(:UNAME_HASH, "")
1807+
Stripe.enable_telemetry = true
1808+
ua = APIRequestor::SystemProfiler.user_agent
1809+
refute ua.key?(:source)
1810+
ensure
1811+
APIRequestor::SystemProfiler.send(:remove_const, :UNAME_HASH)
1812+
APIRequestor::SystemProfiler.const_set(:UNAME_HASH, original)
1813+
Stripe.enable_telemetry = false
1814+
end
1815+
1816+
should "include source when UNAME_HASH is non-empty" do
1817+
original = APIRequestor::SystemProfiler::UNAME_HASH
1818+
APIRequestor::SystemProfiler.send(:remove_const, :UNAME_HASH)
1819+
APIRequestor::SystemProfiler.const_set(:UNAME_HASH, "abc123")
1820+
Stripe.enable_telemetry = true
1821+
ua = APIRequestor::SystemProfiler.user_agent
1822+
assert_equal "abc123", ua[:source]
1823+
ensure
1824+
APIRequestor::SystemProfiler.send(:remove_const, :UNAME_HASH)
1825+
APIRequestor::SystemProfiler.const_set(:UNAME_HASH, original)
1826+
Stripe.enable_telemetry = false
1827+
end
18021828
end
18031829

18041830
context ".detect_ai_agent" do

0 commit comments

Comments
 (0)