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] = ''
end
end
def response_headers(env)
env[:response_headers] ||= Utils::Headers.new
end
end
end

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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}

View File

@ -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

View File

@ -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'

View File

@ -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

View File

@ -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