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