From 7daa4330af37cb1281040b73965da6598e37e2a8 Mon Sep 17 00:00:00 2001 From: Allan Siqueira Date: Wed, 16 Aug 2023 02:47:49 -0300 Subject: [PATCH 1/2] Add new configuration to preserve headers case - Add new configuration to preserve headers case in Net::HTTP class - Add new configuration to preserve headers case in GenericRequest class --- lib/net/http.rb | 9 +++++++++ lib/net/http/generic_request.rb | 14 ++++++++++++-- test/net/http/test_http.rb | 23 +++++++++++++++++++++++ 3 files changed, 44 insertions(+), 2 deletions(-) diff --git a/lib/net/http.rb b/lib/net/http.rb index 4cf3fa3e..c8b5d3f0 100644 --- a/lib/net/http.rb +++ b/lib/net/http.rb @@ -507,6 +507,10 @@ class HTTPHeaderSyntaxError < StandardError; end # Returns the write timeout. # - {write_timeout=}[rdoc-ref:Net::HTTP#write_timeout=]: # Sets the write timeout. + # - {:preserve_headers}[rdoc-ref:Net::HTTP#preserve_headers]: + # Returns the open timeout. + # - {:preserve_headers=}[rdoc-ref:Net::HTTP#preserve_headers=]: + # Sets the read timeout. # # === Requests # @@ -1123,6 +1127,7 @@ def initialize(address, port = nil) # :nodoc: @ssl_context = nil @ssl_session = nil @sspi_enabled = false + @preserve_headers = false SSL_IVNAMES.each do |ivname| instance_variable_set ivname, nil end @@ -1532,6 +1537,9 @@ def use_ssl=(flag) # See {OpenSSL::SSL::SSLContext#verify_hostname=}[https://docs.ruby-lang.org/en/master/OpenSSL/SSL/SSLContext.html#attribute-i-verify_mode]. attr_accessor :verify_hostname + # Sets or returns whether to preserve the headers case + attr_accessor :preserve_headers + # Returns the X509 certificate chain (an array of strings) # for the session's socket peer, # or +nil+ if none. @@ -2300,6 +2308,7 @@ def request(req, body = nil, &block) # :yield: +response+ return request(req, body, &block) } end + req.preserve_headers = preserve_headers if proxy_user() req.proxy_basic_auth proxy_user(), proxy_pass() unless use_ssl? end diff --git a/lib/net/http/generic_request.rb b/lib/net/http/generic_request.rb index 9421535c..47279ae6 100644 --- a/lib/net/http/generic_request.rb +++ b/lib/net/http/generic_request.rb @@ -55,6 +55,7 @@ def initialize(m, reqbody, resbody, uri_or_path, initheader = nil) # :nodoc: @body = nil @body_stream = nil @body_data = nil + @preserve_headers = false end # Returns the string method name for the request: @@ -94,6 +95,9 @@ def initialize(m, reqbody, resbody, uri_or_path, initheader = nil) # :nodoc: # attr_reader :decode_content + # Sets if will preserve case from headers + attr_accessor :preserve_headers + # Returns a string representation of the request: # # Net::HTTP::Post.new(uri).inspect # => "#" @@ -403,8 +407,14 @@ def write_header(sock, ver, path) end buf = +'' buf << reqline << "\r\n" - each_capitalized do |k,v| - buf << "#{k}: #{v}\r\n" + if preserve_headers + each_header do |k,v| + buf << "#{k}: #{v}\r\n" + end + else + each_capitalized do |k,v| + buf << "#{k}: #{v}\r\n" + end end buf << "\r\n" sock.write buf diff --git a/test/net/http/test_http.rb b/test/net/http/test_http.rb index 0508645a..0a8f93fe 100644 --- a/test/net/http/test_http.rb +++ b/test/net/http/test_http.rb @@ -1367,4 +1367,27 @@ def test_partial_response http.ignore_eof = false assert_raise(EOFError) {http.get('/')} end + + def test_no_preserved_headers + headers = { accept: '*/*' } + expected_raw_header = "Accept: */*\r\n" + @server.mount_proc('/') do |req, _res| + assert_includes(req.raw_header, expected_raw_header) + end + + http = Net::HTTP.new(config('host'), config('port')) + http.get('/', headers) + end + + def test_preserved_headers + headers = { accept: '*/*' } + expected_raw_header = "accept: */*\r\n" + @server.mount_proc('/') do |req, _res| + assert_includes(req.raw_header, expected_raw_header) + end + + http = Net::HTTP.new(config('host'), config('port')) + http.preserve_headers = true + http.get('/', headers) + end end From d688a1333016a49b8ff550f1e6ef4629b4701181 Mon Sep 17 00:00:00 2001 From: Allan Siqueira Date: Tue, 7 Nov 2023 14:23:47 -0300 Subject: [PATCH 2/2] refactor: change config name to capitalize_headers --- lib/net/http.rb | 16 ++++++++-------- lib/net/http/generic_request.rb | 12 ++++++------ test/net/http/test_http.rb | 6 +++--- 3 files changed, 17 insertions(+), 17 deletions(-) diff --git a/lib/net/http.rb b/lib/net/http.rb index 28383eb2..3fa733ab 100644 --- a/lib/net/http.rb +++ b/lib/net/http.rb @@ -507,10 +507,10 @@ class HTTPHeaderSyntaxError < StandardError; end # Returns the write timeout. # - {write_timeout=}[rdoc-ref:Net::HTTP#write_timeout=]: # Sets the write timeout. - # - {:preserve_headers}[rdoc-ref:Net::HTTP#preserve_headers]: - # Returns the open timeout. - # - {:preserve_headers=}[rdoc-ref:Net::HTTP#preserve_headers=]: - # Sets the read timeout. + # - {:capitalize_headers}[rdoc-ref:Net::HTTP#capitalize_headers]: + # Returns the capitalize_headers config. + # - {:capitalize_headers=}[rdoc-ref:Net::HTTP#capitalize_headers=]: + # Sets the capitalize_headers config. # # === Requests # @@ -1127,7 +1127,7 @@ def initialize(address, port = nil) # :nodoc: @ssl_context = nil @ssl_session = nil @sspi_enabled = false - @preserve_headers = false + @capitalize_headers = true SSL_IVNAMES.each do |ivname| instance_variable_set ivname, nil end @@ -1537,8 +1537,8 @@ def use_ssl=(flag) # See {OpenSSL::SSL::SSLContext#verify_hostname=}[https://docs.ruby-lang.org/en/master/OpenSSL/SSL/SSLContext.html#attribute-i-verify_mode]. attr_accessor :verify_hostname - # Sets or returns whether to preserve the headers case - attr_accessor :preserve_headers + # Sets or returns whether to capitalize the headers + attr_accessor :capitalize_headers # Returns the X509 certificate chain (an array of strings) # for the session's socket peer, @@ -2308,7 +2308,7 @@ def request(req, body = nil, &block) # :yield: +response+ return request(req, body, &block) } end - req.preserve_headers = preserve_headers + req.capitalize_headers = capitalize_headers if proxy_user() req.proxy_basic_auth proxy_user(), proxy_pass() unless use_ssl? end diff --git a/lib/net/http/generic_request.rb b/lib/net/http/generic_request.rb index b4004663..34e57556 100644 --- a/lib/net/http/generic_request.rb +++ b/lib/net/http/generic_request.rb @@ -55,7 +55,7 @@ def initialize(m, reqbody, resbody, uri_or_path, initheader = nil) # :nodoc: @body = nil @body_stream = nil @body_data = nil - @preserve_headers = false + @capitalize_headers = true end # Returns the string method name for the request: @@ -95,8 +95,8 @@ def initialize(m, reqbody, resbody, uri_or_path, initheader = nil) # :nodoc: # attr_reader :decode_content - # Sets if will preserve case from headers - attr_accessor :preserve_headers + # Sets if will capitalize headers + attr_accessor :capitalize_headers # Returns a string representation of the request: # @@ -407,12 +407,12 @@ def write_header(sock, ver, path) end buf = +'' buf << reqline << "\r\n" - if preserve_headers - each_header do |k,v| + if capitalize_headers + each_capitalized do |k,v| buf << "#{k}: #{v}\r\n" end else - each_capitalized do |k,v| + each_header do |k,v| buf << "#{k}: #{v}\r\n" end end diff --git a/test/net/http/test_http.rb b/test/net/http/test_http.rb index 5128edbf..2d3095e1 100644 --- a/test/net/http/test_http.rb +++ b/test/net/http/test_http.rb @@ -1368,7 +1368,7 @@ def test_partial_response assert_raise(EOFError) {http.get('/')} end - def test_no_preserved_headers + def test_capitalized_headers headers = { accept: '*/*' } expected_raw_header = "Accept: */*\r\n" @server.mount_proc('/') do |req, _res| @@ -1379,7 +1379,7 @@ def test_no_preserved_headers http.get('/', headers) end - def test_preserved_headers + def test_no_capitalized_headers headers = { accept: '*/*' } expected_raw_header = "accept: */*\r\n" @server.mount_proc('/') do |req, _res| @@ -1387,7 +1387,7 @@ def test_preserved_headers end http = Net::HTTP.new(config('host'), config('port')) - http.preserve_headers = true + http.capitalize_headers = false http.get('/', headers) end end