Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Separate Request and Response bodies #847

Merged
merged 4 commits into from Feb 20, 2019
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 4 additions & 0 deletions UPGRADING.md
Expand Up @@ -13,6 +13,10 @@ Please note `Faraday::ClientError` was previously used for both.
* Faraday::ProxyAuthError (407). Please note this raised a `Faraday::ConnectionFailed` before.
* Faraday::UnprocessableEntityError (422)

### Custom adapters
If you have written a custom adapter, please be aware that `env.body` is now an alias to the two new properties `request_body` and `response_body`.
This should work without you noticing if your adapter inherits from `Faraday::Adapter` and calls `save_response`, but if it doesn't, then please ensure you set the `status` BEFORE the `body` while processing the response.

### Others
* Dropped support for jruby and Rubinius.
* Officially supports Ruby 2.3+
Expand Down
18 changes: 16 additions & 2 deletions lib/faraday/options/env.rb
Expand Up @@ -43,9 +43,9 @@ module Faraday
#
# @!attribute reason_phrase
# @return [String]
class Env < Options.new(:method, :body, :url, :request, :request_headers,
class Env < Options.new(:method, :request_body, :url, :request, :request_headers,
:ssl, :parallel_manager, :params, :response, :response_headers, :status,
:reason_phrase)
:reason_phrase, :response_body)

ContentLength = 'Content-Length'.freeze
StatusesWithoutBody = Set.new [204, 304]
Expand Down Expand Up @@ -76,6 +76,7 @@ def self.from(value)

# @param key [Object]
def [](key)
return self[current_body] if key == :body
if in_member_set?(key)
super(key)
else
Expand All @@ -86,13 +87,26 @@ def [](key)
# @param key [Object]
# @param value [Object]
def []=(key, value)
return super(current_body, value) if key == :body
if in_member_set?(key)
super(key, value)
else
custom_members[key] = value
end
end

def current_body
!!status ? :response_body : :request_body
end

def body
self[:body]
end

def body=(value)
self[:body] = value
end

# @return [Boolean] true if status is in the set of {SuccessfulStatuses}.
def success?
SuccessfulStatuses.include?(status)
Expand Down
14 changes: 8 additions & 6 deletions lib/faraday/response.rb
Expand Up @@ -31,8 +31,6 @@ def initialize(env = nil)

attr_reader :env

def_delegators :env, :to_hash

def status
finished? ? env.status : nil
end
Expand Down Expand Up @@ -74,12 +72,16 @@ def success?
finished? && env.success?
end

def to_hash
{
:status => env.status, :body => env.body,
:response_headers => env.response_headers
}
end

# because @on_complete_callbacks cannot be marshalled
def marshal_dump
!finished? ? nil : {
:status => @env.status, :body => @env.body,
:response_headers => @env.response_headers
}
finished? ? to_hash : nil
end

def marshal_load(env)
Expand Down
31 changes: 30 additions & 1 deletion spec/faraday/options/env_spec.rb
@@ -1,5 +1,4 @@
RSpec.describe Faraday::Env do
subject { Faraday::Env.new }
it 'allows to access members' do
expect(subject.method).to be_nil
subject.method = :get
Expand Down Expand Up @@ -34,4 +33,34 @@
expect(env2[:bar]).to eq(:custom_2)
expect(subject[:baz]).to be_nil
end

describe '#body' do
subject { Faraday::Env.from(body: { foo: 'bar' }) }
iMacTia marked this conversation as resolved.
Show resolved Hide resolved

context 'when response is not finished yet' do
it 'returns the request body' do
expect(subject.body).to eq({ foo: 'bar' })
end
end

context 'when response is finished' do
before do
subject.status = 200
subject.body = { bar: 'foo' }
subject.response = Faraday::Response.new(subject)
end

it 'returns the response body' do
expect(subject.body).to eq({ bar: 'foo' })
end

it 'allows to access request_body' do
expect(subject.request_body).to eq({ foo: 'bar' })
end

it 'allows to access response_body' do
expect(subject.response_body).to eq({ bar: 'foo' })
end
end
end
end
1 change: 0 additions & 1 deletion spec/faraday/response_spec.rb
Expand Up @@ -25,7 +25,6 @@
let(:hash) { subject.to_hash }

it { expect(hash).to be_a(Hash) }
it { expect(hash).to eq(env.to_hash) }
it { expect(hash[:status]).to eq(subject.status) }
it { expect(hash[:response_headers]).to eq(subject.headers) }
it { expect(hash[:body]).to eq(subject.body) }
Expand Down
1 change: 0 additions & 1 deletion spec/support/shared_examples/request_method.rb
Expand Up @@ -167,7 +167,6 @@
it 'handles requests with proxy' do
conn_options[:proxy] = 'http://google.co.uk'

# binding.pry
res = conn.public_send(http_method, '/')
expect(res.status).to eq(200)
end
Expand Down