require 'em-http' require 'oauth/helper' require 'oauth/client/helper' require 'oauth/request_proxy/em_http_request' # Extensions for em-http so that we can use consumer.sign! with an EventMachine::HttpClient # instance. This is purely syntactic sugar. class EventMachine::HttpClient attr_reader :oauth_helper # Add the OAuth information to an HTTP request. Depending on the options[:scheme] setting # this may add a header, additional query string parameters, or additional POST body parameters. # The default scheme is +header+, in which the OAuth parameters as put into the +Authorization+ # header. # # * http - Configured Net::HTTP instance, ignored in this scenario except for getting host. # * consumer - OAuth::Consumer instance # * token - OAuth::Token instance # * options - Request-specific options (e.g. +request_uri+, +consumer+, +token+, +scheme+, # +signature_method+, +nonce+, +timestamp+) # # This method also modifies the User-Agent header to add the OAuth gem version. # # See Also: {OAuth core spec version 1.0, section 5.4.1}[http://oauth.net/core/1.0#rfc.section.5.4.1] def oauth!(http, consumer = nil, token = nil, options = {}) options = { :request_uri => normalized_oauth_uri(http), :consumer => consumer, :token => token, :scheme => 'header', :signature_method => nil, :nonce => nil, :timestamp => nil }.merge(options) @oauth_helper = OAuth::Client::Helper.new(self, options) self.__send__(:"set_oauth_#{options[:scheme]}") end # Create a string suitable for signing for an HTTP request. This process involves parameter # normalization as specified in the OAuth specification. The exact normalization also depends # on the options[:scheme] being used so this must match what will be used for the request # itself. The default scheme is +header+, in which the OAuth parameters as put into the +Authorization+ # header. # # * http - Configured Net::HTTP instance # * consumer - OAuth::Consumer instance # * token - OAuth::Token instance # * options - Request-specific options (e.g. +request_uri+, +consumer+, +token+, +scheme+, # +signature_method+, +nonce+, +timestamp+) # # See Also: {OAuth core spec version 1.0, section 9.1.1}[http://oauth.net/core/1.0#rfc.section.9.1.1] def signature_base_string(http, consumer = nil, token = nil, options = {}) options = { :request_uri => normalized_oauth_uri(http), :consumer => consumer, :token => token, :scheme => 'header', :signature_method => nil, :nonce => nil, :timestamp => nil }.merge(options) OAuth::Client::Helper.new(self, options).signature_base_string end protected # Since we expect to get the host etc details from the http instance (...), # we create a fake url here. Surely this is a horrible, horrible idea? def normalized_oauth_uri(http) uri = URI.parse(normalize_uri.path) uri.host = http.address uri.port = http.port if http.respond_to?(:use_ssl?) && http.use_ssl? uri.scheme = "https" else uri.scheme = "http" end uri.to_s end def set_oauth_header headers = (self.options[:head] ||= {}) headers['Authorization'] = @oauth_helper.header end def set_oauth_body raise NotImplementedError, 'please use the set_oauth_header method instead' end def set_oauth_query_string raise NotImplementedError, 'please use the set_oauth_header method instead' end end