0

do you know why Rails always convert all header keys to downcase?

the example I have a request like this :

uri = URI.parse("https://yoururl.com")
request = Net::HTTP::Post.new(uri)
request.add_feild("Code", "asdasdd212312312SDw")
request.content_type = "application/json"
request["Accept"] = "text/plain"
request['RequestSignature'] = "/DlWKm99HgYLXKJTdiSBO"

but when I check request.each_header.entries, I got results like this :

[["accept-encoding", "gzip;q=1.0,deflate;q=0.6,identity;q=0.3"], ["accept", "text/plain"], ["user-agent", "Ruby"], ["host", "your-api"], ["content-type", "application/json"], ["requestsignature", "123"]]

seems like all the headers converted to downcase. do you know how to make the header still consistent with the input?

3limin4t0r
  • 19,353
  • 2
  • 31
  • 52
Rei Aldi
  • 11
  • 4
  • 3
    HTTP header names are case-insensitive – Stefan Sep 17 '21 at 14:11
  • hi @Stefan thanks for your answer, but do you know how to make the request use case sensitive? because now my request always failed because third party server only accept RequestSignature but my request always sent requestsignature -_- – Rei Aldi Sep 17 '21 at 14:16
  • Maybe [How do I preserve case with http.get?](https://stackoverflow.com/q/8864627/477037) helps – Stefan Sep 17 '21 at 14:22
  • BTW, `URI` and `Net::HTTP` are from Ruby's standard library. (not Rails) – Stefan Sep 17 '21 at 14:25
  • @Stefan thanks you help me a lot. it's working ... let me answer my question – Rei Aldi Sep 17 '21 at 15:14

1 Answers1

1

Thanks to @stefan (see comment above). So the solution is to add this new class and save it on lib or app/services:


class ImmutableHeaderKey
  attr_reader :key

  def initialize(key)
    @key = key
  end

  def downcase
    self
  end

  def capitalize
    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
    def self.to_s
      key
    end
    self
  end
end

What you need to do for your request is similar. Tested on Net::HTTP and I think this will work for HTTPParty also:

uri = URI.parse("https://yoursite.com")
request = Net::HTTP::Post.new(uri)
header_signature = ImmutableHeaderKey.new('RequestSignature')
request.content_type = "application/json"
request["Accept"] = "text/plain"
request[header_signature] = "/DlWKm99HgYLXKJTdiSBO"

Note: Tested on Faraday and this method didn't work.

Rei Aldi
  • 11
  • 4