diff --git a/lib/faraday/adapter.rb b/lib/faraday/adapter.rb index eb42e47c..5b0c9814 100644 --- a/lib/faraday/adapter.rb +++ b/lib/faraday/adapter.rb @@ -30,5 +30,9 @@ module Faraday env[:body] = '' end end + + def response_headers(env) + env[:response_headers] ||= Utils::Headers.new + end end end diff --git a/lib/faraday/adapter/action_dispatch.rb b/lib/faraday/adapter/action_dispatch.rb index 2863d497..13553f7b 100644 --- a/lib/faraday/adapter/action_dispatch.rb +++ b/lib/faraday/adapter/action_dispatch.rb @@ -22,7 +22,7 @@ module Faraday @session.__send__(env[:method], env[:url].request_uri, env[:body], env[:request_headers]) resp = @session.response env.update :status => resp.status, :body => resp.body - env[:response_headers].update resp.headers + response_headers(env).update resp.headers @app.call env end end diff --git a/lib/faraday/adapter/em_synchrony.rb b/lib/faraday/adapter/em_synchrony.rb index 3e2d5172..81ef4e50 100644 --- a/lib/faraday/adapter/em_synchrony.rb +++ b/lib/faraday/adapter/em_synchrony.rb @@ -8,20 +8,6 @@ module Faraday self.load_error = e end - class Header - include Net::HTTPHeader - def initialize response - @header = {} - response.response_header.each do |key, value| - case key - when "CONTENT_TYPE"; self.content_type = value - when "CONTENT_LENGTH"; self.content_length = value - else; self[key] = value - end - end - end - end - def call(env) super request = EventMachine::HttpRequest.new(URI::parse(env[:url].to_s)) @@ -67,9 +53,10 @@ module Faraday client = block.call end - env.update(:status => client.response_header.http_status.to_i, - :response_headers => Header.new(client), - :body => client.response) + client.response_header.each do |name, value| + response_headers(env)[name.to_sym] = value + end + env.update :status => client.response_header.status, :body => client.response @app.call env rescue Errno::ECONNREFUSED diff --git a/lib/faraday/adapter/excon.rb b/lib/faraday/adapter/excon.rb index 9ed5f924..09f95440 100644 --- a/lib/faraday/adapter/excon.rb +++ b/lib/faraday/adapter/excon.rb @@ -22,7 +22,7 @@ module Faraday :body => env[:body] env.update :status => resp.status.to_i, :body => resp.body - env[:response_headers].update resp.headers + response_headers(env).update resp.headers @app.call env rescue ::Excon::Errors::SocketError diff --git a/lib/faraday/adapter/net_http.rb b/lib/faraday/adapter/net_http.rb index d1619b2a..da8ca837 100644 --- a/lib/faraday/adapter/net_http.rb +++ b/lib/faraday/adapter/net_http.rb @@ -54,7 +54,7 @@ module Faraday end http_response.each_header do |key, value| - env[:response_headers][key] = value + response_headers(env)[key] = value end env.update :status => http_response.code.to_i, :body => http_response.body diff --git a/lib/faraday/adapter/patron.rb b/lib/faraday/adapter/patron.rb index 900b20d5..ff380533 100644 --- a/lib/faraday/adapter/patron.rb +++ b/lib/faraday/adapter/patron.rb @@ -26,7 +26,7 @@ module Faraday end env.update :status => response.status, :body => response.body - env[:response_headers].update response.headers + response_headers(env).update response.headers @app.call env end diff --git a/lib/faraday/adapter/test.rb b/lib/faraday/adapter/test.rb index 55258b15..d0be73a1 100644 --- a/lib/faraday/adapter/test.rb +++ b/lib/faraday/adapter/test.rb @@ -11,7 +11,7 @@ module Faraday # resp = test.get '/nigiri/sake.json' # resp.body # => 'hi world' # - class Test < Middleware + class Test < Faraday::Adapter attr_accessor :stubs def self.loaded?() false end @@ -105,14 +105,13 @@ module Faraday end def call(env) + super normalized_path = Faraday::Utils.normalize_path(env[:url]) if stub = stubs.match(env[:method], normalized_path, env[:body]) status, headers, body = stub.block.call(env) - env.update \ - :status => status, - :response_headers => headers, - :body => body + env.update :status => status, :body => body + response_headers(env).update headers else raise "no stubbed request for #{env[:method]} #{normalized_path} #{env[:body]}" end diff --git a/lib/faraday/adapter/typhoeus.rb b/lib/faraday/adapter/typhoeus.rb index 00a7dbf7..021e1602 100644 --- a/lib/faraday/adapter/typhoeus.rb +++ b/lib/faraday/adapter/typhoeus.rb @@ -32,7 +32,7 @@ module Faraday is_parallel = !!env[:parallel_manager] req.on_complete do |resp| env.update :status => resp.code, :body => resp.body - env[:response_headers].parse resp.headers + response_headers(env).parse resp.headers env[:response].finish(env) if is_parallel end diff --git a/lib/faraday/request.rb b/lib/faraday/request.rb index 6d363fdf..ee4b40da 100644 --- a/lib/faraday/request.rb +++ b/lib/faraday/request.rb @@ -73,7 +73,6 @@ module Faraday :body => body, :url => connection.build_url(path, env_params), :request_headers => env_headers, - :response_headers => Utils::Headers.new, :parallel_manager => connection.parallel_manager, :request => connection.options.merge(:proxy => connection.proxy), :ssl => connection.ssl} diff --git a/lib/faraday/utils.rb b/lib/faraday/utils.rb index 08c8642f..02b2f3c6 100644 --- a/lib/faraday/utils.rb +++ b/lib/faraday/utils.rb @@ -23,6 +23,8 @@ module Faraday end def []=(k, v) + # join multiple values with a comma + v = v.to_ary.join(', ') if v.respond_to? :to_ary super(KeyMap[k], v) end @@ -33,7 +35,12 @@ module Faraday header_string.split(/\r\n/). tap { |a| a.shift if a.first.index('HTTP/') == 0 }. # drop the HTTP status line map { |h| h.split(/:\s+/, 2) }.reject { |(k, v)| k.nil? }. # split key and value, ignore blank lines - each { |(k, v)| self[k] = v } + each { |key, value| + # join multiple values with a comma + if self[key] then self[key] << ', ' << value + else self[key] = value + end + } end end diff --git a/test/adapters/live_test.rb b/test/adapters/live_test.rb index 37dc023d..e9b740b2 100644 --- a/test/adapters/live_test.rb +++ b/test/adapters/live_test.rb @@ -31,6 +31,14 @@ else assert_match /text\/html/, response.headers['content-type'], 'lowercase fail' end + # https://github.com/geemus/excon/issues/10 + unless %[Faraday::Adapter::Excon] == adapter.to_s + define_method "test_#{adapter}_GET_handles_headers_with_multiple_values" do + response = create_connection(adapter).get('multi') + assert_equal 'one, two', response.headers['set-cookie'] + end + end + define_method "test_#{adapter}_POST_send_url_encoded_params" do resp = create_connection(adapter).post do |req| req.url 'echo_name' diff --git a/test/env_test.rb b/test/env_test.rb index 80976b34..5bd8ecd2 100644 --- a/test/env_test.rb +++ b/test/env_test.rb @@ -29,12 +29,6 @@ class EnvTest < Faraday::TestCase assert_equal 'Faraday', headers['server'] end - def test_response_headers_case_insensitive - headers = @env[:response_headers] - headers['Content-Type'] = 'application/json' - assert_equal 'application/json', headers['content-type'] - end - def test_request_create_stores_body assert_equal @input[:body], @env[:body] end diff --git a/test/live_server.rb b/test/live_server.rb index 2987130e..7afdb0dc 100644 --- a/test/live_server.rb +++ b/test/live_server.rb @@ -6,6 +6,7 @@ get '/hello_world' do end get '/json' do + content_type 'application/json' "[1,2,3]" end @@ -19,26 +20,22 @@ post '/file' do end end -post '/hello' do - "hello #{params[:name]}" +%w[get post].each do |method| + send(method, '/hello') do + "hello #{params[:name]}" + end end -get '/hello' do - "hello #{params[:name]}" -end - -post '/echo_name' do - params[:name].inspect -end - -put '/echo_name' do - params[:name].inspect +%w[post put].each do |method| + send(method, '/echo_name') do + params[:name].inspect + end end delete '/delete_with_json' do %/{"deleted":true}/ end -delete '/delete_with_params' do - params[:deleted] +get '/multi' do + [200, { 'Set-Cookie' => %w[ one two ] }, ''] end