From df6dd3768d5fcc99a348bd52d7e6ffeaa1c391db Mon Sep 17 00:00:00 2001 From: Lamont Granquist Date: Thu, 20 Jul 2017 10:25:19 -0700 Subject: fix retries on JSON POST requests when negotiating protocol version on the first pass through the JSON middleware it encodes the body. if there's a retry, it re-encodes the body as a string with all its metacharacters escaped. this is a particular issue when doing a first request that is a POST that requires negotiating the API version. when doing a GET it isn't a problem because there's no body payload -- but a POST or a PUT which requires a retry will get garbled and will cause a 500. this happens on hosted right now if trying to POST with a v2 API since hosted is only v1, so there's a retry to downgrade. i also made the same kind of changes to the streaming download requests, but since they're GETs its unclear to me if there was any impact there -- but middleware could have been double-mangling headers on a retry. Signed-off-by: Lamont Granquist --- lib/chef/http.rb | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) (limited to 'lib/chef/http.rb') diff --git a/lib/chef/http.rb b/lib/chef/http.rb index c741dcca97..f9845c2460 100644 --- a/lib/chef/http.rb +++ b/lib/chef/http.rb @@ -5,7 +5,7 @@ # Author:: Christopher Brown () # Author:: Christopher Walters () # Author:: Daniel DeLeo () -# Copyright:: Copyright 2009-2016 Chef Software, Inc. +# Copyright:: Copyright 2009-2017, Chef Software Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -144,9 +144,9 @@ class Chef def request(method, path, headers = {}, data = false) http_attempts ||= 0 url = create_url(path) - method, url, headers, data = apply_request_middleware(method, url, headers, data) + processed_method, url, processed_headers, processed_data = apply_request_middleware(method, url, headers, data) - response, rest_request, return_value = send_http_request(method, url, headers, data) + response, rest_request, return_value = send_http_request(processed_method, url, processed_headers, processed_data) response, rest_request, return_value = apply_response_middleware(response, rest_request, return_value) response.error! unless success_response?(response) @@ -176,11 +176,12 @@ class Chef url = create_url(path) response, rest_request, return_value = nil, nil, nil tempfile = nil + data = nil method = :GET - method, url, headers, data = apply_request_middleware(method, url, headers, data) + method, url, processed_headers, data = apply_request_middleware(method, url, headers, data) - response, rest_request, return_value = send_http_request(method, url, headers, data) do |http_response| + response, rest_request, return_value = send_http_request(method, url, processed_headers, data) do |http_response| if http_response.kind_of?(Net::HTTPSuccess) tempfile = stream_to_tempfile(url, http_response, &progress_block) end @@ -223,11 +224,12 @@ class Chef url = create_url(path) response, rest_request, return_value = nil, nil, nil tempfile = nil + data = nil method = :GET - method, url, headers, data = apply_request_middleware(method, url, headers, data) + method, url, processed_headers, data = apply_request_middleware(method, url, headers, data) - response, rest_request, return_value = send_http_request(method, url, headers, data) do |http_response| + response, rest_request, return_value = send_http_request(method, url, processed_headers, data) do |http_response| if http_response.kind_of?(Net::HTTPSuccess) tempfile = stream_to_tempfile(url, http_response) end -- cgit v1.2.1