Skip to content
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ def fetch_ssl_verify_mode
end

def http_connection(uri, ssl_verify_mode, certificate_file, client_certificate_file, client_key_file)
http = Net::HTTP.new(uri.host, uri.port)
http = Net::HTTP.new(uri.hostname, uri.port)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for opening this PR, @chen-anders! I appreciate the Reviewer's note. The tests look good to me, but I think we should add them to the other libraries getting the IPv6 compatible hostname too. Could you update the tests in otlp-http, otlp-logs and otlp-metrics too?

http.use_ssl = uri.scheme == 'https'
http.verify_mode = ssl_verify_mode
http.ca_file = certificate_file unless certificate_file.nil?
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ def handle_http_error(response)
end

def http_connection(uri, ssl_verify_mode, certificate_file, client_certificate_file, client_key_file)
http = Net::HTTP.new(uri.host, uri.port)
http = Net::HTTP.new(uri.hostname, uri.port)
http.use_ssl = uri.scheme == 'https'
http.verify_mode = ssl_verify_mode
http.ca_file = certificate_file unless certificate_file.nil?
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ module Util # rubocop:disable Metrics/ModuleLength
DEFAULT_USER_AGENT = "OTel-OTLP-MetricsExporter-Ruby/#{OpenTelemetry::Exporter::OTLP::Metrics::VERSION} Ruby/#{RUBY_VERSION} (#{RUBY_PLATFORM}; #{RUBY_ENGINE}/#{RUBY_ENGINE_VERSION})".freeze

def http_connection(uri, ssl_verify_mode, certificate_file, client_certificate_file, client_key_file)
http = Net::HTTP.new(uri.host, uri.port)
http = Net::HTTP.new(uri.hostname, uri.port)
http.use_ssl = uri.scheme == 'https'
http.verify_mode = ssl_verify_mode
http.ca_file = certificate_file unless certificate_file.nil?
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ def build_span_flags(parent_span_is_remote, base_flags)
end

def http_connection(uri, ssl_verify_mode, certificate_file, client_certificate_file, client_key_file)
http = Net::HTTP.new(uri.host, uri.port)
http = Net::HTTP.new(uri.hostname, uri.port)
http.use_ssl = uri.scheme == 'https'
http.verify_mode = ssl_verify_mode
http.ca_file = certificate_file unless certificate_file.nil?
Expand Down
142 changes: 142 additions & 0 deletions exporter/otlp/test/opentelemetry/exporter/otlp/exporter_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -357,6 +357,148 @@
end
end

describe 'IPv4/IPv6 compatibility' do
it 'handles IPv6 loopback address with brackets' do
exp = OpenTelemetry::Exporter::OTLP::Exporter.new(endpoint: 'http://[::1]:4318/v1/traces')
http = exp.instance_variable_get(:@http)
_(http.address).must_equal '::1'
_(http.port).must_equal 4318
_(exp.instance_variable_get(:@path)).must_equal '/v1/traces'
end

it 'handles IPv6 full address with brackets' do
exp = OpenTelemetry::Exporter::OTLP::Exporter.new(endpoint: 'http://[2001:db8::1]:4318/v1/traces')
http = exp.instance_variable_get(:@http)
_(http.address).must_equal '2001:db8::1'
_(http.port).must_equal 4318
end

it 'handles IPv6 address with https' do
exp = OpenTelemetry::Exporter::OTLP::Exporter.new(endpoint: 'https://[::1]:4318/v1/traces')
http = exp.instance_variable_get(:@http)
_(http.address).must_equal '::1'
_(http.port).must_equal 4318
_(http.use_ssl?).must_equal true
end

it 'handles IPv6 address with custom path' do
exp = OpenTelemetry::Exporter::OTLP::Exporter.new(endpoint: 'http://[::1]:8080/custom/path')
http = exp.instance_variable_get(:@http)
_(http.address).must_equal '::1'
_(http.port).must_equal 8080
_(exp.instance_variable_get(:@path)).must_equal '/custom/path'
end

it 'handles IPv4 loopback address' do
exp = OpenTelemetry::Exporter::OTLP::Exporter.new(endpoint: 'http://127.0.0.1:4318/v1/traces')
http = exp.instance_variable_get(:@http)
_(http.address).must_equal '127.0.0.1'
_(http.port).must_equal 4318
_(exp.instance_variable_get(:@path)).must_equal '/v1/traces'
end

it 'handles IPv4 address with custom port' do
exp = OpenTelemetry::Exporter::OTLP::Exporter.new(endpoint: 'http://192.168.1.100:8080/v1/traces')
http = exp.instance_variable_get(:@http)
_(http.address).must_equal '192.168.1.100'
_(http.port).must_equal 8080
end

it 'handles IPv4 address with https' do
exp = OpenTelemetry::Exporter::OTLP::Exporter.new(endpoint: 'https://10.0.0.1:4318/v1/traces')
http = exp.instance_variable_get(:@http)
_(http.address).must_equal '10.0.0.1'
_(http.port).must_equal 4318
_(http.use_ssl?).must_equal true
end

it 'handles IPv4 address with custom path' do
exp = OpenTelemetry::Exporter::OTLP::Exporter.new(endpoint: 'http://127.0.0.1:9090/custom/path')
http = exp.instance_variable_get(:@http)
_(http.address).must_equal '127.0.0.1'
_(http.port).must_equal 9090
_(exp.instance_variable_get(:@path)).must_equal '/custom/path'
end

it 'handles IPv4 address from environment variable' do
exp = OpenTelemetry::TestHelpers.with_env('OTEL_EXPORTER_OTLP_ENDPOINT' => 'http://192.168.1.1:4318') do
OpenTelemetry::Exporter::OTLP::Exporter.new
end
http = exp.instance_variable_get(:@http)
_(http.address).must_equal '192.168.1.1'
_(http.port).must_equal 4318
_(exp.instance_variable_get(:@path)).must_equal '/v1/traces'
end

it 'handles hostnames' do
exp = OpenTelemetry::Exporter::OTLP::Exporter.new(endpoint: 'http://localhost:4318/v1/traces')
http = exp.instance_variable_get(:@http)
_(http.address).must_equal 'localhost'
_(http.port).must_equal 4318
end

it 'handles fully qualified domain names' do
exp = OpenTelemetry::Exporter::OTLP::Exporter.new(endpoint: 'http://otel.example.com:4318/v1/traces')
http = exp.instance_variable_get(:@http)
_(http.address).must_equal 'otel.example.com'
_(http.port).must_equal 4318
end

it 'handles hostnames with https' do
exp = OpenTelemetry::Exporter::OTLP::Exporter.new(endpoint: 'https://otel-collector.prod.example.com:443/v1/traces')
http = exp.instance_variable_get(:@http)
_(http.address).must_equal 'otel-collector.prod.example.com'
_(http.port).must_equal 443
_(http.use_ssl?).must_equal true
end

it 'handles IPv6 address from environment variable' do
exp = OpenTelemetry::TestHelpers.with_env('OTEL_EXPORTER_OTLP_ENDPOINT' => 'http://[::1]:4318') do
OpenTelemetry::Exporter::OTLP::Exporter.new
end
http = exp.instance_variable_get(:@http)
_(http.address).must_equal '::1'
_(http.port).must_equal 4318
_(exp.instance_variable_get(:@path)).must_equal '/v1/traces'
end

it 'exports span data with IPv6 address' do
stub_request(:post, 'http://[::1]:4318/v1/traces').to_return(status: 200)
exp = OpenTelemetry::Exporter::OTLP::Exporter.new(endpoint: 'http://[::1]:4318/v1/traces')
span_data = OpenTelemetry::TestHelpers.create_span_data
result = exp.export([span_data])
_(result).must_equal(SUCCESS)
end

it 'exports span data with IPv4 address' do
stub_request(:post, 'http://127.0.0.1:4318/v1/traces').to_return(status: 200)
exp = OpenTelemetry::Exporter::OTLP::Exporter.new(endpoint: 'http://127.0.0.1:4318/v1/traces')
span_data = OpenTelemetry::TestHelpers.create_span_data
result = exp.export([span_data])
_(result).must_equal(SUCCESS)
end

it 'exports span data with IPv6 address via full URL' do
stub_request(:post, 'http://[2001:db8::8a2e:370:7334]:4318/v1/traces').to_return(status: 200)
exp = OpenTelemetry::Exporter::OTLP::Exporter.new(endpoint: 'http://[2001:db8::8a2e:370:7334]:4318/v1/traces')
span_data = OpenTelemetry::TestHelpers.create_span_data
result = exp.export([span_data])
_(result).must_equal(SUCCESS)
end

it 'handles connection errors with IPv6 address gracefully' do
stub_request(:post, 'http://[::1]:4318/v1/traces').to_raise(SocketError.new('getaddrinfo: nodename nor servname provided, or not known'))
exp = OpenTelemetry::Exporter::OTLP::Exporter.new(endpoint: 'http://[::1]:4318/v1/traces')
span_data = OpenTelemetry::TestHelpers.create_span_data

# Mock backoff to prevent retries
exp.stub(:backoff?, ->(**_) { false }) do
result = exp.export([span_data])
_(result).must_equal(FAILURE)
end
end
end

describe 'ssl_verify_mode:' do
it 'can be set to VERIFY_NONE by an envvar' do
exp = OpenTelemetry::TestHelpers.with_env('OTEL_RUBY_EXPORTER_OTLP_SSL_VERIFY_NONE' => 'true') do
Expand Down
Loading