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

Fix error with body.rewind with rack 3.0 #1107

Merged
merged 1 commit into from
Oct 19, 2022
Merged
Show file tree
Hide file tree
Changes from all 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
13 changes: 10 additions & 3 deletions lib/rollbar/request_data_extractor.rb
Original file line number Diff line number Diff line change
Expand Up @@ -214,16 +214,23 @@ def rollbar_raw_body_params(rack_req)
return {} unless correct_method
return {} unless json_request?(rack_req)

raw_body = rack_req.body.read
raw_body = read_raw_body(rack_req.body)
begin
Rollbar::JSON.load(raw_body)
rescue StandardError
raw_body
end
rescue StandardError
{}
ensure
rack_req.body.rewind
end

def read_raw_body(body)
return {} unless body.respond_to?(:rewind)

body.rewind
raw_body = body.read
body.rewind
raw_body
end

def json_request?(rack_req)
Expand Down
41 changes: 41 additions & 0 deletions spec/rollbar/request_data_extractor_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -354,6 +354,47 @@ class ExtractorDummy
end
end

context 'with non-rewindable input' do
let(:params) { { 'key' => 'value' } }
let(:body) { params.to_json }
let(:env) do
Rack::MockRequest.env_for('/?foo=bar',
'CONTENT_TYPE' => 'application/json',
:method => 'POST')
end

# According to Rack 3.0 "The input stream must respond to gets, each, and read"
# https://github.com/rack/rack/blob/3.0.0/SPEC.rdoc#the-input-stream-
let(:non_rewindable_input) do
Class.new do
def initialize(body)
@body = body
end

def gets
@body
end

def read
@body
end

def each
yield(@body)
end
end
end

before do
env['rack.input'] = non_rewindable_input.new(body)
end

it 'skips extracting the body' do
result = subject.extract_request_data_from_rack(env)
expect(result[:body]).to be_eql('{}')
end
end

context 'with POST params' do
let(:params) { { 'key' => 'value' } }
let(:env) do
Expand Down