webmock icon indicating copy to clipboard operation
webmock copied to clipboard

`WebMock::Util::Headers.normalize_headers` replaces underscores with dashes

Open mikekelly opened this issue 10 years ago • 11 comments

WebMock is unable to correctly mock server responses that include underscores in the header names because it replaces any underscores with dashes. Is there a specific reason for this behaviour? I checked the HTTP specification and underscores are not an illegal character.

The offending line is here:

https://github.com/bblimke/webmock/blob/6b5374c50b288c7086a3eecd098f78507d6f8994/lib/webmock/util/headers.rb#L10

mikekelly avatar May 05 '15 21:05 mikekelly

@mikekelly WebMock tries to normalize headers to have unified version for comparison with stubs.

What exactly is the issue you have problems with?

bblimke avatar May 07 '15 16:05 bblimke

I'm stubbing a response which has a header called x-my_header but the webmock response renames it tox-my-header which breaks my client. I'm unable to simulate response headers with underscores

mikekelly avatar May 07 '15 17:05 mikekelly

@mikekelly I see. You're right, WebMock should not do that.

bblimke avatar May 07 '15 21:05 bblimke

Do you know why the behaviour was added in the first place?

mikekelly avatar May 07 '15 23:05 mikekelly

Do you need someone to propose a solution in a PR?

mikekelly avatar May 08 '15 22:05 mikekelly

Right now I am using a monkey patch which resolves this issue, I could re-use that.

mikekelly avatar May 08 '15 22:05 mikekelly

It was added to ensure unified format of headers i.e. if case someone declares 'content_type' in the response.

bblimke avatar May 09 '15 16:05 bblimke

It's wasn't the best approach though.

bblimke avatar May 09 '15 16:05 bblimke

@mikekelly I made a pull request with some hacky code to get specs around how we are normalizing headers right now. Can you write a spec that fits you use case.

If you don't get to it, I'll take a stab when I have some time. https://github.com/bblimke/webmock/pull/482

davidbegin avatar May 14 '15 03:05 davidbegin

It's a huge problem!!! My temporary solution: /config/initializers/webmoch_rewrite.rb

# frozen_string_literal: true
if defined? WebMock::Response
  WebMock::Response.class_eval do
    def headers=(headers)
      @headers = headers
      if @headers && [email protected]_a?(Proc) # rubocop:disable Style/GuardClause
        @headers =
          if @headers.key?(:skip_normalize)
            @headers.except(:skip_normalize)
          else
            WebMock::Util::Headers.normalize_headers(@headers)
          end
      end
    end
  end
end

Blaze34 avatar Mar 10 '17 12:03 Blaze34

i have a PR ready to add a config, but i dont have access to push a branch. However, this inspired a similar workaround that works really well for me:

def preserve_header_names_webmock!
  return unless defined? WebMock::Util::Headers

  WebMock::Util::Headers.class_eval do
    class << self
      alias_method :true_normalize_name, :normalize_name

      def normalize_name(name)
        name
      end
    end
  end
end

def restore_normailzing_header_names_webmock!
  return unless defined? WebMock::Util::Headers

  WebMock::Util::Headers.class_eval do
    class << self
      alias_method :normalize_name, :true_normalize_name

      undef :true_normalize_name
    end
  end
end

i have it in my webmock spec support file and i use preserve_header_names_webmock! in a before block and restore_normailzing_header_names_webmock! in a after block

rodeezy avatar Sep 17 '24 20:09 rodeezy