`WebMock::Util::Headers.normalize_headers` replaces underscores with dashes
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 WebMock tries to normalize headers to have unified version for comparison with stubs.
What exactly is the issue you have problems with?
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 I see. You're right, WebMock should not do that.
Do you know why the behaviour was added in the first place?
Do you need someone to propose a solution in a PR?
Right now I am using a monkey patch which resolves this issue, I could re-use that.
It was added to ensure unified format of headers i.e. if case someone declares 'content_type' in the response.
It's wasn't the best approach though.
@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
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
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