Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue with Content Type #148

Open
OskarEichler opened this issue Aug 23, 2023 · 2 comments
Open

Issue with Content Type #148

OskarEichler opened this issue Aug 23, 2023 · 2 comments

Comments

@OskarEichler
Copy link

We've identified an issue in the current release of net-http (0.3.2).

When setting a 'Content-Type' header on a POST request like so:
request['Content-Type'] = 'application/json'

It does set the header, however, it does not recognize that the Content-Type is set correctly and adds an additional header to the request with the default application/x-www-form-urlencoded

This can be seen when calling: request.to_hash.inspect:

{"accept-encoding"=>["gzip;q=1.0,deflate;q=0.6,identity;q=0.3"], "Accept"=>["*/*"], "User-Agent"=>["Ruby"], "Host"=>["api.songstats.com"], "Content-Type"=>["application/json"], "connection"=>["close"], "host"=>["api.songstats.com"], "content-length"=>["290"], "content-type"=>["application/x-www-form-urlencoded"]}

The only way to force the application/json header to go through is to explicitly set it in the request:

request.content_type = 'application/json'

So actually it needs to be set twice in order to fully work:

request['Content-Type'] = 'application/json'
request.content_type = 'application/json'

Also when setting request['content-type'] = 'application/json' in lower case it's throwing the error:

NoMethodError: undefined method `split' for nil:NilClass
from /Users/Oskar/.rbenv/versions/3.2.1/lib/ruby/3.2.0/net/http/header.rb:713:in `main_type'

It would be great if this can be streamlined so that setting the content-type in the headers immediately propagates across the entire request, without the need to set it multiple times or be cautious of case sensitivity. This took us a couple of hours to debug because we were un-aware that it currently sends the same header twice in the same request with different values.

@0x1eef
Copy link
Contributor

0x1eef commented Sep 19, 2023

@OskarEichler
Can you provide an isolated reproduction case ? Are you using set_form, set_form_data ?
I tried to reproduce, but no luck.

@OskarEichler
Copy link
Author

@0x1eef Thanks for looking into this - here is how we send the request:

      https = Net::HTTP.new(url.host, url.port)
      https.use_ssl = true

      request_method = method == :get ? CaseSensitiveGet : CaseSensitivePost

      request = request_method.new(url, {myCasedHeader: 'x-api-key'})
      request["Authorization"] = "Bearer #{access_token}"
      request["x-api-key"] = AMAZON_API_KEY
      request['Content-Type'] = 'application/json'
      request.content_type = 'application/json'
      request.body = payload.to_json
     
      data = https.request(request)

Also note that we had to create custom methods CaseSensitiveGet and CaseSensitivePost as you library for some reason Capitalized the header keys. In the case of amazon they do not recognize the key 'X-api-key', only 'x-api-key', so we had to manually create the modifications so that they don't get auto cased. It would be great if you can fix that so that the keys are passed exactly as they are being provided by the user.

Here is our CaseSensitiveGet class for context:

class CaseSensitiveGet < Net::HTTP::Get
  def initialize_http_header(headers)
    @header = {}
    headers.each{|k,v| @header[k.to_s] = [v] }
  end

  def [](name)
    @header[name.to_s]
  end

  def []=(name, val)
    if val
      @header[name.to_s] = [val]
    else
      @header.delete(name.to_s)
    end
  end

  def capitalize(name)
    name
  end
end

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

2 participants