diff options
author | danielsdeleo <dan@opscode.com> | 2013-10-07 16:40:04 -0700 |
---|---|---|
committer | danielsdeleo <dan@opscode.com> | 2013-10-08 15:01:48 -0700 |
commit | 75a71fcdb1e03ba405fe0ddf1d9717e4a5c57b03 (patch) | |
tree | d36696d88b997580dc13d24856ecfde3a5cbd29c /lib | |
parent | 4ba34085703951587586aa68f616087a9a95cb69 (diff) | |
download | chef-75a71fcdb1e03ba405fe0ddf1d9717e4a5c57b03.tar.gz |
Refactor HTTP streaming to reuse base implementations
Diffstat (limited to 'lib')
-rw-r--r-- | lib/chef/http.rb | 15 | ||||
-rw-r--r-- | lib/chef/rest.rb | 52 |
2 files changed, 32 insertions, 35 deletions
diff --git a/lib/chef/http.rb b/lib/chef/http.rb index 98070e097b..94d9d4d145 100644 --- a/lib/chef/http.rb +++ b/lib/chef/http.rb @@ -155,17 +155,20 @@ class Chef end def http_client - @http_client ||= BasicClient.new(create_url(url)) + BasicClient.new(create_url(url)) end # Runs a synchronous HTTP request, with no middleware applied (use #request # to have the middleware applied). The entire response will be loaded into memory. - def send_http_request(method, url, headers, body) + def send_http_request(method, url, headers, body, &response_handler) headers = build_headers(method, url, headers, body) retrying_http_errors(url) do - - request, response = http_client.request(method, url, body, headers) {|r| r.read_body } + if block_given? + request, response = http_client.request(method, url, body, headers, &response_handler) + else + request, response = http_client.request(method, url, body, headers) {|r| r.read_body } + end @last_response = response Chef::Log.debug("---- HTTP Status and Header Data: ----") @@ -182,7 +185,9 @@ class Chef [response, request, false] elsif redirect_location = redirected_to(response) if [:GET, :HEAD].include?(method) - follow_redirect {api_request(method, create_url(redirect_location))} + follow_redirect do + send_http_request(method, create_url(redirect_location), headers, body, &response_handler) + end else raise Exceptions::InvalidRedirect, "#{method} request was redirected from #{url} to #{redirect_location}. Only GET and HEAD support redirects." end diff --git a/lib/chef/rest.rb b/lib/chef/rest.rb index e93c19151a..c589373837 100644 --- a/lib/chef/rest.rb +++ b/lib/chef/rest.rb @@ -158,43 +158,35 @@ class Chef # If no block is given, the tempfile is returned, which means it's up to # you to unlink the tempfile when you're done with it. def streaming_request(url, headers, &block) + rest_request = nil # ensure this is defined, it's referenced in rescue clause + + # Manually apply middleware to avoid specifying an Accept + # application/json content type preference: method, url, headers, data = [@decompressor, @authenticator].inject([:GET, url, headers, nil]) do |req_data, middleware| middleware.handle_request(*req_data) end - headers = build_headers(method, url, headers, data) - retriable_rest_request(method, url, data, headers) do |rest_request| - begin - tempfile = nil - response = rest_request.call do |r| - if block_given? && r.kind_of?(Net::HTTPSuccess) - begin - tempfile = stream_to_tempfile(url, r, &block) - yield tempfile - ensure - tempfile.close! - end - else - tempfile = stream_to_tempfile(url, r) + response, rest_request, return_value = send_http_request(method, url, headers, data) do |http_response| + @last_response = http_response + if http_response.kind_of?(Net::HTTPSuccess) + tempfile = stream_to_tempfile(url, http_response) + if block_given? + begin + yield tempfile + ensure + tempfile && tempfile.close! end end - @last_response = response - if response.kind_of?(Net::HTTPSuccess) - tempfile - elsif redirect_location = redirected_to(response) - # TODO: test tempfile unlinked when following redirects. - tempfile && tempfile.close! - follow_redirect {streaming_request(create_url(redirect_location), {}, &block)} - else - tempfile && tempfile.close! - response.error! - end - rescue Exception => e - if e.respond_to?(:chef_rest_request=) - e.chef_rest_request = rest_request - end - raise + return tempfile end end + unless response.kind_of?(Net::HTTPSuccess) or response.kind_of?(Net::HTTPRedirection) + response.error! + end + rescue Exception => e + if e.respond_to?(:chef_rest_request=) + e.chef_rest_request = rest_request + end + raise end def follow_redirect |