From d7a65997fdb7084180029827ce820a8dae3fcd7f Mon Sep 17 00:00:00 2001 From: rhett-inbox Date: Tue, 2 May 2023 16:07:07 -0500 Subject: [PATCH 1/2] extract core redirection logic from handle_response as the method was getting lengthy. introduce logic to clear the body when redirecting to a GET --- lib/httparty/request.rb | 50 ++++++++++++++++++++++------------- spec/httparty/request_spec.rb | 8 ++++++ 2 files changed, 40 insertions(+), 18 deletions(-) diff --git a/lib/httparty/request.rb b/lib/httparty/request.rb index 290d5327..14542446 100644 --- a/lib/httparty/request.rb +++ b/lib/httparty/request.rb @@ -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 @@ -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 @@ -362,6 +369,13 @@ 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 diff --git a/spec/httparty/request_spec.rb b/spec/httparty/request_spec.rb index 354441e1..02dcad32 100644 --- a/spec/httparty/request_spec.rb +++ b/spec/httparty/request_spec.rb @@ -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 From b4f6dff05b0f6e8d8742a8c6bcb15af82324382c Mon Sep 17 00:00:00 2001 From: rhett-inbox Date: Tue, 2 May 2023 16:23:52 -0500 Subject: [PATCH 2/2] spacing --- lib/httparty/request.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/httparty/request.rb b/lib/httparty/request.rb index 14542446..e25fa4b6 100644 --- a/lib/httparty/request.rb +++ b/lib/httparty/request.rb @@ -376,6 +376,7 @@ 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