Skip to content

Commit

Permalink
Merge pull request #783 from rhett-inbox/clear-body-on-redirect
Browse files Browse the repository at this point in the history
Clear body when redirecting to a GET
  • Loading branch information
jnunemaker authored Mar 11, 2024
2 parents 36c31e0 + b4f6dff commit cdae411
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 18 deletions.
51 changes: 33 additions & 18 deletions lib/httparty/request.rb
Original file line number Diff line number Diff line change
Expand Up @@ -295,24 +295,7 @@ def assume_utf16_is_big_endian

def handle_response(raw_body, &block)
if response_redirects?
options[:limit] -= 1
if options[:logger]
logger = HTTParty::Logger.build(options[:logger], options[:log_level], options[:log_format])
logger.format(self, last_response)
end
self.path = last_response['location']
self.redirect = true
if last_response.class == Net::HTTPSeeOther
unless options[:maintain_method_across_redirects] && options[:resend_on_redirect]
self.http_method = Net::HTTP::Get
end
elsif last_response.code != '307' && last_response.code != '308'
unless options[:maintain_method_across_redirects]
self.http_method = Net::HTTP::Get
end
end
capture_cookies(last_response)
perform(&block)
handle_redirection(&block)
else
raw_body ||= last_response.body

Expand All @@ -331,6 +314,30 @@ def handle_response(raw_body, &block)
end
end

def handle_redirection(&block)
options[:limit] -= 1
if options[:logger]
logger = HTTParty::Logger.build(options[:logger], options[:log_level], options[:log_format])
logger.format(self, last_response)
end
self.path = last_response['location']
self.redirect = true
if last_response.class == Net::HTTPSeeOther
unless options[:maintain_method_across_redirects] && options[:resend_on_redirect]
self.http_method = Net::HTTP::Get
end
elsif last_response.code != '307' && last_response.code != '308'
unless options[:maintain_method_across_redirects]
self.http_method = Net::HTTP::Get
end
end
if http_method == Net::HTTP::Get
clear_body
end
capture_cookies(last_response)
perform(&block)
end

def handle_host_redirection
check_duplicate_location_header
redirect_path = options[:uri_adapter].parse(last_response['location']).normalize
Expand Down Expand Up @@ -362,6 +369,14 @@ def parse_response(body)
parser.call(body, format)
end

# Some Web Application Firewalls reject incoming GET requests that have a body
# if we redirect, and the resulting verb is GET then we will clear the body that
# may be left behind from the initiating request
def clear_body
options[:body] = nil
@raw_request.body = nil
end

def capture_cookies(response)
return unless response['Set-Cookie']
cookies_hash = HTTParty::CookieHash.new
Expand Down
8 changes: 8 additions & 0 deletions spec/httparty/request_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -928,6 +928,14 @@
expect(@request.http_method).to eq(Net::HTTP::Delete)
end

it 'should clear the body before resulting GET requests' do
@request.http_method = Net::HTTP::Post
@request.options[:body] = { text: 'something' }
expect(@request.perform.parsed_response).to eq({"hash" => {"foo" => "bar"}})
expect(@request.http_method).to eq(Net::HTTP::Get)
expect(@request.options[:body]).to be_nil
end

it 'should log the redirection' do
logger_double = double
expect(logger_double).to receive(:info).twice
Expand Down

0 comments on commit cdae411

Please sign in to comment.