diff --git a/lib/httparty/request.rb b/lib/httparty/request.rb index 290d5327..e25fa4b6 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,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 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