stop ruby http request modifying header name
While it's possible to monkey patch Net::HTTPHeader and Net:HTTPGenericRequest to remove the downcase and capitalize, I found a different approach that allows selective case sensitivity rather than forcing everything.
The solution:
class CaseSensitiveString < String
def downcase
self
end
def capitalize
self
end
end
Then CaseSensitiveString.new('keyname') to create your keys when they are case sensitive. Use strings/symbols for other keys to maintain existing behaviour. This is much simpler than the monkey patching and works well with the rest-client library as well as Net::HTTP.
According to the HTTP spec (RFC 2616), header field names are case-insensitive. So the third-party server has a broken implementation.
If you really needed to, you could monkey-patch Net::HTTP to preserve case, because it downcases the field names when it stores them and then writes them with initial caps.
Here's the storage method you used (Net::HTTPHeader#[]=
):
# File net/http.rb, line 1160
def []=(key, val)
unless val
@header.delete key.downcase
return val
end
@header[key.downcase] = [val]
end
And here is where it writes the header (Net::HTTPGenericRequest#write_header
):
# File lib/net/http.rb, line 2071
def write_header(sock, ver, path)
buf = "#{@method} #{path} HTTP/#{ver}\r\n"
each_capitalized do |k,v|
buf << "#{k}: #{v}\r\n"
end
buf << "\r\n"
sock.write buf
end
Those are likely the only methods you'd need to override, but I'm not 100% certain.
Building off of a previous answer, this will work for ruby 2.3:
class CaseSensitiveString < String
def downcase
self
end
def capitalize
self
end
def to_s
self
end
end
The to_s
method needs to be added because as of 2.3, HTTP::Header
's capitalize
method calls to_s
on each header.