class StudioApi::GenericRequest
Class which use itself direct connection to studio for tasks where ActiveResource is not enough. For consistent api is all network exceptions mapped to ones used in ActiveResource.
@example
rq = StudioApi::GenericRequest.new @connection rq.get "/appliances" rq.post "/file", :file => "/etc/config"
Public Class Methods
Creates new instance of request for given connection @param (StudioApi::Connection
) connection information about connection
# File lib/studio_api/generic_request.rb 43 def initialize(connection) 44 @connection = connection 45 if connection.proxy 46 proxy = connection.proxy 47 @http = Net::HTTP.new(connection.uri.host, connection.uri.port, 48 proxy.host, proxy.port, proxy.user, proxy.password) 49 else 50 @http = Net::HTTP.new(connection.uri.host, connection.uri.port) 51 end 52 @http.read_timeout = connection.timeout 53 if connection.uri.scheme == "https" 54 @http.use_ssl = true 55 Connection::SSL_ATTRIBUTES.each do |attr| 56 @http.send :"#{attr}=", connection.ssl[attr.to_sym] if connection.ssl[attr.to_sym] 57 end 58 end 59 end
Public Instance Methods
sends delete request @param (String) path relative path from api root @return (String) response body from studio @raise [ActiveResource::ConnectionError] when problem occur during connection
# File lib/studio_api/generic_request.rb 82 def delete(path) 83 #Even it is not dry I want to avoid meta programming with dynamic code evaluation so code is clear 84 do_request(Net::HTTP::Delete.new(Util.join_relative_url(@connection.uri.request_uri,path))) 85 end
sends get request @param (String) path relative path from api root @return (String) response body from studio @raise [ActiveResource::ConnectionError] when problem occur during connection
# File lib/studio_api/generic_request.rb 65 def get(path) 66 do_request(Net::HTTP::Get.new(Util.join_relative_url(@connection.uri.request_uri,path))) 67 end
sends get request to suse studio @return (nil) as response @raise [ActiveResource::ConnectionError] when problem occur during connection
# File lib/studio_api/generic_request.rb 72 def get_file(path, &block) 73 do_file_request(Net::HTTP::Get.new( 74 Util.join_relative_url(@connection.uri.request_uri,path)), 75 &block) 76 end
sends post request @param (String) path relative path from api root @param (Hash<#to_s,#to_s>,Hash<#to_s,#path>) data hash containing data to attach to body @return (String) response body from studio @raise [ActiveResource::ConnectionError] when problem occur during connection
# File lib/studio_api/generic_request.rb 92 def post(path,data={}) 93 request = Net::HTTP::Post.new(Util.join_relative_url(@connection.uri.request_uri,path)) 94 set_data(request,data) unless data.empty? 95 do_request request 96 end
sends post request @param (String) path relative path from api root @param (Hash<#to_s,#to_s>,Hash<#to_s,#path>) data hash containing data to attach to body @return (String) response body from studio @raise [ActiveResource::ConnectionError] when problem occur during connection
# File lib/studio_api/generic_request.rb 103 def put(path,data={}) 104 request = Net::HTTP::Put.new(Util.join_relative_url(@connection.uri.request_uri,path)) 105 set_data(request,data) unless data.empty? 106 do_request request 107 end
Private Instance Methods
# File lib/studio_api/generic_request.rb 119 def do_file_request request, &block 120 request.basic_auth @connection.user, @connection.password 121 @http.start do |http| 122 http.request request do |response| 123 handle_active_resource_exception response 124 response.read_body {|body| yield body } 125 end 126 end 127 end
# File lib/studio_api/generic_request.rb 110 def do_request(request) 111 request.basic_auth @connection.user, @connection.password 112 @http.start() do 113 response = @http.request request 114 handle_active_resource_exception response 115 response.body 116 end 117 end
# File lib/studio_api/generic_request.rb 138 def error_message response 139 xml_parsed = XmlSimple.xml_in(response.body, {'KeepRoot' => true}) 140 raise "Unknown error response from Studio: #{response.body}" unless xml_parsed['error'] 141 msg = "" 142 xml_parsed['error'].each() {|error| msg << error['message'][0]+"\n" } 143 return msg 144 rescue RuntimeError 145 return response.message+"\n"+response.body 146 end
XXX not so nice to use internal method, but better to be DRY and proper test if it works with supported rails
# File lib/studio_api/generic_request.rb 130 def handle_active_resource_exception response 131 unless response.kind_of? Net::HTTPSuccess 132 msg = error_message response 133 response.instance_variable_set "@message",msg 134 ActiveResource::Connection.new('').send :handle_response, response 135 end 136 end
# File lib/studio_api/generic_request.rb 174 def mime_type(file) 175 case 176 when file =~ /\.jpe?g\z/i then 'image/jpg' 177 when file =~ /\.gif\z/i then 'image/gif' 178 when file =~ /\.png\z/i then 'image/png' 179 else 'application/octet-stream' 180 end 181 end
# File lib/studio_api/generic_request.rb 148 def set_data(request,data) 149 if data[:__raw] 150 request.body = data[:__raw] 151 else 152 boundary = Time.now.to_i.to_s(16) 153 request["Content-Type"] = "multipart/form-data; boundary=#{boundary}" 154 body = "" 155 data.each do |key,value| 156 esc_key = CGI.escape(key.to_s) 157 body << "--#{boundary}\r\n" 158 if value.respond_to?(:read) && value.respond_to?(:path) 159 # ::File is needed to use "Ruby" file instead this one 160 body << "Content-Disposition: form-data; name=\"#{esc_key}\"; filename=\"#{::File.basename(value.path)}\"\r\n" 161 body << "Content-Type: #{mime_type(value.path)}\r\n\r\n" 162 body << value.read 163 else 164 body << "Content-Disposition: form-data; name=\"#{esc_key}\"\r\n\r\n#{value}" 165 end 166 body << "\r\n" 167 end 168 body << "--#{boundary}--\r\n\r\n" 169 request.body = body 170 request["Content-Length"] = request.body.size 171 end 172 end