我正在ruby中做一个http请求:
http = Net::HTTP.new(uri.host, uri.port)
req = Net::HTTP::Post.new(uri.path)
req.body = payload
req['customeheader'] = 'xxxxxxxxx'
http.set_debug_output $stdout
我打开了调试,当发布请求时,我可以看到标题被发布为:
Customheader: xxxxxxxxx
无论如何要阻止这一点,我发布的第三方服务器发出错误是因为标题名称不正确 - 它期待customheader:
答案 0 :(得分:14)
虽然可以通过修补Net :: HTTPHeader和Net:HTTPGenericRequest来删除小写和大写,但我发现了一种不同的方法,它允许选择性区分大小写而不是强制一切。
解决方案:
class CaseSensitiveString < String
def downcase
self
end
def capitalize
self
end
end
然后CaseSensitiveString.new('keyname')在区分大小写时创建密钥。将字符串/符号用于其他键以维护现有行为。这比猴子补丁简单得多,并且与rest-client库以及Net :: HTTP配合良好。
答案 1 :(得分:5)
根据HTTP规范(RFC 2616),标题字段名称为case-insensitive。因此第三方服务器的实现方式已经破裂。
如果你真的需要,你可以修补Net :: HTTP以保留大小写,因为它在存储它们时会对字段名称进行下调,然后用初始大写字母写下它们。
以下是您使用的存储方法(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
这是写标题(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
这些可能是您需要覆盖的唯一方法,但我不是100%肯定。
答案 2 :(得分:5)
基于之前的答案,这适用于ruby 2.3:
class CaseSensitiveString < String
def downcase
self
end
def capitalize
self
end
def to_s
self
end
end
需要添加to_s
方法,因为从2.3开始,HTTP::Header
capitalize
方法会在每个标题上调用to_s
。