diff options
author | Daniel DeLeo <dan@opscode.com> | 2010-07-22 17:17:38 -0700 |
---|---|---|
committer | Daniel DeLeo <dan@opscode.com> | 2010-07-22 17:17:38 -0700 |
commit | c95c31a36e62b216f1afeec27b3cec927bcd1aa3 (patch) | |
tree | aab5a981f29d6489481144507301f1df5b097e55 /chef/lib/chef/cookbook_site_streaming_uploader.rb | |
parent | 0100df72eb2a66c9d07de46a04fcacfd4c7d9c14 (diff) | |
download | chef-c95c31a36e62b216f1afeec27b3cec927bcd1aa3.tar.gz |
purge whitespace and add license header
Diffstat (limited to 'chef/lib/chef/cookbook_site_streaming_uploader.rb')
-rw-r--r-- | chef/lib/chef/cookbook_site_streaming_uploader.rb | 79 |
1 files changed, 48 insertions, 31 deletions
diff --git a/chef/lib/chef/cookbook_site_streaming_uploader.rb b/chef/lib/chef/cookbook_site_streaming_uploader.rb index 4a6e751f77..932661785e 100644 --- a/chef/lib/chef/cookbook_site_streaming_uploader.rb +++ b/chef/lib/chef/cookbook_site_streaming_uploader.rb @@ -1,29 +1,48 @@ +# +# Author:: Stanislav Vitvitskiy +# Author:: Nuo Yan (nuo@opscode.com) +# Author:: Christopher Walters (<cw@opscode.com>) +# Copyright:: Copyright (c) 2009, 2010 Opscode, Inc. +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + require 'net/http' require 'mixlib/authentication/signedheaderauth' require 'openssl' -# inspired by/cargo-culted from http://stanislavvitvitskiy.blogspot.com/2008/12/multipart-post-in-ruby.html -# TODO: confirm that code is public domain +# inspired by from http://stanislavvitvitskiy.blogspot.com/2008/12/multipart-post-in-ruby.html class Chef class CookbookSiteStreamingUploader DefaultHeaders = { 'accept' => 'application/json', 'x-chef-version' => ::Chef::VERSION } - + class << self def post(to_url, user_id, secret_key_filename, params = {}, headers = {}) make_request(:post, to_url, user_id, secret_key_filename, params, headers) end - + def put(to_url, user_id, secret_key_filename, params = {}, headers = {}) make_request(:put, to_url, user_id, secret_key_filename, params, headers) end - + def make_request(http_verb, to_url, user_id, secret_key_filename, params = {}, headers = {}) boundary = '----RubyMultipartClient' + rand(1000000).to_s + 'ZZZZZ' parts = [] content_file = nil - + timestamp = Time.now.utc.iso8601 secret_key = OpenSSL::PKey::RSA.new(File.read(secret_key_filename)) @@ -46,31 +65,31 @@ class Chef end parts << StringPart.new("--" + boundary + "--\r\n") end - + body_stream = MultipartStream.new(parts) - + timestamp = Time.now.utc.iso8601 - + url = URI.parse(to_url) - + Chef::Log.logger.debug("Signing: method: #{http_verb}, path: #{url.path}, file: #{content_file}, User-id: #{user_id}, Timestamp: #{timestamp}") - + # We use the body for signing the request if the file parameter - # wasn't a valid file or wasn't included. Extract the body (with + # wasn't a valid file or wasn't included. Extract the body (with # multi-part delimiters intact) to sign the request. # TODO: tim: 2009-12-28: It'd be nice to remove this special case, and # always hash the entire request body. In the file case it would just be # expanded multipart text - the entire body of the POST. content_body = parts.inject("") { |result,part| result + part.read(0, part.size) } content_file.rewind if content_file # we consumed the file for the above operation, so rewind it. - + signing_options = { :http_method=>http_verb, :path=>url.path, :user_id=>user_id, :timestamp=>timestamp} (content_file && signing_options[:file] = content_file) || (signing_options[:body] = (content_body || "")) - + headers.merge!(Mixlib::Authentication::SignedHeaderAuth.signing_object(signing_options).sign(secret_key)) content_file.rewind if content_file @@ -83,11 +102,11 @@ class Chef Net::HTTP::Put.new(url.path, headers) when :post Net::HTTP::Post.new(url.path, headers) - end + end req.content_length = body_stream.size req.content_type = 'multipart/form-data; boundary=' + boundary unless parts.empty? req.body_stream = body_stream - + http = Net::HTTP.new(url.host, url.port) if url.scheme == "https" http.use_ssl = true @@ -100,30 +119,30 @@ class Chef # TODO: stop the following madness! class << res alias :to_s :body - + # BUGBUG this makes the response compatible with what respsonse_steps expects to test headers (response.headers[] -> response[]) def headers self end - + def status code.to_i end end res end - + end class StreamPart def initialize(stream, size) @stream, @size = stream, size end - + def size @size end - + # read the specified amount from the stream def read(offset, how_much) @stream.read(how_much) @@ -134,7 +153,7 @@ class Chef def initialize(str) @str = str end - + def size @str.length end @@ -151,26 +170,26 @@ class Chef @part_no = 0 @part_offset = 0 end - + def size @parts.inject(0) {|size, part| size + part.size} end - + def read(how_much) return nil if @part_no >= @parts.size how_much_current_part = @parts[@part_no].size - @part_offset - + how_much_current_part = if how_much_current_part > how_much how_much else how_much_current_part end - + how_much_next_part = how_much - how_much_current_part current_part = @parts[@part_no].read(@part_offset, how_much_current_part) - + # recurse into the next part if the current one was not large enough if how_much_next_part > 0 @part_no += 1 @@ -187,8 +206,6 @@ class Chef end end end - - end - -end
\ No newline at end of file + end +end |