Skip to content
Browse files

Ensure multiple values for the same header can be recorded and played…

… back.

This already worked for most adapters, but had an issue for the HTTP client adapter.

Note that I had to change the line breaks in the webmock server response to \r\n (which matches the HTTP spec, I believe) in order to get curb and patron to parse the headers correctly.
  • Loading branch information...
1 parent 7c21556 commit 553496851cebbef505708c91f99ae1d00151a9d6 @myronmarston myronmarston committed Feb 18, 2012
View
12 lib/webmock/http_lib_adapters/httpclient_adapter.rb
@@ -112,7 +112,17 @@ def build_httpclient_response(webmock_response, stream = false, &block)
def build_webmock_response(httpclient_response)
webmock_response = WebMock::Response.new
webmock_response.status = [httpclient_response.status, httpclient_response.reason]
- webmock_response.headers = httpclient_response.header.all
+
+ webmock_response.headers = {}.tap do |hash|
+ httpclient_response.header.all.each do |(key, value)|
+ if hash.has_key?(key)
+ hash[key] = Array(hash[key]) + [value]
+ else
+ hash[key] = value
+ end
+ end
+ end
+
if httpclient_response.content.respond_to?(:read)
webmock_response.body = httpclient_response.content.read
body = HTTP::Message::Body.new
View
10 spec/acceptance/curb/curb_spec_helper.rb
@@ -10,6 +10,16 @@ def http_request(method, uri, options = {}, &block)
status, response_headers =
WebMock::HttpLibAdapters::CurbAdapter.parse_header_string(curl.header_str)
+ # Deal with the fact that the HTTP spec allows multi-values headers
+ # to either be a single entry with a comma-separated listed of
+ # values, or multiple separate entries
+ response_headers.keys.each do |k|
+ v = response_headers[k]
+ if v.is_a?(Array)
+ response_headers[k] = v.join(', ')
+ end
+ end
+
OpenStruct.new(
:body => curl.body_str,
:headers => WebMock::Util::Headers.normalize_headers(response_headers),
View
21 spec/acceptance/shared/complex_cross_concern_behaviors.rb
@@ -0,0 +1,21 @@
+shared_context "complex cross-concern behaviors" do |*adapter_info|
+ it 'allows a response with multiple values for the same header to be recorded and played back exactly as-is' do
+ WebMock.allow_net_connect!
+
+ recorded_response = nil
+ WebMock.after_request { |_,r| recorded_response = r }
+ real_response = http_request(:get, webmock_server_url)
+
+ stub_request(:get, webmock_server_url).to_return(
+ :status => recorded_response.status,
+ :body => recorded_response.body,
+ :headers => recorded_response.headers
+ )
+
+ played_back_response = http_request(:get, webmock_server_url)
+
+ played_back_response.headers.keys.should include('Set-Cookie')
+ played_back_response.should == real_response
+ end
+end
+
View
3 spec/acceptance/webmock_shared.rb
@@ -6,6 +6,7 @@
require 'acceptance/shared/stubbing_requests'
require 'acceptance/shared/allowing_and_disabling_net_connect'
require 'acceptance/shared/precedence_of_stubs'
+require 'acceptance/shared/complex_cross_concern_behaviors'
unless defined? SAMPLE_HEADERS
SAMPLE_HEADERS = { "Content-Length" => "8888", "Accept" => "application/json" }
@@ -34,5 +35,7 @@
include_context "callbacks", *adapter_info
include_context "enabled and disabled webmock", *adapter_info
+
+ include_context "complex cross-concern behaviors", *adapter_info
end
end
View
12 spec/support/webmock_server.rb
@@ -33,11 +33,13 @@ def start
end
server.start do |socket|
socket.puts <<-EOT.gsub(/^\s+\|/, '')
- |HTTP/1.1 200 OK
- |Date: Fri, 31 Dec 1999 23:59:59 GMT
- |Content-Type: text/html
- |Content-Length: 11
- |
+ |HTTP/1.1 200 OK\r
+ |Date: Fri, 31 Dec 1999 23:59:59 GMT\r
+ |Content-Type: text/html\r
+ |Content-Length: 11\r
+ |Set-Cookie: bar\r
+ |Set-Cookie: foo\r
+ |\r
|hello world
EOT
end

0 comments on commit 5534968

Please sign in to comment.
Something went wrong with that request. Please try again.