weary 0.6.0 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -1,15 +1,13 @@
1
1
  # Weary
2
2
 
3
- _The Weary need REST_
3
+ Weary is a tiny DSL for making the consumption of RESTful web services simple. It has evolved from the ideas put forth by libraries like [HTTParty](http://github.com/jnunemaker/httparty/ "JNunemaker's HTTParty") and [Typhoeus](http://github.com/pauldix/typhoeus "Paul Dix's Typhoeus"). It provides some sweet syntactic sugar over the Net/HTTP standard library.
4
4
 
5
- Weary is a tiny DSL for making the consumption of RESTful web services simple. It is the little brother to [HTTParty](http://github.com/jnunemaker/httparty/ "JNunemaker's HTTParty"). It provides a thin, gossamer-like layer over the Net/HTTP library.
6
-
7
- The things it do:
5
+ What does it do:
8
6
 
9
7
  + Quickly build an interface to your favorite REST API.
10
8
  + Parse XML and JSON with the [Crack](http://github.com/jnunemaker/crack) library.
11
- + Authenticate, basically, with Basic Authentication.
12
- + Consume with [OAuth](http://oauth.net/)
9
+ + Authentication with Basic Authentication and [OAuth](http://oauth.net/).
10
+ + Asynchronous, multi-threaded requests.
13
11
 
14
12
  Browse the documentation here: [http://rdoc.info/projects/mwunsch/weary](http://rdoc.info/projects/mwunsch/weary)
15
13
  Peruse the [Wiki](http://wiki.github.com/mwunsch/weary) to discover libraries built with Weary and a more thorough review of the API.
@@ -19,6 +17,7 @@ Peruse the [Wiki](http://wiki.github.com/mwunsch/weary) to discover libraries bu
19
17
  + [Crack](http://github.com/jnunemaker/crack) >= 0.1.2
20
18
  + [OAuth](http://github.com/mojodna/oauth) >= 0.3.5
21
19
  + [RSpec](http://rspec.info/) (for running the tests)
20
+ + [FakeWeb](http://github.com/chrisk/fakeweb) (for running the tests)
22
21
 
23
22
  ## Installation
24
23
 
@@ -42,10 +41,9 @@ You do have Rubygems right? You do use [Gemcutter](http://gemcutter.org/), right
42
41
  me = user.show(:id => "markwunsch").perform
43
42
  puts me["name"]
44
43
 
45
- Hey, that's me!
46
-
44
+ Hey, that's me!
47
45
 
48
- ## How it works
46
+ ## The Base API/DSL
49
47
 
50
48
  Create a class that inherits from `Weary::Base` to give it methods to craft a resource request:
51
49
 
@@ -58,7 +56,7 @@ Create a class that inherits from `Weary::Base` to give it methods to craft a re
58
56
 
59
57
  If you instantiate this class, you'll get an instance method named `foo` that crafts a GET request to "http://path/to/foo"
60
58
 
61
- Besides the name of the resource, you can also give `declare_resource` a block like:
59
+ Besides the name of the resource, you can also give `declare` a block like:
62
60
 
63
61
  declare "foo" do |r|
64
62
  r.url = "path/to/foo"
@@ -73,7 +71,7 @@ Besides the name of the resource, you can also give `declare_resource` a block l
73
71
  So this would form a method:
74
72
 
75
73
  x = Foo.new
76
- x.foo(:id => "mwunsch", :bar => 123)
74
+ x.foo :id => "mwunsch", :bar => 123
77
75
 
78
76
  That method would return a `Weary::Request` object. Use the `perform` method and get a `Weary::Response` that you could parse and/or examine.
79
77
 
@@ -109,7 +107,7 @@ There are many ways to form URLs in Weary. You can define URLs for the entire cl
109
107
  get "show_users"
110
108
  end
111
109
 
112
- If you don't supply a url when declaring the Resource, Weary will look to see if you've defined a domain, and will make a url for you. The above `get` declaration creates a url that looks like: *http://foo.bar/show_users.xml*
110
+ If you don't supply a url when declaring the Resource, Weary will look to see if you've defined a domain, and will make a url for you. The above `get` declaration creates a url that looks like: *http://foo.bar/show_users.xml*. I think it's better to write the whole URL out. That's unambiguous.
113
111
 
114
112
  ### Weary DSL
115
113
 
@@ -135,5 +133,89 @@ Then you can do something like this:
135
133
  f.update
136
134
 
137
135
  Which will create a POST Request for *http://foo.bar/update.xml* that will authenticate you, using basic authentication, with the username/password of "me"/"secrets" and will send the parameter `{:user => "me"}`. Easy.
136
+
137
+ ## Weary Class Methods
138
+
139
+ Maybe you don't want the baggage that comes with `Weary::Base`. That's okay, Weary provides some basic class-level methods to Easily build a `Weary::Request`:
140
+
141
+ # See examples/repo.rb to see this in practice
142
+ class Repository
143
+
144
+ def show(user, repo)
145
+ Weary.get "http://github.com/api/v2/yaml/repos/show/#{user}/#{repo}"
146
+ end
147
+
148
+ end
149
+
150
+ Repository.new.show 'mwunsch', 'weary'
151
+
152
+ That will build the Get request to fetch the YAML info about this repository.
153
+
154
+ Pass a block to `Weary.get` to dive further into the Request:
155
+
156
+ Weary.get "http://twitter.com/statuses/user_timeline" do |req|
157
+ req.follows = false
158
+ req.with = {:id => 'markwunsch'}
159
+ req.credentials = {:username => 'markwunsch', :password => 'secret'}
160
+ req.headers = {"User-Agent" => Weary::UserAgents["Safari 4.0.2 - Mac"]}
161
+ end
162
+
163
+ ## Request Callbacks
164
+
165
+ A `Weary::Request` has a couple of callbacks you can do:
166
+
167
+ status = Weary.get("http://twitter.com/statuses/user_timeline") do |r|
168
+ r.with = {:id => 'markwunsch'}
169
+ end
170
+
171
+ status.before_send do |request|
172
+ puts "Sending a request to #{request.uri}"
173
+ end
174
+
175
+ status.on_complete do |response|
176
+ if response.success?
177
+ puts response.body
178
+ else
179
+ puts "Something went wrong: #{response.code}: #{response.message}"
180
+ end
181
+ end
182
+
183
+ `before_send` is sent just before the request is made, and `on_complete` is triggered immediately following. `before_send` passes the Request object to the block and `on_complete` passes the Response object.
184
+
185
+ You don't need to define `on_complete`, though. Passing a block to the `perform` method of the Request also defines this callback or will overwrite what you had previously defined:
186
+
187
+ status.perform do |response|
188
+ puts "Request to #{response.url}, complete. Got a #{response.code}."
189
+ end
190
+
191
+ ## Multiple Asynchronous Requests with Batch
192
+
193
+ Requests, along with the `perform` method, also has a `perform!` method, which spins off a Thread to actually perform the Net::HTTP Request. This method returns a Thread object, and is encapsulated by the `perform` method.
194
+
195
+ Weary::Batch allows you to make a group of `perform!` requests, firing at will. It takes a group of Requests.
196
+
197
+ # see examples/batch.rb
198
+ resources = %w[http://twitter.com http://github.com http://vimeo.com http://tumblr.com]
199
+ requests = []
200
+
201
+ ## build the group of requests:
202
+ resources.each do |url|
203
+ requests << Weary.get(url) do |req|
204
+ req.on_complete {|res| puts "Hello from #{res.url}"}
205
+ end
206
+ end
207
+
208
+ ## And fire them off:
209
+ Weary.batch(requests).perform
210
+
211
+ Batch has callbacks, just like the Request:
212
+
213
+ Weary.batch(requests).perform do
214
+ puts 'All done.'
215
+ end
216
+
217
+ You can investigate the pool of threads once you've called `perform` with `Batch#pool` or look at all the returned responses with `Batch#responses`.
218
+
219
+ ## And more...
138
220
 
139
- There's more to discover in the Wiki.
221
+ There's more to discover in the Wiki.
data/Rakefile CHANGED
@@ -20,42 +20,18 @@ begin
20
20
  gemspec.summary = "A little DSL for consuming RESTful web services"
21
21
  gemspec.email = "mark@markwunsch.com"
22
22
  gemspec.homepage = "http://github.com/mwunsch/weary"
23
- gemspec.description = "The Weary need REST: a tiny DSL that makes the consumption of RESTful web services simple."
23
+ gemspec.description = "A tiny DSL that makes the consumption of RESTful web services simple."
24
24
  gemspec.authors = "Mark Wunsch"
25
- gemspec.add_dependency('crack', '>= 0.1.2')
26
- gemspec.add_dependency('oauth', '>= 0.3.5')
25
+ gemspec.add_dependency 'crack', '>= 0.1.2'
26
+ gemspec.add_dependency 'oauth', '>= 0.3.5'
27
+ gemspec.add_development_dependency 'rspec'
28
+ gemspec.add_development_dependency 'fakeweb'
27
29
  end
28
30
  Jeweler::GemcutterTasks.new
29
31
  rescue LoadError
30
32
  puts "Jeweler not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
31
33
  end
32
34
 
33
- begin
34
- require 'rake/contrib/sshpublisher'
35
- namespace :rubyforge do
36
-
37
- desc "Release gem and RDoc documentation to RubyForge"
38
- task :release => ["rubyforge:release:gem", "rubyforge:release:docs"]
39
-
40
- namespace :release do
41
- desc "Publish RDoc to RubyForge."
42
- task :docs => [:rdoc] do
43
- config = YAML.load(
44
- File.read(File.expand_path('~/.rubyforge/user-config.yml'))
45
- )
46
-
47
- host = "#{config['username']}@rubyforge.org"
48
- remote_dir = "/var/www/gforge-projects/weary/"
49
- local_dir = 'doc'
50
-
51
- Rake::SshDirPublisher.new(host, remote_dir, local_dir).upload
52
- end
53
- end
54
- end
55
- rescue LoadError
56
- puts "Rake SshDirPublisher is unavailable or your rubyforge environment is not configured."
57
- end
58
-
59
35
  desc "Open an irb session preloaded with this library"
60
36
  task :console do
61
37
  sh "irb -rubygems -I lib -r weary.rb"
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.6.0
1
+ 0.7.0
@@ -0,0 +1,20 @@
1
+ $LOAD_PATH.unshift File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib'))
2
+ require 'rubygems'
3
+ require 'weary'
4
+ require 'fakeweb'
5
+ require 'pp'
6
+
7
+ hello = "Hello from"
8
+ resources = %w[http://twitter.com http://github.com http://vimeo.com http://tumblr.com]
9
+ resources.each {|url| FakeWeb.register_uri :get, url, :body => "#{hello} #{url}" }
10
+
11
+ requests = []
12
+ resources.each do |url|
13
+ requests << Weary.get(url) do |request|
14
+ request.on_complete { |response| puts response.body }
15
+ end
16
+ end
17
+
18
+ Weary.batch(requests).perform
19
+
20
+ FakeWeb.clean_registry
@@ -2,19 +2,15 @@ $LOAD_PATH.unshift File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib
2
2
  require 'rubygems'
3
3
  require 'weary'
4
4
 
5
- class Repository < Weary::Base
5
+ class Repository
6
6
 
7
- def initialize(user, repo)
8
- self.modify_resource(:show) do |r|
9
- r.url = "http://github.com/api/v2/yaml/repos/show/#{user}/#{repo}"
10
- end
11
- end
12
-
13
- get "show" do |r|
14
- r.url = "http://github.com/api/v2/yaml/repos/show/__gh_user__/__gh_repo__"
7
+ def show(user, repo)
8
+ Weary.get "http://github.com/api/v2/yaml/repos/show/#{user}/#{repo}"
15
9
  end
16
10
 
17
11
  end
18
12
 
19
- weary = Repository.new('mwunsch','weary')
20
- puts weary.show.perform.body
13
+ weary = Repository.new
14
+ weary.show('mwunsch','weary').perform do |response|
15
+ puts response.body
16
+ end
@@ -1,6 +1,7 @@
1
1
  $LOAD_PATH.unshift File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib'))
2
2
  require 'rubygems'
3
3
  require 'weary'
4
+ require 'pp'
4
5
 
5
6
  class Status < Weary::Base
6
7
 
@@ -14,5 +15,12 @@ class Status < Weary::Base
14
15
  end
15
16
 
16
17
  toots = Status.new
17
- recent_toot = toots.user_timeline(:id => "markwunsch").perform[0]
18
- puts "@" + recent_toot["user"]["screen_name"] + ": " + "\"#{recent_toot['text']}\""
18
+
19
+ toots.user_timeline(:id => "markwunsch").perform do |response|
20
+ if response.success?
21
+ recent_toot = response[0]
22
+ puts "@#{recent_toot['user']['screen_name']}: \"#{recent_toot['text']}\""
23
+ else
24
+ puts "#{response.code}: #{response.message}"
25
+ end
26
+ end
@@ -10,19 +10,23 @@ autoload :Yaml, 'yaml'
10
10
  require 'weary/request'
11
11
  require 'weary/response'
12
12
  require 'weary/resource'
13
+ require 'weary/batch'
13
14
  require 'weary/exceptions'
14
15
  require 'weary/httpverb'
15
16
  require 'weary/base'
16
17
 
17
18
  module Weary
18
19
 
20
+ # Supported HTTP Verbs
19
21
  Methods = [:get, :post, :put, :delete, :head]
22
+
23
+ # Supported Content Types
20
24
  ContentTypes = { :json => [:json, 'json', 'application/json', 'text/json', 'application/javascript', 'text/javascript'],
21
25
  :xml => [:xml, 'xml', 'text/xml', 'application/xml'],
22
26
  :html => [:html, 'html', 'text/html'],
23
27
  :yaml => [:yaml, 'yaml', 'application/x-yaml', 'text/yaml'],
24
- :plain => [:plain, 'plain', 'text/plain']
25
- }
28
+ :plain => [:plain, 'plain', 'text/plain'] }
29
+
26
30
  # A collection of User Agent strings that I stole from HURL (http://hurl.it)
27
31
  UserAgents = {
28
32
  "Firefox 1.5.0.12 - Mac" => "Mozilla/5.0 (Macintosh; U; PPC Mac OS X Mach-O; en-US; rv:1.8.0.12) Gecko/20070508 Firefox/1.5.0.12",
@@ -33,7 +37,7 @@ module Weary
33
37
  "Firefox 3.0.4 - Windows" => "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.12) Gecko/2008102920 Firefox/3.0.4",
34
38
  "Firefox 3.5.2 - Mac" => "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.1.2) Gecko/20090729 Firefox/3.5.2",
35
39
  "Firefox 3.5.2 - Windows" => "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.1.2) Gecko/20090729 Firefox/3.5.2",
36
- "Internet Explorer 5.2.3 Mac" => "Mozilla/4.0 (compatible; MSIE 5.23; Mac_PowerPC)",
40
+ "Internet Explorer 5.2.3 - Mac" => "Mozilla/4.0 (compatible; MSIE 5.23; Mac_PowerPC)",
37
41
  "Internet Explorer 5.5" => "Mozilla/4.0 (compatible; MSIE 5.5; Windows NT 5.1)",
38
42
  "Internet Explorer 6.0" => "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)",
39
43
  "Internet Explorer 7.0" => "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0)",
@@ -55,10 +59,39 @@ module Weary
55
59
  "Safari 4.0.2 - Windows" => "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/530.19.2 (KHTML, like Gecko) Version/4.0.2 Safari/530.19.1"
56
60
  }
57
61
 
58
- # Weary::Query quickly performs a GET request on a URL and parses the request.
59
- def self.Query(url)
60
- req = Weary::Request.new(url, :get).perform
61
- req.parse
62
+ class << self
63
+ def get(url,&block)
64
+ request url, :get, block
65
+ end
66
+
67
+ def post(url,&block)
68
+ request url, :post, block
69
+ end
70
+
71
+ def put(url,&block)
72
+ request url, :put, block
73
+ end
74
+
75
+ def delete(url,&block)
76
+ request url, :delete, block
77
+ end
78
+
79
+ def head(url,&block)
80
+ request url, :head, block
81
+ end
82
+
83
+ # Create a Request for the URL.
84
+ # Defaults to a GET Request. Use a block to further modify the Request
85
+ def request(url,via = :get,block = nil)
86
+ req = Request.new(url,via)
87
+ block.call(req) if block
88
+ req
89
+ end
90
+
91
+ # Create a Batch for a group of Requests
92
+ def batch(*requests)
93
+ Batch.new(requests)
94
+ end
62
95
  end
63
96
 
64
97
  end
@@ -16,8 +16,7 @@ module Weary
16
16
 
17
17
  # Each Weary::Base object has its own set of Resources
18
18
  def resources
19
- @resources = Marshal.load(Marshal.dump(@@resources)) if !@resources
20
- @resources
19
+ @resources ||= Marshal.load(Marshal.dump(@@resources))
21
20
  end
22
21
 
23
22
  # Make changes to a Resource given and rebuild the Request method for this object
@@ -0,0 +1,37 @@
1
+ module Weary
2
+ class Batch
3
+
4
+ attr_accessor :requests, :pool, :responses
5
+
6
+ def initialize(*requests)
7
+ @requests = requests.flatten
8
+ end
9
+
10
+ # A callback that is triggered after all the Responses have been received.
11
+ def on_complete(&block)
12
+ @on_complete = block if block_given?
13
+ @on_complete
14
+ end
15
+
16
+ # A callback that is triggered before the Requests are performed
17
+ def before_send(&block)
18
+ @before_send = block if block_given?
19
+ @before_send
20
+ end
21
+
22
+ # Perform each Request in a separate Thread.
23
+ # The Threads are collected in `pool`.
24
+ # The Responses are collected in `responses`.
25
+ # Pass in a block to use as the on_complete callback.
26
+ def perform(&block)
27
+ @on_complete = block if block_given?
28
+ @responses = []
29
+ @pool = []
30
+ before_send.call if before_send
31
+ requests.each {|req| @pool << req.perform! }
32
+ pool.each {|res| @responses << res.value }
33
+ on_complete.call if on_complete
34
+ responses
35
+ end
36
+ end
37
+ end
@@ -11,5 +11,5 @@ module Weary
11
11
  class NotFound < ClientError; end #404
12
12
  class MethodNotAllowed < ClientError; end #405
13
13
  class ResourceConflict < ClientError; end #409
14
- class UnprocessableEntity < ClientError; end #422
14
+ class UnprocessableEntity < ClientError; end #422
15
15
  end
@@ -6,7 +6,7 @@ module Weary
6
6
  def initialize(http_verb = :get)
7
7
  self.verb = http_verb
8
8
  end
9
-
9
+
10
10
  def normalize
11
11
  return verb.to_s.strip.downcase.intern
12
12
  end
@@ -24,7 +24,7 @@ module Weary
24
24
  when :head
25
25
  Net::HTTP::Head
26
26
  else
27
- Net::HTTP::Get
27
+ raise "Weary does not recognize the HTTP verb '#{normalize.inspect}'."
28
28
  end
29
29
  end
30
30
 
@@ -1,20 +1,34 @@
1
1
  module Weary
2
2
  class Request
3
3
 
4
- attr_reader :uri
5
- attr_accessor :options
4
+ attr_reader :uri, :with, :credentials
5
+ attr_accessor :headers
6
6
 
7
7
  def initialize(url, http_verb= :get, options={})
8
- self.method = http_verb
9
8
  self.uri = url
10
- self.options = options
9
+ self.via = http_verb
10
+ self.credentials = {:username => options[:basic_auth][:username],
11
+ :password => options[:basic_auth][:password]} if options[:basic_auth]
12
+ self.credentials = options[:oauth] if options[:oauth]
13
+ if (options[:body])
14
+ self.with = options[:body]
15
+ end
16
+ self.headers = options[:headers] if options[:headers]
17
+ self.follows = true
18
+ if options.has_key?(:no_follow)
19
+ self.follows = options[:no_follow] ? false : true
20
+ end
11
21
  end
12
-
22
+
23
+ # Create a URI object for the given URL
13
24
  def uri=(url)
14
25
  @uri = URI.parse(url)
26
+ if (with && !request_preparation.request_body_permitted?)
27
+ @uri.query = with
28
+ end
15
29
  end
16
30
 
17
- def method=(http_verb)
31
+ def via=(http_verb)
18
32
  verb = HTTPVerb.new(http_verb).normalize
19
33
  @http_verb = if Methods.include?(verb)
20
34
  verb
@@ -23,44 +37,113 @@ module Weary
23
37
  end
24
38
  end
25
39
 
26
- def method
40
+ def via
27
41
  @http_verb
28
42
  end
29
43
 
30
- def perform
31
- req = http.request(request)
32
- response = Response.new(req, @http_verb)
33
- if response.redirected?
34
- return response if options[:no_follow]
35
- response.follow_redirect
44
+ # Set parameters to send with the Request.
45
+ # If this Request does not accept a body (a GET request for instance),
46
+ # set the query string for the url.
47
+ def with=(params)
48
+ @with = (params.respond_to?(:to_params) ? params.to_params : params)
49
+ if (!request_preparation.request_body_permitted?)
50
+ uri.query = @with
36
51
  end
37
- response
38
52
  end
39
53
 
40
- private
41
- def http
42
- connection = Net::HTTP.new(@uri.host, @uri.port)
43
- connection.use_ssl = @uri.is_a?(URI::HTTPS)
44
- connection.verify_mode = OpenSSL::SSL::VERIFY_NONE if connection.use_ssl
45
- connection
54
+ # Credentials to send to Authorize the Request
55
+ # For basic auth, use a hash with keys :username and :password
56
+ # For OAuth, use an Access Token
57
+ def credentials=(auth)
58
+ if auth.is_a?(OAuth::AccessToken)
59
+ @credentials = auth
60
+ else
61
+ @credentials = {:username => auth[:username], :password => auth[:password]}
46
62
  end
63
+ end
64
+
65
+ # Should the Request follow redirects?
66
+ def follows=(bool)
67
+ @follows = (bool ? true : false)
68
+ end
69
+
70
+ def follows?
71
+ @follows
72
+ end
73
+
74
+ # A callback that is triggered after the Response is received.
75
+ def on_complete(&block)
76
+ @on_complete = block if block_given?
77
+ @on_complete
78
+ end
47
79
 
48
- def request
49
- request_class = HTTPVerb.new(@http_verb).request_class
50
- prepare = request_class.new(@uri.request_uri)
51
-
52
- prepare.body = options[:body].is_a?(Hash) ? options[:body].to_params : options[:body] if options[:body]
53
- prepare.basic_auth(options[:basic_auth][:username], options[:basic_auth][:password]) if options[:basic_auth]
54
- if options[:headers]
55
- options[:headers].each_pair do |key, value|
56
- prepare[key] = value
57
- end
80
+ # A callback that is sent before the Request is fired.
81
+ def before_send(&block)
82
+ @before_send = block if block_given?
83
+ @before_send
84
+ end
85
+
86
+ # Perform the Request, returns the Response. Pass a block in to use
87
+ # as the on_complete callback.
88
+ def perform(&block)
89
+ @on_complete = block if block_given?
90
+ response = perform!
91
+ response.value
92
+ end
93
+
94
+ # Spins off a new thread to perform the Request.
95
+ def perform!(&block)
96
+ @on_complete = block if block_given?
97
+ Thread.new {
98
+ before_send.call(self) if before_send
99
+ req = http.request(request)
100
+ response = Response.new(req, self)
101
+ if response.redirected? && follows?
102
+ response.follow_redirect
103
+ else
104
+ on_complete.call(response) if on_complete
105
+ response
58
106
  end
59
- if options[:oauth]
60
- options[:oauth].sign!(prepare)
107
+ }
108
+ end
109
+
110
+ # Build the HTTP connection.
111
+ def http
112
+ connection = Net::HTTP.new(uri.host, uri.port)
113
+ connection.verify_mode = OpenSSL::SSL::VERIFY_NONE if connection.use_ssl?
114
+ connection
115
+ end
116
+
117
+ # Build the HTTP Request.
118
+ def request
119
+ req = request_preparation
120
+
121
+ req.body = with if (with && req.request_body_permitted?)
122
+ if (credentials)
123
+ if (credentials.is_a?(OAuth::AccessToken))
124
+ credentials.sign!(req)
125
+ else
126
+ req.basic_auth(credentials[:username], credentials[:password])
127
+ end
128
+ end
129
+
130
+ if headers
131
+ headers.each_pair do |key, value|
132
+ req[key] = value
61
133
  end
62
- prepare
63
134
  end
135
+
136
+ req
137
+ end
138
+
139
+ # Prepare the HTTP Request.
140
+ # The Request has a lifecycle:
141
+ # Prepare with `request_preparation`
142
+ # Build with `request`
143
+ # Fire with `perform`
144
+ def request_preparation
145
+ HTTPVerb.new(via).request_class.new(uri.request_uri)
146
+ end
64
147
 
65
148
  end
66
149
  end