2

Maybe I'm just blind but many post about passing headers in Net::HTTP follows the lines of

require 'net/http'    

uri = URI("http://www.ruby-lang.org")
req = Net::HTTP::Get.new(uri)
req['some_header'] = "some_val"

res = Net::HTTP.start(uri.hostname, uri.port) {|http|
  http.request(req)
}

puts res.body

(From Ruby - Send GET request with headers metaphori's answer)

And from the Net::HTTP docs (https://docs.ruby-lang.org/en/2.0.0/Net/HTTP.html)

uri = URI('http://example.com/cached_response')
file = File.stat 'cached_response'

req = Net::HTTP::Get.new(uri)
req['If-Modified-Since'] = file.mtime.rfc2822

res = Net::HTTP.start(uri.hostname, uri.port) {|http|
  http.request(req)
}

open 'cached_response', 'w' do |io|
  io.write res.body
end if res.is_a?(Net::HTTPSuccess)

But what is the advantage of doing the above when you can pass the headers via the following way?

options = { 
  'headers' => {
    'Content-Type' => 'application/json'
  }
}

request = Net::HTTP::Get.new('http://www.stackoverflow.com/', options['headers'])

This allows you to parameterize the headers and can allow for multiple headers very easily.

My main question is, what is the advantage of passing the headers in the creation of Net::HTTP::Get vs passing them after the creation of Net::HTTP::Get

Net::HTTPHeader already goes ahead and assigns the headers in the function

def initialize_http_header(initheader)
    @header = {}
    return unless initheader
    initheader.each do |key, value|
      warn "net/http: duplicated HTTP header: #{key}", uplevel: 1 if key?(key) and $VERBOSE
      if value.nil?
        warn "net/http: nil HTTP header: #{key}", uplevel: 1 if $VERBOSE
      else
        value = value.strip # raise error for invalid byte sequences
        if value.count("\r\n") > 0
          raise ArgumentError, 'header field value cannot include CR/LF'
        end
        @header[key.downcase] = [value]
      end
    end
  end

So doing request['some_header'] = "some_val" almost seems like code duplication.

1 Answers1

1

There is no advantage for setting headers one way or another, at least not that I can think of. It comes down to your own preference. In fact, if you take a look at what happens when you supply headers while initializing a new Net::Http::Get, you will find that internally, Ruby simply sets the headers onto a @headers variable: https://github.com/ruby/ruby/blob/c5eb24349a4535948514fe765c3ddb0628d81004/lib/net/http/header.rb#L25

And if you set the headers using request[name] = value, you can see that Net::Http does the exact same thing, but in a different method: https://github.com/ruby/ruby/blob/c5eb24349a4535948514fe765c3ddb0628d81004/lib/net/http/header.rb#L46

So the resulting object has the same configuration no matter which way you decide to pass the request headers.

Stephen Crosby
  • 1,157
  • 7
  • 19