From ff4a414e5c3db43d2af26692f4253f3ce5db5cbd Mon Sep 17 00:00:00 2001 From: Sangyong Sim Date: Fri, 30 Nov 2018 11:00:22 +0900 Subject: [PATCH] Preserve HTTP header key as string to prevent send Host header twice accidentally. --- lib/net/http/header.rb | 26 ++++++++++++++------------ test/net/http/test_httpheader.rb | 5 +++++ 2 files changed, 19 insertions(+), 12 deletions(-) diff --git a/lib/net/http/header.rb b/lib/net/http/header.rb index 4fa6d8a772..4b5306b4f7 100644 --- a/lib/net/http/header.rb +++ b/lib/net/http/header.rb @@ -22,7 +22,7 @@ def initialize_http_header(initheader) if value.count("\r\n") > 0 raise ArgumentError, "header #{key} has field value #{value.inspect}, this cannot include CR/LF" end - @header[key.downcase] = [value] + @header[key.to_s.downcase] = [value] end end end @@ -36,14 +36,14 @@ def size #:nodoc: obsolete # Returns the header field corresponding to the case-insensitive key. # For example, a key of "Content-Type" might return "text/html" def [](key) - a = @header[key.downcase] or return nil + a = @header[key.to_s.downcase] or return nil a.join(', ') end # Sets the header field corresponding to the case-insensitive key. def []=(key, val) unless val - @header.delete key.downcase + @header.delete key.to_s.downcase return val end set_field(key, val) @@ -65,8 +65,9 @@ def []=(key, val) # p request.get_fields('X-My-Header') #=> ["a", "b", "c"] # def add_field(key, val) - if @header.key?(key.downcase) - append_field_value(@header[key.downcase], val) + stringified_downcased_key = key.to_s.downcase + if @header.key?(stringified_downcased_key) + append_field_value(@header[stringified_downcased_key], val) else set_field(key, val) end @@ -77,13 +78,13 @@ def add_field(key, val) when Enumerable ary = [] append_field_value(ary, val) - @header[key.downcase] = ary + @header[key.to_s.downcase] = ary else val = val.to_s # for compatibility use to_s instead of to_str if val.b.count("\r\n") > 0 raise ArgumentError, 'header field value cannot include CR/LF' end - @header[key.downcase] = [val] + @header[key.to_s.downcase] = [val] end end @@ -112,8 +113,9 @@ def add_field(key, val) # #=> "session=al98axx; expires=Fri, 31-Dec-1999 23:58:23, query=rubyscript; expires=Fri, 31-Dec-1999 23:58:23" # def get_fields(key) - return nil unless @header[key.downcase] - @header[key.downcase].dup + stringified_downcased_key = key.to_s.downcase + return nil unless @header[stringified_downcased_key] + @header[stringified_downcased_key].dup end # Returns the header field corresponding to the case-insensitive key. @@ -121,7 +123,7 @@ def get_fields(key) # raises an IndexError if there's no header field named +key+ # See Hash#fetch def fetch(key, *args, &block) #:yield: +key+ - a = @header.fetch(key.downcase, *args, &block) + a = @header.fetch(key.to_s.downcase, *args, &block) a.kind_of?(Array) ? a.join(', ') : a end @@ -182,12 +184,12 @@ def each_value #:yield: +value+ # Removes a header field, specified by case-insensitive key. def delete(key) - @header.delete(key.downcase) + @header.delete(key.to_s.downcase) end # true if +key+ header exists. def key?(key) - @header.key?(key.downcase) + @header.key?(key.to_s.downcase) end # Returns a Hash consisting of header names and array of values. diff --git a/test/net/http/test_httpheader.rb b/test/net/http/test_httpheader.rb index f8778522eb..cb4678a805 100644 --- a/test/net/http/test_httpheader.rb +++ b/test/net/http/test_httpheader.rb @@ -31,6 +31,11 @@ def test_initialize assert_raise(ArgumentError){ @c.initialize_http_header("foo"=>"a\xff") } end + def test_initialize_with_symbol + @c.initialize_http_header(foo: "abc") + assert_equal "abc", @c["foo"] + end + def test_size assert_equal 0, @c.size @c['a'] = 'a' -- 2.19.1