From b36ca9f9d02e27e8febe3cd76aa46e8de57b0b9d Mon Sep 17 00:00:00 2001 From: Yuri Smirnov Date: Sat, 19 Sep 2026 10:37:35 +0300 Subject: [PATCH] Omit the default port from the logged URL The Net::HTTP adapter always spelled the port out, so an ordinary HTTPS request was logged as https://example.com:443/path. That is not the URL anyone writes by hand, so grepping the log for the URL a gateway uses finds nothing, and the line cannot be pasted into curl as it stands. Dropped when it is the default for the scheme, keeping any other port. The suite's own server listens on 9292, so the existing expectations are unaffected; the new spec drives Net::HTTP directly to cover 443 and 80. --- lib/httplog/adapters/net_http.rb | 9 ++++++- spec/lib/net_http_url_spec.rb | 45 ++++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+), 1 deletion(-) create mode 100644 spec/lib/net_http_url_spec.rb diff --git a/lib/httplog/adapters/net_http.rb b/lib/httplog/adapters/net_http.rb index 168cc7f..9aab384 100644 --- a/lib/httplog/adapters/net_http.rb +++ b/lib/httplog/adapters/net_http.rb @@ -6,7 +6,7 @@ class HTTP alias orig_connect connect unless method_defined?(:orig_connect) def request(req, body = nil, &block) - url = "#{protocol}://#{@address}:#{@port}#{req.path}" + url = "#{protocol}://#{@address}#{port_suffix}#{req.path}" bm = Benchmark.realtime do @response = orig_request(req, body, &block) @@ -52,5 +52,12 @@ def connect def protocol use_ssl? ? 'https' : 'http' end + + # Omitted when it is the default for the scheme, so the logged URL is the one a reader would + # write by hand — and the one they can paste into curl or grep the log for. + def port_suffix + default_port = use_ssl? ? Net::HTTP.https_default_port : Net::HTTP.default_port + @port == default_port ? '' : ":#{@port}" + end end end diff --git a/spec/lib/net_http_url_spec.rb b/spec/lib/net_http_url_spec.rb new file mode 100644 index 0000000..cd0bd34 --- /dev/null +++ b/spec/lib/net_http_url_spec.rb @@ -0,0 +1,45 @@ +# frozen_string_literal: true + +require 'spec_helper' + +# The logged URL is what a reader greps the log for and pastes into curl, so it has to be the URL +# as it would be written by hand: the scheme the connection actually used, and no port when it is +# the default for that scheme. +# +# Driven directly rather than through the test server, because the ports that matter here are 443 +# and 80 and the suite's server listens on 9292. +describe 'Net::HTTP logged URL' do + let(:logger) { Logger.new @log } + let(:path) { '/index.html' } + + before { HttpLog.configure { |c| c.logger = logger } } + + def logged_url(port:, use_ssl:) + http = Net::HTTP.new('example.com', port) + http.use_ssl = use_ssl + + response = Net::HTTPOK.new('1.1', '200', 'OK') + allow(response).to receive(:body).and_return('') + allow(http).to receive(:orig_request).and_return(response) + allow(http).to receive(:started?).and_return(true) + + http.request(Net::HTTP::Get.new(path)) + log[/Sending: GET (\S+)/, 1] + end + + it 'omits the default port for https' do + expect(logged_url(port: 443, use_ssl: true)).to eq("https://example.com#{path}") + end + + it 'omits the default port for http' do + expect(logged_url(port: 80, use_ssl: false)).to eq("http://example.com#{path}") + end + + it 'keeps a port that is not the default' do + expect(logged_url(port: 9292, use_ssl: false)).to eq("http://example.com:9292#{path}") + end + + it 'keeps a port that is not the default for https' do + expect(logged_url(port: 8443, use_ssl: true)).to eq("https://example.com:8443#{path}") + end +end