summaryrefslogtreecommitdiff
path: root/lib/chef/rest.rb
diff options
context:
space:
mode:
Diffstat (limited to 'lib/chef/rest.rb')
-rw-r--r--lib/chef/rest.rb99
1 files changed, 98 insertions, 1 deletions
diff --git a/lib/chef/rest.rb b/lib/chef/rest.rb
index 1ca18e4ef5..f71c203b3a 100644
--- a/lib/chef/rest.rb
+++ b/lib/chef/rest.rb
@@ -26,7 +26,104 @@ require 'json'
class Chef
class REST
- def initialize(url, username)
+ def initialize(url)
+ @url = url
+ @cookies = Hash.new
+ end
+
+ # Send an HTTP GET request to the path
+ def get_rest(path)
+ run_request(:GET, create_url(path))
+ end
+
+ # Send an HTTP DELETE request to the path
+ def delete_rest(path)
+ run_request(:DELETE, create_url(path))
+ end
+
+ # Send an HTTP POST request to the path
+ def post_rest(path, json)
+ run_request(:POST, create_url(path), json)
+ end
+
+ # Send an HTTP PUT request to the path
+ def put_rest(path, json)
+ run_request(:PUT, create_url(path), json)
+ end
+
+ def create_url(path)
+ if path =~ /^(http|https):\/\//
+ URI.parse(path)
+ else
+ URI.parse("#{@url}/#{path}")
+ end
+ end
+
+ # Actually run an HTTP request. First argument is the HTTP method,
+ # which should be one of :GET, :PUT, :POST or :DELETE. Next is the
+ # URL, then an object to include in the body (which will be converted with
+ # .to_json) and finally, the limit of HTTP Redirects to follow (10).
+ #
+ # Typically, you won't use this method -- instead, you'll use one of
+ # the helper methods (get_rest, post_rest, etc.)
+ #
+ # Will return the body of the response on success.
+ def run_request(method, url, data=false, limit=10)
+ raise ArgumentError, 'HTTP redirect too deep' if limit == 0
+
+ http = Net::HTTP.new(url.host, url.port)
+ if url.scheme == "https"
+ http.use_ssl = true
+ if Chef::Config[:ssl_verify_mode] == :verify_none
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE
+ end
+ end
+ http.read_timeout = Chef::Config[:rest_timeout]
+ headers = {
+ 'Accept' => "application/json",
+ }
+ if @cookies["#{url.host}:#{url.port}"]
+ headers['Cookie'] = @cookies["#{url.host}:#{url.port}"]
+ end
+ req = nil
+ case method
+ when :GET
+ req_path = "#{url.path}"
+ req_path << "?#{url.query}" if url.query
+ req = Net::HTTP::Get.new(req_path, headers)
+ when :POST
+ headers["Content-Type"] = 'application/json' if data
+ req = Net::HTTP::Post.new(url.path, headers)
+ req.body = data.to_json if data
+ when :PUT
+ headers["Content-Type"] = 'application/json' if data
+ req = Net::HTTP::Put.new(url.path, headers)
+ req.body = data.to_json if data
+ when :DELETE
+ req_path = "#{url.path}"
+ req_path << "?#{url.query}" if url.query
+ req = Net::HTTP::Delete.new(req_path, headers)
+ else
+ raise ArgumentError, "You must provide :GET, :PUT, :POST or :DELETE as the method"
+ end
+ res = http.request(req)
+ if res.kind_of?(Net::HTTPSuccess)
+ if res['set-cookie']
+ @cookies["#{url.host}:#{url.port}"] = res['set-cookie']
+ end
+ if res['content-type'] == "application/json"
+ JSON.parse(res.body)
+ else
+ res.body
+ end
+ elsif res.kind_of?(Net::HTTPRedirection)
+ if res['set-cookie']
+ @cookies["#{url.host}:#{url.port}"] = res['set-cookie']
+ end
+ run_request(:GET, create_url(res['location']), false, limit - 1)
+ else
+ res.error!
+ end
end
end