Class: Videojuicer::OAuth::RequestProxy
- Includes:
- Configurable, Exceptions
- Defined in:
- lib/videojuicer/oauth/request_proxy.rb
Instance Attribute Summary
Attributes included from Configurable
Instance Method Summary collapse
-
#authified_query_string(method, path, params = {}) ⇒ Object
Authifies the given parameters and converts them into a query string.
-
#authify_params(method, path, params) ⇒ Object
Takes a set of business parameters you want sent to the provider, and merges them with the proxy configuration to produce a set of parameters that will be accepted by the OAuth provider.
-
#delete(path, params = {}) ⇒ Object
Makes a DELETE request given path and params.
- #flatten_params(params, *hash_path) ⇒ Object
-
#get(path, params = {}) ⇒ Object
Makes a GET request given path and params.
-
#handle_response(response, request) ⇒ Object
Handles an HTTPResponse object appropriately.
- #host_stub ⇒ Object
-
#initialize(options = {}) ⇒ RequestProxy
constructor
Initializes a new RequestProxy object which can be used to make requests.
-
#make_request(method, host, port, path, params = {}) ⇒ Object
Does the actual work of making a request.
-
#normalize_params(params, *hash_path) ⇒ Object
Returns a string representing a normalised parameter hash.
-
#post(path, params = {}) ⇒ Object
Makes a POST request given path and params.
-
#put(path, params = {}) ⇒ Object
Makes a PUT request given path and params.
-
#request_class_for_method(m, in_module = Net::HTTP) ⇒ Object
Returns the Net::HTTPRequest subclass needed to make a request for the given method.
-
#response_error(exception_klass, request, response) ⇒ Object
Handles the response as an error of the desired type.
-
#signature(method, path, params) ⇒ Object
Calculates and returns the encrypted signature for this proxy object and the given request properties.
-
#signature_base_string(method, path, params) ⇒ Object
Returns the unencrypted signature base string for this proxy object and the given request properties.
-
#signature_secret ⇒ Object
Calculates and returns the signature secret to be used for this proxy object.
- #signed_url(method, path, params = {}) ⇒ Object
-
#split_by_signature_eligibility(params, *hash_path) ⇒ Object
Splits a given parameter hash into two hashes - one containing all string and non-binary parameters, and one containing all file/binary parameters.
Methods included from Configurable
#api_version, #config, #configure!, #consumer_key, #consumer_secret, #host, #port, #protocol, #scope, #seed_name, #token, #token_secret, #user_id
Constructor Details
#initialize(options = {}) ⇒ RequestProxy
Initializes a new RequestProxy object which can be used to make requests. Accepts all the same options as Videojuicer::configure! as well as: token
- The OAuth token to use in requests made through this proxy. token_secret
- The OAuth token secret to use when encrypting the request signature.
28 29 30 |
# File 'lib/videojuicer/oauth/request_proxy.rb', line 28 def initialize(={}) configure!() end |
Instance Method Details
#authified_query_string(method, path, params = {}) ⇒ Object
Authifies the given parameters and converts them into a query string.
182 183 184 |
# File 'lib/videojuicer/oauth/request_proxy.rb', line 182 def authified_query_string(method, path, params={}) normalize_params(authify_params(method, path, params)) end |
#authify_params(method, path, params) ⇒ Object
Takes a set of business parameters you want sent to the provider, and merges them with the proxy configuration to produce a set of parameters that will be accepted by the OAuth provider.
189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 |
# File 'lib/videojuicer/oauth/request_proxy.rb', line 189 def authify_params(method, path, params) params = { :oauth_consumer_key=>consumer_key, :oauth_token=>token, :api_version=>api_version, :oauth_timestamp=>Time.now.to_i, :oauth_nonce=>rand(9999), :oauth_signature_method=>"HMAC-SHA1", :seed_name=>seed_name, :user_id=>user_id }.merge(params) params.delete_if {|k,v| (!v) or (v.to_s.empty?) } params[:oauth_signature] = signature(method, path, params) return params end |
#delete(path, params = {}) ⇒ Object
Makes a DELETE request given path and params. The host will be ascertained from the configuration options.
46 |
# File 'lib/videojuicer/oauth/request_proxy.rb', line 46 def delete(path, params={}); make_request(:delete, host, port, path, params); end |
#flatten_params(params, *hash_path) ⇒ Object
232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 |
# File 'lib/videojuicer/oauth/request_proxy.rb', line 232 def flatten_params(params, *hash_path) op = {} params.sort {|a,b| a.to_s<=>b.to_s}.each do |key, value| path = hash_path.dup path << key.to_s if value.is_a?(Hash) op.merge! flatten_params(value, *path) elsif value key_path = path.first + path[1..(path.length-1)].collect {|h| "[#{h}]"}.join("") op[key_path] = value end end return op end |
#get(path, params = {}) ⇒ Object
Makes a GET request given path and params. The host will be ascertained from the configuration options.
34 |
# File 'lib/videojuicer/oauth/request_proxy.rb', line 34 def get(path, params={}); make_request(:get, host, port, path, params); end |
#handle_response(response, request) ⇒ Object
Handles an HTTPResponse object appropriately. Redirects are followed, error states raise errors and success responses are returned directly.
103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 |
# File 'lib/videojuicer/oauth/request_proxy.rb', line 103 def handle_response(response, request) c = response.code.to_i case c when 200..399 # Successful or redirected response response when 415 # Validation error response when 401 # Authentication problem response_error Unauthenticated, request, response when 403 # Attempted to perform a forbidden action response_error Forbidden, request, response when 404 # Resource URL not valid response_error NoResource, request, response when 406 # Excuse me WTF r u doin response_error NotAcceptable, request, response when 411 # App-side server error where request is not properly constructed. response_error ContentLengthRequired, request, response when 500..600 # Remote application failure response_error RemoteApplicationError, request, response else response_error UnhandledHTTPStatus, request, response end end |
#host_stub ⇒ Object
97 98 99 |
# File 'lib/videojuicer/oauth/request_proxy.rb', line 97 def host_stub "#{protocol}://#{host}:#{port}" end |
#make_request(method, host, port, path, params = {}) ⇒ Object
Does the actual work of making a request. Returns a Net::HTTPResponse object.
49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 |
# File 'lib/videojuicer/oauth/request_proxy.rb', line 49 def make_request(method, host, port, path, params={}) # Strip the files from the parameters to determine what, from the whole bundle, needs signing signature_params, multipart_params = split_by_signature_eligibility(params) if multipart_params.any? # Sign the params and include the as multipart multipart_params = flatten_params( authify_params(method, path, signature_params).deep_merge(multipart_params) ) query_string = "" else # Use the query string query_string = authified_query_string(method, path, signature_params) end # Generate the HTTP Request and handle the response url = "#{host_stub}#{path}" request = request_class_for_method(method).new("#{path}?#{query_string}") # Generate the multipart body and headers if multipart_params.any? post_body, content_type = Multipart::Post.new(multipart_params).to_multipart request.content_length = post_body.length request.content_type = content_type request.body = post_body else # Send a content-length on POST and PUT to avoid an HTTP 411 response case method when :post, :put request = request_class_for_method(method).new("#{path}") request.content_type = "application/x-www-form-urlencoded" request.body = query_string request.content_length = query_string.length end end begin #response = HTTPClient.send(method, url, multipart_params) response = Net::HTTP.start(host, port) {|http| http.request(request) } rescue EOFError => e raise "EOF error when accessing #{url.inspect}" rescue Errno::ECONNREFUSED => e raise "Could not connect to #{url.inspect}" end return handle_response(response, request) end |
#normalize_params(params, *hash_path) ⇒ Object
228 229 230 |
# File 'lib/videojuicer/oauth/request_proxy.rb', line 228 def normalize_params(params, *hash_path) flatten_params(params).sort {|a,b| a.to_s <=> b.to_s}.collect {|k, v| "#{CGI.rfc3986_escape(k)}=#{CGI.rfc3986_escape(v.to_s)}" }.join("&") end |
#post(path, params = {}) ⇒ Object
Makes a POST request given path and params. The host will be ascertained from the configuration options.
38 |
# File 'lib/videojuicer/oauth/request_proxy.rb', line 38 def post(path, params={}); make_request(:post, host, port, path, params); end |
#put(path, params = {}) ⇒ Object
Makes a PUT request given path and params. The host will be ascertained from the configuration options.
42 |
# File 'lib/videojuicer/oauth/request_proxy.rb', line 42 def put(path, params={}); make_request(:put, host, port, path, params); end |
#request_class_for_method(m, in_module = Net::HTTP) ⇒ Object
Returns the Net::HTTPRequest subclass needed to make a request for the given method.
249 250 251 252 253 254 255 256 257 258 259 260 261 262 |
# File 'lib/videojuicer/oauth/request_proxy.rb', line 249 def request_class_for_method(m, in_module=Net::HTTP) case (m.is_a?(Symbol) ? m : m.downcase.to_sym rescue :get) when :post in_module::Post when :put in_module::Put when :head in_module::Head when :delete in_module::Delete else in_module::Get end end |
#response_error(exception_klass, request, response) ⇒ Object
Handles the response as an error of the desired type.
136 137 138 139 140 141 142 143 144 145 |
# File 'lib/videojuicer/oauth/request_proxy.rb', line 136 def response_error(exception_klass, request, response) begin e = JSON.parse(response.body) e = e["error"] raise exception_klass, "#{e["message"]} \n #{(e["backtrace"] || []).join("\n")}" rescue JSON::ParserError raise exception_klass, "#{exception_klass.to_s} : Response code was #{response.code} for request: #{request.path}" end end |
#signature(method, path, params) ⇒ Object
Calculates and returns the encrypted signature for this proxy object and the given request properties.
207 208 209 210 211 |
# File 'lib/videojuicer/oauth/request_proxy.rb', line 207 def signature(method, path, params) base = signature_base_string(method, path, params) signature_octet = HMAC::SHA1.digest(signature_secret, base) signature_base64 = [signature_octet].pack('m').chomp.gsub(/\n/, '') end |
#signature_base_string(method, path, params) ⇒ Object
Returns the unencrypted signature base string for this proxy object and the given request properties.
220 221 222 |
# File 'lib/videojuicer/oauth/request_proxy.rb', line 220 def signature_base_string(method, path, params) s = [method.to_s.upcase, "#{protocol}://#{host}#{path}", normalize_params(params)].collect {|e| CGI.rfc3986_escape(e)}.join("&") end |
#signature_secret ⇒ Object
Calculates and returns the signature secret to be used for this proxy object.
214 215 216 |
# File 'lib/videojuicer/oauth/request_proxy.rb', line 214 def signature_secret [consumer_secret, token_secret].collect {|e| CGI.rfc3986_escape(e.to_s)}.join("&") end |
#signed_url(method, path, params = {}) ⇒ Object
177 178 179 |
# File 'lib/videojuicer/oauth/request_proxy.rb', line 177 def signed_url(method, path, params={}) "#{protocol}://#{host}:#{port}#{path}?#{authified_query_string(method, path, params)}" end |
#split_by_signature_eligibility(params, *hash_path) ⇒ Object
Splits a given parameter hash into two hashes - one containing all string and non-binary parameters, and one containing all file/binary parameters. This action is performed recursively so that:
params = {:user=>{:attributes=>{:file=>some_file, :name=>"user name"}}, :foo=>"bar"}
normal, multipart = split_multipart_params(params)
normal.inspect # => {:user=>{:attributes=>{:name=>"user name"}}, :foo=>"bar"}
multipart.inspect # => {:user=>{:attributes=>{:file=>some_file}}}
154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 |
# File 'lib/videojuicer/oauth/request_proxy.rb', line 154 def split_by_signature_eligibility(params, *hash_path) strings = {} files = {} params.each do |key, value| if value.is_a?(Hash) # Call recursively s, f = split_by_signature_eligibility(value, *(hash_path+[key])) strings = strings.deep_merge(s) files = files.deep_merge(f) else # Insert it into files at the current key path if it is a binary, # and into strings if it is not. pwd = (value.respond_to?(:read))? files : strings hash_path.each do |component| pwd[component] ||= {} pwd = pwd[component] end pwd[key] = value end end return strings, files end |