diff --git a/lib/twitter/client.rb b/lib/twitter/client.rb index 6f504c667..54721b0ee 100644 --- a/lib/twitter/client.rb +++ b/lib/twitter/client.rb @@ -2856,19 +2856,13 @@ def connection end # Perform an HTTP request - def request(method, path, params, options) + def request(method, path, params={}, options={}) uri = options[:endpoint] || @endpoint uri = URI(uri) unless uri.respond_to?(:host) uri += path request_headers = {} if self.credentials? - # When posting a file, don't sign any params - signature_params = if [:post, :put].include?(method.to_sym) && params.values.any?{|value| value.is_a?(File) || (value.is_a?(Hash) && (value[:io].is_a?(IO) || value[:io].is_a?(StringIO)))} - {} - else - params - end - authorization = SimpleOAuth::Header.new(method, uri, signature_params, credentials) + authorization = auth_header(method, uri, params) request_headers[:authorization] = authorization.to_s end connection.url_prefix = options[:endpoint] || @endpoint @@ -2889,5 +2883,11 @@ def request(method, path, params, options) raise Twitter::Error::ClientError end + def auth_header(method, uri, params={}) + # When posting a file, don't sign any params + signature_params = [:post, :put].include?(method.to_sym) && params.values.any?{|value| value.is_a?(File) || (value.is_a?(Hash) && (value[:io].is_a?(IO) || value[:io].is_a?(StringIO)))} ? {} : params + SimpleOAuth::Header.new(method, uri, signature_params, credentials) + end + end end diff --git a/lib/twitter/configurable.rb b/lib/twitter/configurable.rb index b437fcdc4..3923893cd 100644 --- a/lib/twitter/configurable.rb +++ b/lib/twitter/configurable.rb @@ -58,10 +58,16 @@ def reset! private # @return [Hash] - # @note After Ruby 1.8 is deprecated, can be rewritten as: - # options.select{|key| AUTH_KEYS.include?(key)} + # @todo In version 4, rename to oauth_token to token and oauth_token_secret + # to token_secret and rewrite as: + # options.select{|key| AUTH_KEYS.include?(key)} def credentials - Hash[options.select{|key, value| AUTH_KEYS.include?(key)}] + { + :consumer_key => @consumer_key, + :consumer_secret => @consumer_secret, + :token => @oauth_token, + :token_secret => @oauth_token_secret, + } end # @return [Hash] diff --git a/spec/twitter/client_spec.rb b/spec/twitter/client_spec.rb index f43a7d28c..1632fd3ca 100644 --- a/spec/twitter/client_spec.rb +++ b/spec/twitter/client_spec.rb @@ -3,7 +3,7 @@ describe Twitter::Client do subject do - client = Twitter::Client.new + client = Twitter::Client.new(:consumer_key => "CK", :consumer_secret => "CS", :oauth_token => "OT", :oauth_token_secret => "OS") client.class_eval{public *Twitter::Client.private_instance_methods} client end @@ -92,30 +92,26 @@ end describe "#rate_limited?" do - before do - @client = Twitter::Client.new - end it "returns true for rate limited methods" do - @client.rate_limited?(:user).should be_true + subject.rate_limited?(:user).should be_true end it "returns false for rate limited methods" do - @client.rate_limited?(:rate_limit_status).should be_false + subject.rate_limited?(:rate_limit_status).should be_false end it "raises an ArgumentError for non-existant methods" do lambda do - @client.rate_limited?(:foo) + subject.rate_limited?(:foo) end.should raise_error(ArgumentError, "no method `foo' for Twitter::Client") end end describe "#put" do before do - @client = Twitter::Client.new stub_put("/custom/put"). with(:body => {:updated => "object"}) end it "allows custom put requests" do - @client.put("/custom/put", {:updated => "object"}) + subject.put("/custom/put", {:updated => "object"}) a_put("/custom/put"). with(:body => {:updated => "object"}). should have_been_made @@ -144,14 +140,11 @@ end describe "#request" do - before do - @client = Twitter::Client.new({:consumer_key => "CK", :consumer_secret => "CS", :oauth_token => "OT", :oauth_token_secret => "OS"}) - end it "encodes the entire body when no uploaded media is present" do stub_post("/1/statuses/update.json"). with(:body => {:status => "Update"}). to_return(:body => fixture("status.json"), :headers => {:content_type => "application/json; charset=utf-8"}) - @client.update("Update") + subject.update("Update") a_post("/1/statuses/update.json"). with(:body => {:status => "Update"}). should have_been_made @@ -159,16 +152,29 @@ it "encodes none of the body when uploaded media is present" do stub_post("/1/statuses/update_with_media.json", "https://upload.twitter.com"). to_return(:body => fixture("status_with_media.json"), :headers => {:content_type => "application/json; charset=utf-8"}) - @client.update_with_media("Update", fixture("pbjt.gif")) + subject.update_with_media("Update", fixture("pbjt.gif")) a_post("/1/statuses/update_with_media.json", "https://upload.twitter.com"). should have_been_made end it "catches Faraday errors" do subject.stub!(:connection).and_raise(Faraday::Error::ClientError.new("Oups")) lambda do - subject.request(:get, "/path", {}, {}) + subject.request(:get, "/path") end.should raise_error(Twitter::Error::ClientError, "Oups") end end + describe "#auth_header" do + it "creates the correct auth headers" do + uri = URI("https://api.twitter.com/1/direct_messages.json") + authorization = subject.auth_header(:get, uri) + authorization.options[:signature_method].should == "HMAC-SHA1" + authorization.options[:version].should == "1.0" + authorization.options[:consumer_key].should == "CK" + authorization.options[:consumer_secret].should == "CS" + authorization.options[:token].should == "OT" + authorization.options[:token_secret].should == "OS" + end + end + end