more love for response headers; handle ones with multiple values

Also:
  - ensure that env[:response_headers] is not available during request phase
  - fix headers from "Test" adapter

Closes #43
This commit is contained in:
Mislav Marohnić 2011-03-27 21:57:14 +02:00
parent ce861bbc14
commit f739002d0b
13 changed files with 44 additions and 49 deletions

View File

@ -30,5 +30,9 @@ module Faraday
env[:body] = '' env[:body] = ''
end end
end end
def response_headers(env)
env[:response_headers] ||= Utils::Headers.new
end
end end
end end

View File

@ -22,7 +22,7 @@ module Faraday
@session.__send__(env[:method], env[:url].request_uri, env[:body], env[:request_headers]) @session.__send__(env[:method], env[:url].request_uri, env[:body], env[:request_headers])
resp = @session.response resp = @session.response
env.update :status => resp.status, :body => resp.body env.update :status => resp.status, :body => resp.body
env[:response_headers].update resp.headers response_headers(env).update resp.headers
@app.call env @app.call env
end end
end end

View File

@ -8,20 +8,6 @@ module Faraday
self.load_error = e self.load_error = e
end 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) def call(env)
super super
request = EventMachine::HttpRequest.new(URI::parse(env[:url].to_s)) request = EventMachine::HttpRequest.new(URI::parse(env[:url].to_s))
@ -67,9 +53,10 @@ module Faraday
client = block.call client = block.call
end end
env.update(:status => client.response_header.http_status.to_i, client.response_header.each do |name, value|
:response_headers => Header.new(client), response_headers(env)[name.to_sym] = value
:body => client.response) end
env.update :status => client.response_header.status, :body => client.response
@app.call env @app.call env
rescue Errno::ECONNREFUSED rescue Errno::ECONNREFUSED

View File

@ -22,7 +22,7 @@ module Faraday
:body => env[:body] :body => env[:body]
env.update :status => resp.status.to_i, :body => resp.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 @app.call env
rescue ::Excon::Errors::SocketError rescue ::Excon::Errors::SocketError

View File

@ -54,7 +54,7 @@ module Faraday
end end
http_response.each_header do |key, value| http_response.each_header do |key, value|
env[:response_headers][key] = value response_headers(env)[key] = value
end end
env.update :status => http_response.code.to_i, :body => http_response.body env.update :status => http_response.code.to_i, :body => http_response.body

View File

@ -26,7 +26,7 @@ module Faraday
end end
env.update :status => response.status, :body => response.body env.update :status => response.status, :body => response.body
env[:response_headers].update response.headers response_headers(env).update response.headers
@app.call env @app.call env
end end

View File

@ -11,7 +11,7 @@ module Faraday
# resp = test.get '/nigiri/sake.json' # resp = test.get '/nigiri/sake.json'
# resp.body # => 'hi world' # resp.body # => 'hi world'
# #
class Test < Middleware class Test < Faraday::Adapter
attr_accessor :stubs attr_accessor :stubs
def self.loaded?() false end def self.loaded?() false end
@ -105,14 +105,13 @@ module Faraday
end end
def call(env) def call(env)
super
normalized_path = Faraday::Utils.normalize_path(env[:url]) normalized_path = Faraday::Utils.normalize_path(env[:url])
if stub = stubs.match(env[:method], normalized_path, env[:body]) if stub = stubs.match(env[:method], normalized_path, env[:body])
status, headers, body = stub.block.call(env) status, headers, body = stub.block.call(env)
env.update \ env.update :status => status, :body => body
:status => status, response_headers(env).update headers
:response_headers => headers,
:body => body
else else
raise "no stubbed request for #{env[:method]} #{normalized_path} #{env[:body]}" raise "no stubbed request for #{env[:method]} #{normalized_path} #{env[:body]}"
end end

View File

@ -32,7 +32,7 @@ module Faraday
is_parallel = !!env[:parallel_manager] is_parallel = !!env[:parallel_manager]
req.on_complete do |resp| req.on_complete do |resp|
env.update :status => resp.code, :body => resp.body 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 env[:response].finish(env) if is_parallel
end end

View File

@ -73,7 +73,6 @@ module Faraday
:body => body, :body => body,
:url => connection.build_url(path, env_params), :url => connection.build_url(path, env_params),
:request_headers => env_headers, :request_headers => env_headers,
:response_headers => Utils::Headers.new,
:parallel_manager => connection.parallel_manager, :parallel_manager => connection.parallel_manager,
:request => connection.options.merge(:proxy => connection.proxy), :request => connection.options.merge(:proxy => connection.proxy),
:ssl => connection.ssl} :ssl => connection.ssl}

View File

@ -23,6 +23,8 @@ module Faraday
end end
def []=(k, v) def []=(k, v)
# join multiple values with a comma
v = v.to_ary.join(', ') if v.respond_to? :to_ary
super(KeyMap[k], v) super(KeyMap[k], v)
end end
@ -33,7 +35,12 @@ module Faraday
header_string.split(/\r\n/). header_string.split(/\r\n/).
tap { |a| a.shift if a.first.index('HTTP/') == 0 }. # drop the HTTP status line 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 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
end end

View File

@ -31,6 +31,14 @@ else
assert_match /text\/html/, response.headers['content-type'], 'lowercase fail' assert_match /text\/html/, response.headers['content-type'], 'lowercase fail'
end 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 define_method "test_#{adapter}_POST_send_url_encoded_params" do
resp = create_connection(adapter).post do |req| resp = create_connection(adapter).post do |req|
req.url 'echo_name' req.url 'echo_name'

View File

@ -29,12 +29,6 @@ class EnvTest < Faraday::TestCase
assert_equal 'Faraday', headers['server'] assert_equal 'Faraday', headers['server']
end 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 def test_request_create_stores_body
assert_equal @input[:body], @env[:body] assert_equal @input[:body], @env[:body]
end end

View File

@ -6,6 +6,7 @@ get '/hello_world' do
end end
get '/json' do get '/json' do
content_type 'application/json'
"[1,2,3]" "[1,2,3]"
end end
@ -19,26 +20,22 @@ post '/file' do
end end
end end
post '/hello' do %w[get post].each do |method|
"hello #{params[:name]}" send(method, '/hello') do
"hello #{params[:name]}"
end
end end
get '/hello' do %w[post put].each do |method|
"hello #{params[:name]}" send(method, '/echo_name') do
end params[:name].inspect
end
post '/echo_name' do
params[:name].inspect
end
put '/echo_name' do
params[:name].inspect
end end
delete '/delete_with_json' do delete '/delete_with_json' do
%/{"deleted":true}/ %/{"deleted":true}/
end end
delete '/delete_with_params' do get '/multi' do
params[:deleted] [200, { 'Set-Cookie' => %w[ one two ] }, '']
end end