faraday 0.7.6 → 0.8.0.rc2

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile CHANGED
@@ -1,4 +1,4 @@
1
- source 'http://rubygems.org'
1
+ source 'https://rubygems.org'
2
2
 
3
3
  group :development do
4
4
  gem 'sinatra', '~> 1.2'
@@ -14,9 +14,6 @@ end
14
14
  platforms :ruby do
15
15
  gem 'patron', '~> 0.4'
16
16
  gem 'typhoeus', '~> 0.3'
17
- # ActiveSupport::JSON will be used in ruby 1.8 and Yajl in 1.9; this is to test against both adapters
18
- gem 'activesupport', '~> 2.3', :require => nil, :platforms => [:ruby_18, :jruby]
19
- gem 'yajl-ruby', '~> 1.0', :require => 'yajl', :platforms => :ruby_19
20
17
  end
21
18
 
22
19
  platforms :jruby do
data/README.md CHANGED
@@ -1,177 +1,195 @@
1
- faraday
2
- =======
3
- Modular HTTP client library using middleware heavily inspired by Rack.
1
+ # faraday [![Build Status](https://secure.travis-ci.org/technoweenie/faraday.png?branch=master)][travis] [![Dependency Status](https://gemnasium.com/technoweenie/faraday.png?travis)][gemnasium]
2
+ Modular HTTP client library that uses middleware. Heavily inspired by Rack.
4
3
 
5
- This mess is gonna get raw, like sushi. So, haters to the left.
4
+ [travis]: http://travis-ci.org/technoweenie/faraday
5
+ [gemnasium]: https://gemnasium.com/technoweenie/faraday
6
6
 
7
- Usage
8
- -----
9
- conn = Faraday.new(:url => 'http://sushi.com') do |builder|
10
- builder.use Faraday::Request::UrlEncoded # convert request params as "www-form-urlencoded"
11
- builder.use Faraday::Request::JSON # encode request params as json
12
- builder.use Faraday::Response::Logger # log the request to STDOUT
13
- builder.use Faraday::Adapter::NetHttp # make http requests with Net::HTTP
7
+ ## <a name="usage"></a>Usage
14
8
 
15
- # or, use shortcuts:
16
- builder.request :url_encoded
17
- builder.request :json
18
- builder.response :logger
19
- builder.adapter :net_http
20
- end
9
+ ```ruby
10
+ conn = Faraday.new(:url => 'http://sushi.com') do |builder|
11
+ builder.use Faraday::Request::UrlEncoded # convert request params as "www-form-urlencoded"
12
+ builder.use Faraday::Response::Logger # log the request to STDOUT
13
+ builder.use Faraday::Adapter::NetHttp # make http requests with Net::HTTP
21
14
 
22
- ## GET ##
15
+ # or, use shortcuts:
16
+ builder.request :url_encoded
17
+ builder.response :logger
18
+ builder.adapter :net_http
19
+ end
23
20
 
24
- response = conn.get '/nigiri/sake.json' # GET http://sushi.com/nigiri/sake.json
25
- response.body
21
+ ## GET ##
26
22
 
27
- conn.get '/nigiri', 'X-Awesome' => true # custom request header
23
+ response = conn.get '/nigiri/sake.json' # GET http://sushi.com/nigiri/sake.json
24
+ response.body
28
25
 
29
- conn.get do |req| # GET http://sushi.com/search?page=2&limit=100
30
- req.url '/search', :page => 2
31
- req.params['limit'] = 100
32
- end
26
+ conn.get '/nigiri', 'X-Awesome' => true # custom request header
33
27
 
34
- ## POST ##
28
+ conn.get do |req| # GET http://sushi.com/search?page=2&limit=100
29
+ req.url '/search', :page => 2
30
+ req.params['limit'] = 100
31
+ end
35
32
 
36
- conn.post '/nigiri', { :name => 'Maguro' } # POST "name=maguro" to http://sushi.com/nigiri
33
+ ## POST ##
37
34
 
38
- # post payload as JSON instead of "www-form-urlencoded" encoding:
39
- conn.post '/nigiri', payload, 'Content-Type' => 'application/json'
35
+ conn.post '/nigiri', { :name => 'Maguro' } # POST "name=maguro" to http://sushi.com/nigiri
40
36
 
41
- # a more verbose way:
42
- conn.post do |req|
43
- req.url '/nigiri'
44
- req.headers['Content-Type'] = 'application/json'
45
- req.body = { :name => 'Unagi' }
46
- end
37
+ # post payload as JSON instead of "www-form-urlencoded" encoding:
38
+ conn.post do |req|
39
+ req.url '/nigiri'
40
+ req.headers['Content-Type'] = 'application/json'
41
+ req.body = '{ "name": "Unagi" }'
42
+ end
43
+
44
+ ## Options ##
45
+
46
+ conn.get do |req|
47
+ req.url '/search'
48
+ req.options = {
49
+ :timeout => 5, # open/read timeout Integer in seconds
50
+ :open_timeout => 2, # read timeout Integer in seconds
51
+ :proxy => {
52
+ :uri => "http://example.org/", # proxy server URI
53
+ :user => "me", # proxy server username
54
+ :password => "test123" # proxy server password
55
+ }
56
+ }
57
+ end
58
+ ```
47
59
 
48
60
  If you're ready to roll with just the bare minimum:
49
61
 
50
- # default stack (net/http), no extra middleware:
51
- response = Faraday.get 'http://sushi.com/nigiri/sake.json'
62
+ ```ruby
63
+ # default stack (net/http), no extra middleware:
64
+ response = Faraday.get 'http://sushi.com/nigiri/sake.json'
65
+ ```
52
66
 
53
- Advanced middleware usage
54
- -------------------------
67
+ ## Advanced middleware usage
55
68
  The order in which middleware is stacked is important. Like with Rack, the first middleware on the list wraps all others, while the last middleware is the innermost one, so that's usually the adapter.
56
69
 
57
- conn = Faraday.new(:url => 'http://sushi.com') do |builder|
58
- # POST/PUT params encoders:
59
- builder.request :multipart
60
- builder.request :url_encoded
61
- builder.request :json
70
+ ```ruby
71
+ conn = Faraday.new(:url => 'http://sushi.com') do |builder|
72
+ # POST/PUT params encoders:
73
+ builder.request :multipart
74
+ builder.request :url_encoded
62
75
 
63
- builder.adapter :net_http
64
- end
76
+ builder.adapter :net_http
77
+ end
78
+ ```
65
79
 
66
80
  This request middleware setup affects POST/PUT requests in the following way:
67
81
 
68
82
  1. `Request::Multipart` checks for files in the payload, otherwise leaves everything untouched;
69
83
  2. `Request::UrlEncoded` encodes as "application/x-www-form-urlencoded" if not already encoded or of another type
70
- 2. `Request::JSON` encodes as "application/json" if not already encoded or of another type
71
84
 
72
- Because "UrlEncoded" is higher on the stack than JSON encoder, it will get to process the request first. Swapping them means giving the other priority. Specifying the "Content-Type" for the request is explicitly stating which middleware should process it.
85
+ Swapping middleware means giving the other priority. Specifying the "Content-Type" for the request is explicitly stating which middleware should process it.
73
86
 
74
87
  Examples:
75
88
 
76
- payload = { :name => 'Maguro' }
89
+ ```ruby
90
+ payload = { :name => 'Maguro' }
77
91
 
78
- # post payload as JSON instead of urlencoded:
79
- conn.post '/nigiri', payload, 'Content-Type' => 'application/json'
92
+ # uploading a file:
93
+ payload = { :profile_pic => Faraday::UploadIO.new('avatar.jpg', 'image/jpeg') }
80
94
 
81
- # uploading a file:
82
- payload = { :profile_pic => Faraday::UploadIO.new('avatar.jpg', 'image/jpeg') }
95
+ # "Multipart" middleware detects files and encodes with "multipart/form-data":
96
+ conn.put '/profile', payload
97
+ ```
83
98
 
84
- # "Multipart" middleware detects files and encodes with "multipart/form-data":
85
- conn.put '/profile', payload
86
-
87
- Writing middleware
88
- ------------------
99
+ ## Writing middleware
89
100
  Middleware are classes that respond to `call()`. They wrap the request/response cycle.
90
101
 
91
- def call(env)
92
- # do something with the request
102
+ ```ruby
103
+ def call(env)
104
+ # do something with the request
93
105
 
94
- @app.call(env).on_complete do
95
- # do something with the response
96
- end
97
- end
106
+ @app.call(env).on_complete do
107
+ # do something with the response
108
+ end
109
+ end
110
+ ```
98
111
 
99
112
  It's important to do all processing of the response only in the `on_complete` block. This enables middleware to work in parallel mode where requests are asynchronous.
100
113
 
101
114
  The `env` is a hash with symbol keys that contains info about the request and, later, response. Some keys are:
102
115
 
103
- # request phase
104
- :method - :get, :post, ...
105
- :url - URI for the current request; also contains GET parameters
106
- :body - POST parameters for :post/:put requests
107
- :request_headers
108
-
109
- # response phase
110
- :status - HTTP response status code, such as 200
111
- :body - the response body
112
- :response_headers
113
-
114
- Testing
115
- -------
116
- # It's possible to define stubbed request outside a test adapter block.
117
- stubs = Faraday::Adapter::Test::Stubs.new do |stub|
118
- stub.get('/tamago') { [200, {}, 'egg'] }
119
- end
120
-
121
- # You can pass stubbed request to the test adapter or define them in a block
122
- # or a combination of the two.
123
- test = Faraday.new do |builder|
124
- builder.adapter :test, stubs do |stub|
125
- stub.get('/ebi') {[ 200, {}, 'shrimp' ]}
126
- end
127
- end
128
-
129
- # It's also possible to stub additional requests after the connection has
130
- # been initialized. This is useful for testing.
131
- stubs.get('/uni') {[ 200, {}, 'urchin' ]}
132
-
133
- resp = test.get '/tamago'
134
- resp.body # => 'egg'
135
- resp = test.get '/ebi'
136
- resp.body # => 'shrimp'
137
- resp = test.get '/uni'
138
- resp.body # => 'urchin'
139
- resp = test.get '/else' #=> raises "no such stub" error
140
-
141
- # If you like, you can treat your stubs as mocks by verifying that all of
142
- # the stubbed calls were made. NOTE that this feature is still fairly
143
- # experimental: It will not verify the order or count of any stub, only that
144
- # it was called once during the course of the test.
145
- stubs.verify_stubbed_calls
146
-
147
- TODO
148
- ----
116
+ ```
117
+ # request phase
118
+ :method - :get, :post, ...
119
+ :url - URI for the current request; also contains GET parameters
120
+ :body - POST parameters for :post/:put requests
121
+ :request_headers
122
+
123
+ # response phase
124
+ :status - HTTP response status code, such as 200
125
+ :body - the response body
126
+ :response_headers
127
+ ```
128
+
129
+ ## <a name="testing"></a>Testing
130
+
131
+ ```ruby
132
+ # It's possible to define stubbed request outside a test adapter block.
133
+ stubs = Faraday::Adapter::Test::Stubs.new do |stub|
134
+ stub.get('/tamago') { [200, {}, 'egg'] }
135
+ end
136
+
137
+ # You can pass stubbed request to the test adapter or define them in a block
138
+ # or a combination of the two.
139
+ test = Faraday.new do |builder|
140
+ builder.adapter :test, stubs do |stub|
141
+ stub.get('/ebi') {[ 200, {}, 'shrimp' ]}
142
+ end
143
+ end
144
+
145
+ # It's also possible to stub additional requests after the connection has
146
+ # been initialized. This is useful for testing.
147
+ stubs.get('/uni') {[ 200, {}, 'urchin' ]}
148
+
149
+ resp = test.get '/tamago'
150
+ resp.body # => 'egg'
151
+ resp = test.get '/ebi'
152
+ resp.body # => 'shrimp'
153
+ resp = test.get '/uni'
154
+ resp.body # => 'urchin'
155
+ resp = test.get '/else' #=> raises "no such stub" error
156
+
157
+ # If you like, you can treat your stubs as mocks by verifying that all of
158
+ # the stubbed calls were made. NOTE that this feature is still fairly
159
+ # experimental: It will not verify the order or count of any stub, only that
160
+ # it was called once during the course of the test.
161
+ stubs.verify_stubbed_calls
162
+ ```
163
+
164
+ ## <a name="todo"></a>TODO
149
165
  * support streaming requests/responses
150
166
  * better stubbing API
151
- * Support timeouts
152
167
  * Add curb, em-http, fast_http
153
168
 
154
- Note on Patches/Pull Requests
155
- -----------------------------
156
- * Fork the project.
157
- * Make your feature addition or bug fix.
158
- * Add tests for it. This is important so I don't break it in a
159
- future version unintentionally.
160
- * Commit, do not mess with rakefile, version, or history.
161
- (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
162
- * Send me a pull request. Bonus points for topic branches.
163
-
164
- Supported Rubies
165
- ----------------
166
- This library aims to support and is [tested
167
- against](http://travis-ci.org/technoweenie/faraday) the following Ruby
169
+ ## <a name="pulls"></a>Note on Patches/Pull Requests
170
+ 1. Fork the project.
171
+ 2. Make your feature addition or bug fix.
172
+ 3. Add tests for it. This is important so I don't break it in a future version
173
+ unintentionally.
174
+ 4. Commit, do not mess with rakefile, version, or history. (if you want to have
175
+ your own version, that is fine but bump version in a commit by itself I can
176
+ ignore when I pull)
177
+ 5. Send me a pull request. Bonus points for topic branches.
178
+
179
+ ## <a name="versions"></a>Supported Ruby Versions
180
+ This library aims to support and is [tested against][travis] the following Ruby
168
181
  implementations:
169
182
 
170
183
  * Ruby 1.8.7
171
- * Ruby 1.9.1
172
184
  * Ruby 1.9.2
173
- * [Rubinius](http://rubini.us)
174
- * [Ruby Enterprise Edition](http://www.rubyenterpriseedition.com/)
185
+ * Ruby 1.9.3
186
+ * JRuby[]
187
+ * [Rubinius][]
188
+ * [Ruby Enterprise Edition][ree]
189
+
190
+ [jruby]: http://jruby.org/
191
+ [rubinius]: http://rubini.us/
192
+ [ree]: http://www.rubyenterpriseedition.com/
175
193
 
176
194
  If something doesn't work on one of these interpreters, it should be considered
177
195
  a bug.
@@ -187,8 +205,7 @@ implementation, you will be personally responsible for providing patches in a
187
205
  timely fashion. If critical issues for a particular implementation exist at the
188
206
  time of a major release, support for that Ruby version may be dropped.
189
207
 
190
- Copyright
191
- ---------
192
- Copyright (c) 2009-2011 rick, hobson. See [LICENSE][license] for details.
208
+ ## <a name="copyright"></a>Copyright
209
+ Copyright (c) 2009 rick olson, zack hobson. See [LICENSE][] for details.
193
210
 
194
211
  [license]: https://github.com/technoweenie/faraday/blob/master/LICENSE.md
data/Rakefile CHANGED
@@ -1,12 +1,9 @@
1
- #!/usr/bin/env rake
2
-
3
1
  require 'date'
2
+ require 'rake/testtask'
4
3
 
5
- #############################################################################
6
- #
7
- # Helper functions
8
- #
9
- #############################################################################
4
+ task :default => :test
5
+
6
+ ## helper functions
10
7
 
11
8
  def name
12
9
  @name ||= Dir['*.gemspec'].first.split('.').first
@@ -17,14 +14,6 @@ def version
17
14
  line.match(/.*VERSION\s*=\s*['"](.*)['"]/)[1]
18
15
  end
19
16
 
20
- def date
21
- Date.today.to_s
22
- end
23
-
24
- def rubyforge_project
25
- name
26
- end
27
-
28
17
  def gemspec_file
29
18
  "#{name}.gemspec"
30
19
  end
@@ -37,26 +26,17 @@ def replace_header(head, header_name)
37
26
  head.sub!(/(\.#{header_name}\s*= ').*'/) { "#{$1}#{send(header_name)}'"}
38
27
  end
39
28
 
40
- #############################################################################
41
- #
42
- # Standard tasks
43
- #
44
- #############################################################################
29
+ ## standard tasks
45
30
 
46
- task :default => :test
47
-
48
- require 'rake/testtask'
49
31
  Rake::TestTask.new(:test) do |test|
50
32
  test.libs << 'lib' << 'test'
51
33
  test.pattern = 'test/**/*_test.rb'
52
34
  test.verbose = true
53
35
  end
54
36
 
55
- TEST_SERVER = 'http://faradaylive.heroku.com'
56
-
57
- desc "Run tests including live tests against #{TEST_SERVER}"
58
- task :"test:live" do
59
- ENV['LIVE'] = TEST_SERVER
37
+ desc "Run tests including live tests against a local server on port 4567"
38
+ task :"test:local" do
39
+ ENV['LIVE'] = '1'
60
40
  Rake::Task[:test].invoke
61
41
  end
62
42
 
@@ -65,25 +45,13 @@ task :console do
65
45
  sh "irb -rubygems -r ./lib/#{name}.rb"
66
46
  end
67
47
 
68
- #############################################################################
69
- #
70
- # Custom tasks (add your own tasks here)
71
- #
72
- #############################################################################
73
-
48
+ ## release management tasks
74
49
 
75
-
76
- #############################################################################
77
- #
78
- # Packaging tasks
79
- #
80
- #############################################################################
81
-
82
- desc "Create tag v#{version} and build and push #{gem_file} to Rubygems"
50
+ desc "Commit, create tag v#{version} and build and push #{gem_file} to Rubygems"
83
51
  task :release => :build do
84
52
  sh "git commit --allow-empty -a -m 'Release #{version}'"
85
53
  sh "git tag v#{version}"
86
- sh "git push origin master"
54
+ sh "git push"
87
55
  sh "git push origin v#{version}"
88
56
  sh "gem push pkg/#{gem_file}"
89
57
  end
@@ -96,7 +64,7 @@ task :build => :gemspec do
96
64
  end
97
65
 
98
66
  desc "Generate #{gemspec_file}"
99
- task :gemspec => :validate do
67
+ task :gemspec do
100
68
  # read spec file and split out manifest section
101
69
  spec = File.read(gemspec_file)
102
70
  head, manifest, tail = spec.split(" # = MANIFEST =\n")
@@ -104,9 +72,6 @@ task :gemspec => :validate do
104
72
  # replace name version and date
105
73
  replace_header(head, :name)
106
74
  replace_header(head, :version)
107
- replace_header(head, :date)
108
- #comment this out if your rubyforge_project has a different name
109
- replace_header(head, :rubyforge_project)
110
75
 
111
76
  # determine file list from git ls-files
112
77
  files = `git ls-files`.
@@ -123,16 +88,3 @@ task :gemspec => :validate do
123
88
  File.open(gemspec_file, 'w') { |io| io.write(spec) }
124
89
  puts "Updated #{gemspec_file}"
125
90
  end
126
-
127
- desc "Validate #{gemspec_file}"
128
- task :validate do
129
- libfiles = Dir['lib/*'] - ["lib/#{name}.rb", "lib/#{name}"]
130
- unless libfiles.empty?
131
- puts "Directory `lib` should only contain a `#{name}.rb` file and `#{name}` dir."
132
- exit!
133
- end
134
- unless Dir['VERSION*'].empty?
135
- puts "A `VERSION` file at root level violates Gem best practices."
136
- exit!
137
- end
138
- end