mirror of
https://github.com/mastodon/mastodon.git
synced 2025-01-10 04:06:27 +01:00
Do now swallow response body on persistent connection (#32729)
This commit is contained in:
parent
4e2c15b45d
commit
8e2c642d44
@ -111,16 +111,10 @@ class Request
|
||||
end
|
||||
|
||||
begin
|
||||
# If we are using a persistent connection, we have to
|
||||
# read every response to be able to move forward at all.
|
||||
# However, simply calling #to_s or #flush may not be safe,
|
||||
# as the response body, if malicious, could be too big
|
||||
# for our memory. So we use the #body_with_limit method
|
||||
response.body_with_limit if http_client.persistent?
|
||||
|
||||
yield response if block_given?
|
||||
ensure
|
||||
http_client.close unless http_client.persistent?
|
||||
response.truncated_body if http_client.persistent? && !response.connection.finished_request?
|
||||
http_client.close unless http_client.persistent? && response.connection.finished_request?
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -4,7 +4,9 @@ require 'rails_helper'
|
||||
require 'securerandom'
|
||||
|
||||
RSpec.describe Request do
|
||||
subject { described_class.new(:get, 'http://example.com') }
|
||||
subject { described_class.new(:get, 'http://example.com', **options) }
|
||||
|
||||
let(:options) { {} }
|
||||
|
||||
describe '#headers' do
|
||||
it 'returns user agent' do
|
||||
@ -39,8 +41,8 @@ RSpec.describe Request do
|
||||
end
|
||||
|
||||
describe '#perform' do
|
||||
context 'with valid host' do
|
||||
before { stub_request(:get, 'http://example.com') }
|
||||
context 'with valid host and non-persistent connection' do
|
||||
before { stub_request(:get, 'http://example.com').to_return(body: 'lorem ipsum') }
|
||||
|
||||
it 'executes a HTTP request' do
|
||||
expect { |block| subject.perform(&block) }.to yield_control
|
||||
@ -71,9 +73,9 @@ RSpec.describe Request do
|
||||
expect(subject.send(:http_client)).to have_received(:close)
|
||||
end
|
||||
|
||||
it 'returns response which implements body_with_limit' do
|
||||
it 'yields response' do
|
||||
subject.perform do |response|
|
||||
expect(response).to respond_to :body_with_limit
|
||||
expect(response.body_with_limit).to eq 'lorem ipsum'
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -95,6 +97,43 @@ RSpec.describe Request do
|
||||
expect { subject.perform }.to raise_error Mastodon::ValidationError
|
||||
end
|
||||
end
|
||||
|
||||
context 'with persistent connection' do
|
||||
before { stub_request(:get, 'http://example.com').to_return(body: SecureRandom.random_bytes(2.megabytes)) }
|
||||
|
||||
let(:http_client) { described_class.http_client.persistent('http://example.com') }
|
||||
let(:options) { { http_client: http_client } }
|
||||
|
||||
it 'leaves connection open after completely consumed response' do
|
||||
allow(http_client).to receive(:close)
|
||||
|
||||
subject.perform { |response| response.truncated_body(3.megabytes) }
|
||||
|
||||
expect(http_client).to_not have_received(:close)
|
||||
end
|
||||
|
||||
it 'leaves connection open after nearly consumed response' do
|
||||
allow(http_client).to receive(:close)
|
||||
|
||||
subject.perform { |response| response.truncated_body(1.8.megabytes) }
|
||||
|
||||
expect(http_client).to_not have_received(:close)
|
||||
end
|
||||
|
||||
it 'closes connection after unconsumed response' do
|
||||
allow(http_client).to receive(:close)
|
||||
|
||||
subject.perform
|
||||
|
||||
expect(http_client).to have_received(:close)
|
||||
end
|
||||
|
||||
it 'yields response' do
|
||||
subject.perform do |response|
|
||||
expect(response.body_with_limit(2.megabytes).size).to eq 2.megabytes
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "response's body_with_limit method" do
|
||||
|
Loading…
x
Reference in New Issue
Block a user