如何使用http.get保留案例?

Yar*_*veh 3 ruby ruby-on-rails

我需要在特定字符大小写中发送HTTP标头.我知道这是针对RFC的,但我有一个要求.

http.get似乎改变了我提供的头字典的情况.我该如何保留角色?

yfe*_*lum 13

根据Tin Man的回答,该Net::HTTP库调用#downcase了您的自定义标题键(以及所有标题键),这里有一些其他选项不会对整个文件进行修补Net::HTTP.

你可以试试这个:

custom_header_key = "X-miXEd-cASe"
def custom_header_key.downcase
  self
end
Run Code Online (Sandbox Code Playgroud)

要避免清除方法缓存,请将上述结果存储在类级别常量中:

custom_header_key = "X-miXEd-cASe"
def custom_header_key.downcase
  self
end
CUSTOM_HEADER_KEY = custom_header_key
Run Code Online (Sandbox Code Playgroud)

或子类String以覆盖该特定行为:

class StringWithIdentityDowncase < String
  def downcase
    self
  end
end

custom_header_key = StringWithIdentityDowncase.new("X-miXEd-cASe")
Run Code Online (Sandbox Code Playgroud)


Jos*_*eek 5

接受的答案不起作用.坦率地说,我怀疑它曾经做过,因为看起来它必须覆盖拆分和大写,我跟着那个方法回来了一些提交,至少自2004年以来就是这样.

这是我的解决方案,回答这个封闭的问题:

require 'net/http'

class Net::HTTP::ImmutableHeaderKey
  attr_reader :key

  def initialize(key)
    @key = key
  end

  def downcase
    self
  end

  def capitalize
    self
  end

  def split(*)
    [self]
  end

  def hash
    key.hash
  end

  def eql?(other)
    key.eql? other.key.eql?
  end

  def to_s
    key
  end
end
Run Code Online (Sandbox Code Playgroud)

现在,您需要确保始终使用此类的实例作为键.

request           = Net::HTTP::Get.new('/')
user_key          = Net::HTTP::ImmutableHeaderKey.new("user")
request[user_key] = "James"

require 'stringio'
StringIO.new.tap do |output|
  request.exec output, 'ver', 'path'
  puts output.string
end

# >> GET path HTTP/ver
# >> Accept-Encoding: gzip;q=1.0,deflate;q=0.6,identity;q=0.3
# >> Accept: */*
# >> User-Agent: Ruby
# >> user: James
# >> 
Run Code Online (Sandbox Code Playgroud)