avdi-faraday 0.8.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (60) hide show
  1. data/Gemfile +27 -0
  2. data/LICENSE.md +20 -0
  3. data/README.md +250 -0
  4. data/Rakefile +87 -0
  5. data/config.ru +6 -0
  6. data/faraday.gemspec +86 -0
  7. data/lib/faraday.rb +276 -0
  8. data/lib/faraday/adapter.rb +71 -0
  9. data/lib/faraday/adapter/em_http.rb +217 -0
  10. data/lib/faraday/adapter/em_synchrony.rb +89 -0
  11. data/lib/faraday/adapter/em_synchrony/parallel_manager.rb +66 -0
  12. data/lib/faraday/adapter/excon.rb +59 -0
  13. data/lib/faraday/adapter/httpclient.rb +92 -0
  14. data/lib/faraday/adapter/net_http.rb +116 -0
  15. data/lib/faraday/adapter/net_http_persistent.rb +37 -0
  16. data/lib/faraday/adapter/patron.rb +65 -0
  17. data/lib/faraday/adapter/rack.rb +57 -0
  18. data/lib/faraday/adapter/test.rb +162 -0
  19. data/lib/faraday/adapter/typhoeus.rb +107 -0
  20. data/lib/faraday/builder.rb +184 -0
  21. data/lib/faraday/connection.rb +468 -0
  22. data/lib/faraday/error.rb +40 -0
  23. data/lib/faraday/middleware.rb +41 -0
  24. data/lib/faraday/request.rb +101 -0
  25. data/lib/faraday/request/authorization.rb +40 -0
  26. data/lib/faraday/request/basic_authentication.rb +13 -0
  27. data/lib/faraday/request/multipart.rb +62 -0
  28. data/lib/faraday/request/retry.rb +67 -0
  29. data/lib/faraday/request/token_authentication.rb +15 -0
  30. data/lib/faraday/request/url_encoded.rb +35 -0
  31. data/lib/faraday/response.rb +99 -0
  32. data/lib/faraday/response/logger.rb +34 -0
  33. data/lib/faraday/response/raise_error.rb +16 -0
  34. data/lib/faraday/upload_io.rb +23 -0
  35. data/lib/faraday/utils.rb +274 -0
  36. data/script/test +91 -0
  37. data/test/adapters/default_test.rb +14 -0
  38. data/test/adapters/em_http_test.rb +19 -0
  39. data/test/adapters/em_synchrony_test.rb +20 -0
  40. data/test/adapters/excon_test.rb +15 -0
  41. data/test/adapters/httpclient_test.rb +16 -0
  42. data/test/adapters/integration.rb +193 -0
  43. data/test/adapters/logger_test.rb +37 -0
  44. data/test/adapters/net_http_persistent_test.rb +11 -0
  45. data/test/adapters/net_http_test.rb +49 -0
  46. data/test/adapters/patron_test.rb +17 -0
  47. data/test/adapters/rack_test.rb +26 -0
  48. data/test/adapters/test_middleware_test.rb +70 -0
  49. data/test/adapters/typhoeus_test.rb +20 -0
  50. data/test/authentication_middleware_test.rb +65 -0
  51. data/test/connection_test.rb +375 -0
  52. data/test/env_test.rb +183 -0
  53. data/test/helper.rb +75 -0
  54. data/test/live_server.rb +57 -0
  55. data/test/middleware/retry_test.rb +62 -0
  56. data/test/middleware_stack_test.rb +203 -0
  57. data/test/middleware_test.rb +12 -0
  58. data/test/request_middleware_test.rb +108 -0
  59. data/test/response_middleware_test.rb +74 -0
  60. metadata +182 -0
data/Gemfile ADDED
@@ -0,0 +1,27 @@
1
+ source 'https://rubygems.org'
2
+
3
+ group :development do
4
+ gem 'sinatra', '~> 1.2'
5
+ end
6
+
7
+ group :test do
8
+ gem 'em-http-request', '~> 1.0', :require => 'em-http'
9
+ gem 'em-synchrony', '~> 1.0', :require => ['em-synchrony', 'em-synchrony/em-http'], :platforms => :ruby_19
10
+ gem 'excon', '~> 0.14'
11
+ gem 'httpclient', '~> 2.2'
12
+ gem 'net-http-persistent', '~> 2.5', :require => false
13
+ gem 'leftright', '~> 0.9', :require => false
14
+ gem 'rack-test', '~> 0.6', :require => 'rack/test'
15
+ end
16
+
17
+ platforms :ruby do
18
+ gem 'patron', '~> 0.4', '> 0.4.1'
19
+ gem 'typhoeus', '~> 0.3.3'
20
+ end
21
+
22
+ platforms :jruby do
23
+ gem 'jruby-openssl', '~> 0.7'
24
+ gem 'ffi-ncurses', '~> 0.3'
25
+ end
26
+
27
+ gemspec
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 rick olson, zack hobson
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,250 @@
1
+ # Faraday
2
+
3
+ Faraday is an HTTP client lib that provides a common interface over many
4
+ adapters (such as Net::HTTP) and embraces the concept of Rack middleware when
5
+ processing the request/response cycle.
6
+
7
+ Faraday supports these adapters:
8
+
9
+ * Net::HTTP
10
+ * [Excon][]
11
+ * [Typhoeus][]
12
+ * [Patron][]
13
+ * [EventMachine][]
14
+
15
+ It also includes a Rack adapter for hitting loaded Rack applications through
16
+ Rack::Test, and a Test adapter for stubbing requests by hand.
17
+
18
+ ## Usage
19
+
20
+ ```ruby
21
+ conn = Faraday.new(:url => 'http://sushi.com') do |faraday|
22
+ faraday.request :url_encoded # form-encode POST params
23
+ faraday.response :logger # log requests to STDOUT
24
+ faraday.adapter Faraday.default_adapter # make requests with Net::HTTP
25
+ end
26
+
27
+ ## GET ##
28
+
29
+ response = conn.get '/nigiri/sake.json' # GET http://sushi.com/nigiri/sake.json
30
+ response.body
31
+
32
+ conn.get '/nigiri', { :name => 'Maguro' } # GET /nigiri?name=Maguro
33
+
34
+ conn.get do |req| # GET http://sushi.com/search?page=2&limit=100
35
+ req.url '/search', :page => 2
36
+ req.params['limit'] = 100
37
+ end
38
+
39
+ ## POST ##
40
+
41
+ conn.post '/nigiri', { :name => 'Maguro' } # POST "name=maguro" to http://sushi.com/nigiri
42
+
43
+ # post payload as JSON instead of "www-form-urlencoded" encoding:
44
+ conn.post do |req|
45
+ req.url '/nigiri'
46
+ req.headers['Content-Type'] = 'application/json'
47
+ req.body = '{ "name": "Unagi" }'
48
+ end
49
+
50
+ ## Per-request options ##
51
+
52
+ conn.get do |req|
53
+ req.url '/search'
54
+ req.options[:timeout] = 5 # open/read timeout in seconds
55
+ req.options[:open_timeout] = 2 # connection open timeout in seconds
56
+ end
57
+ ```
58
+
59
+ If you don't need to set up anything, you can roll with just the bare minimum:
60
+
61
+ ```ruby
62
+ # using the default stack:
63
+ response = Faraday.get 'http://sushi.com/nigiri/sake.json'
64
+ ```
65
+
66
+ ## Advanced middleware usage
67
+
68
+ The order in which middleware is stacked is important. Like with Rack, the
69
+ first middleware on the list wraps all others, while the last middleware is the
70
+ innermost one, so that must be the adapter.
71
+
72
+ ```ruby
73
+ Faraday.new(...) do |conn|
74
+ # POST/PUT params encoders:
75
+ conn.request :multipart
76
+ conn.request :url_encoded
77
+
78
+ conn.adapter :net_http
79
+ end
80
+ ```
81
+
82
+ This request middleware setup affects POST/PUT requests in the following way:
83
+
84
+ 1. `Request::Multipart` checks for files in the payload, otherwise leaves
85
+ everything untouched;
86
+ 2. `Request::UrlEncoded` encodes as "application/x-www-form-urlencoded" if not
87
+ already encoded or of another type
88
+
89
+ Swapping middleware means giving the other priority. Specifying the
90
+ "Content-Type" for the request is explicitly stating which middleware should
91
+ process it.
92
+
93
+ Examples:
94
+
95
+ ```ruby
96
+ # uploading a file:
97
+ payload[:profile_pic] = Faraday::UploadIO.new('/path/to/avatar.jpg', 'image/jpeg')
98
+
99
+ # "Multipart" middleware detects files and encodes with "multipart/form-data":
100
+ conn.put '/profile', payload
101
+ ```
102
+
103
+ ## Writing middleware
104
+
105
+ Middleware are classes that implement a `call` instance method. They hook into
106
+ the request/response cycle.
107
+
108
+ ```ruby
109
+ def call(env)
110
+ # do something with the request
111
+
112
+ @app.call(env).on_complete do
113
+ # do something with the response
114
+ end
115
+ end
116
+ ```
117
+
118
+ It's important to do all processing of the response only in the `on_complete`
119
+ block. This enables middleware to work in parallel mode where requests are
120
+ asynchronous.
121
+
122
+ The `env` is a hash with symbol keys that contains info about the request and,
123
+ later, response. Some keys are:
124
+
125
+ ```
126
+ # request phase
127
+ :method - :get, :post, ...
128
+ :url - URI for the current request; also contains GET parameters
129
+ :body - POST parameters for :post/:put requests
130
+ :request_headers
131
+
132
+ # response phase
133
+ :status - HTTP response status code, such as 200
134
+ :body - the response body
135
+ :response_headers
136
+ ```
137
+
138
+ ## Using Faraday for testing
139
+
140
+ ```ruby
141
+ # It's possible to define stubbed request outside a test adapter block.
142
+ stubs = Faraday::Adapter::Test::Stubs.new do |stub|
143
+ stub.get('/tamago') { [200, {}, 'egg'] }
144
+ end
145
+
146
+ # You can pass stubbed request to the test adapter or define them in a block
147
+ # or a combination of the two.
148
+ test = Faraday.new do |builder|
149
+ builder.adapter :test, stubs do |stub|
150
+ stub.get('/ebi') {[ 200, {}, 'shrimp' ]}
151
+ end
152
+ end
153
+
154
+ # It's also possible to stub additional requests after the connection has
155
+ # been initialized. This is useful for testing.
156
+ stubs.get('/uni') {[ 200, {}, 'urchin' ]}
157
+
158
+ resp = test.get '/tamago'
159
+ resp.body # => 'egg'
160
+ resp = test.get '/ebi'
161
+ resp.body # => 'shrimp'
162
+ resp = test.get '/uni'
163
+ resp.body # => 'urchin'
164
+ resp = test.get '/else' #=> raises "no such stub" error
165
+
166
+ # If you like, you can treat your stubs as mocks by verifying that all of
167
+ # the stubbed calls were made. NOTE that this feature is still fairly
168
+ # experimental: It will not verify the order or count of any stub, only that
169
+ # it was called once during the course of the test.
170
+ stubs.verify_stubbed_calls
171
+ ```
172
+
173
+ ## TODO
174
+
175
+ * support streaming requests/responses
176
+ * better stubbing API
177
+
178
+ ## Contributing
179
+
180
+ You can run the test suite against a live server by running `script/test`. It
181
+ automatically starts a test server in background. Only tests in
182
+ `test/adapters/*_test.rb` require a server, though.
183
+
184
+ ``` sh
185
+ # run the whole suite
186
+ $ script/server
187
+
188
+ # run only specific files
189
+ $ script/server excon typhoeus
190
+ ```
191
+
192
+ We will accept middleware that:
193
+
194
+ 1. is useful to a broader audience, but can be implemented relatively
195
+ simple; and
196
+ 2. which isn't already present in [faraday_middleware][] project.
197
+
198
+ We will accept adapters that:
199
+
200
+ 1. support SSL & streaming;
201
+ 1. are proven and may have better performance than existing ones; or
202
+ 2. if they have features not present in included adapters.
203
+
204
+ We are pushing towards a 1.0 release, when we will have to follow [Semantic
205
+ Versioning][semver]. If your patch includes changes to break compatiblitity,
206
+ note that so we can add it to the [Changelog][].
207
+
208
+ ## Supported Ruby versions
209
+
210
+ This library aims to support and is [tested against][travis] the following Ruby
211
+ implementations:
212
+
213
+ * MRI 1.8.7
214
+ * MRI 1.9.2
215
+ * MRI 1.9.3
216
+ * [JRuby][]
217
+ * [Rubinius][]
218
+
219
+ If something doesn't work on one of these interpreters, it should be considered
220
+ a bug.
221
+
222
+ This library may inadvertently work (or seem to work) on other Ruby
223
+ implementations, however support will only be provided for the versions listed
224
+ above.
225
+
226
+ If you would like this library to support another Ruby version, you may
227
+ volunteer to be a maintainer. Being a maintainer entails making sure all tests
228
+ run and pass on that implementation. When something breaks on your
229
+ implementation, you will be personally responsible for providing patches in a
230
+ timely fashion. If critical issues for a particular implementation exist at the
231
+ time of a major release, support for that Ruby version may be dropped.
232
+
233
+ ## Copyright
234
+
235
+ Copyright (c) 2009-2012 [Rick Olson](mailto:technoweenie@gmail.com), zack hobson.
236
+ See [LICENSE][] for details.
237
+
238
+
239
+ [license]: https://github.com/technoweenie/faraday/blob/master/LICENSE.md
240
+ [travis]: http://travis-ci.org/technoweenie/faraday
241
+ [jruby]: http://jruby.org/
242
+ [rubinius]: http://rubini.us/
243
+ [semver]: http://semver.org/
244
+ [changelog]: https://github.com/technoweenie/faraday/wiki/Changelog
245
+ [excon]: https://github.com/geemus/excon#readme
246
+ [typhoeus]: https://github.com/typhoeus/typhoeus#readme
247
+ [patron]: http://toland.github.com/patron/
248
+
249
+ [eventmachine]: https://github.com/igrigorik/em-http-request#readme
250
+ [faraday_middleware]: https://github.com/pengwynn/faraday_middleware/wiki
@@ -0,0 +1,87 @@
1
+ require 'date'
2
+ require 'rake/testtask'
3
+
4
+ task :default => :test
5
+
6
+ ## helper functions
7
+
8
+ def name
9
+ @name ||= Dir['*.gemspec'].first.split('.').first
10
+ end
11
+
12
+ def gem_name
13
+ 'avdi-faraday'
14
+ end
15
+
16
+ def version
17
+ line = File.read("lib/#{name}.rb")[/^\s*VERSION\s*=\s*.*/]
18
+ line.match(/.*VERSION\s*=\s*['"](.*)['"]/)[1]
19
+ end
20
+
21
+ def gemspec_file
22
+ "#{name}.gemspec"
23
+ end
24
+
25
+ def gem_file
26
+ "#{gem_name}-#{version}.gem"
27
+ end
28
+
29
+ def replace_header(head, header_name)
30
+ head.sub!(/(\.#{header_name}\s*= ').*'/) { "#{$1}#{send(header_name)}'"}
31
+ end
32
+
33
+ ## standard tasks
34
+
35
+ desc "Run all tests"
36
+ task :test do
37
+ exec 'script/test'
38
+ end
39
+
40
+ desc "Open an irb session preloaded with this library"
41
+ task :console do
42
+ sh "irb -rubygems -r ./lib/#{name}.rb"
43
+ end
44
+
45
+ ## release management tasks
46
+
47
+ desc "Commit, create tag v#{version} and build and push #{gem_file} to Rubygems"
48
+ task :release => :build do
49
+ sh "git commit --allow-empty -a -m 'Release #{version}'"
50
+ sh "git tag v#{version}-avdi"
51
+ sh "git push avdi"
52
+ sh "git push avdi v#{version}"
53
+ sh "gem push pkg/#{gem_file}"
54
+ end
55
+
56
+ desc "Build #{gem_file} into the pkg directory"
57
+ task :build => :gemspec do
58
+ sh "mkdir -p pkg"
59
+ sh "gem build #{gemspec_file}"
60
+ sh "mv #{gem_file} pkg"
61
+ end
62
+
63
+ desc "Generate #{gemspec_file}"
64
+ task :gemspec do
65
+ # read spec file and split out manifest section
66
+ spec = File.read(gemspec_file)
67
+ head, manifest, tail = spec.split(" # = MANIFEST =\n")
68
+
69
+ # replace name version and date
70
+ replace_header(head, :gem_name)
71
+ replace_header(head, :version)
72
+
73
+ # determine file list from git ls-files
74
+ files = `git ls-files`.
75
+ split("\n").
76
+ sort.
77
+ reject { |file| file =~ /^\./ }.
78
+ reject { |file| file =~ /^(rdoc|pkg)/ }.
79
+ map { |file| " #{file}" }.
80
+ join("\n")
81
+
82
+ # piece file back together and write
83
+ manifest = " s.files = %w[\n#{files}\n ]\n"
84
+ spec = [head, manifest, tail].join(" # = MANIFEST =\n")
85
+ File.open(gemspec_file, 'w') { |io| io.write(spec) }
86
+ puts "Updated #{gemspec_file}"
87
+ end
@@ -0,0 +1,6 @@
1
+ require 'rubygems'
2
+ require 'bundler'
3
+ Bundler.setup
4
+
5
+ require File.expand_path('../test/live_server', __FILE__)
6
+ run Sinatra::Application
@@ -0,0 +1,86 @@
1
+ Gem::Specification.new do |s|
2
+ s.specification_version = 2 if s.respond_to? :specification_version=
3
+ s.required_rubygems_version = Gem::Requirement.new(">= 1.3.5") if s.respond_to? :required_rubygems_version=
4
+
5
+ s.name = 'avdi-faraday'
6
+ s.version = '0.8.1'
7
+
8
+ s.summary = "Avdi's personal fork of Faraday. Nothing to see here. Move along."
9
+ s.description = "Just a fork so I can satisfy gem dependencies in Leadlight."
10
+
11
+ s.authors = ["Rick Olson", "Avdi Grimm"]
12
+ s.email = 'avdi@avdi.org'
13
+ s.homepage = 'https://github.com/avdi/faraday'
14
+
15
+ s.add_dependency 'multipart-post', '~> 1.1'
16
+ s.add_development_dependency 'rake'
17
+ s.add_development_dependency 'simplecov'
18
+ s.add_development_dependency 'test-unit'
19
+ s.add_development_dependency 'webmock'
20
+
21
+ # = MANIFEST =
22
+ s.files = %w[
23
+ Gemfile
24
+ LICENSE.md
25
+ README.md
26
+ Rakefile
27
+ config.ru
28
+ faraday.gemspec
29
+ lib/faraday.rb
30
+ lib/faraday/adapter.rb
31
+ lib/faraday/adapter/em_http.rb
32
+ lib/faraday/adapter/em_synchrony.rb
33
+ lib/faraday/adapter/em_synchrony/parallel_manager.rb
34
+ lib/faraday/adapter/excon.rb
35
+ lib/faraday/adapter/httpclient.rb
36
+ lib/faraday/adapter/net_http.rb
37
+ lib/faraday/adapter/net_http_persistent.rb
38
+ lib/faraday/adapter/patron.rb
39
+ lib/faraday/adapter/rack.rb
40
+ lib/faraday/adapter/test.rb
41
+ lib/faraday/adapter/typhoeus.rb
42
+ lib/faraday/builder.rb
43
+ lib/faraday/connection.rb
44
+ lib/faraday/error.rb
45
+ lib/faraday/middleware.rb
46
+ lib/faraday/request.rb
47
+ lib/faraday/request/authorization.rb
48
+ lib/faraday/request/basic_authentication.rb
49
+ lib/faraday/request/multipart.rb
50
+ lib/faraday/request/retry.rb
51
+ lib/faraday/request/token_authentication.rb
52
+ lib/faraday/request/url_encoded.rb
53
+ lib/faraday/response.rb
54
+ lib/faraday/response/logger.rb
55
+ lib/faraday/response/raise_error.rb
56
+ lib/faraday/upload_io.rb
57
+ lib/faraday/utils.rb
58
+ script/test
59
+ test/adapters/default_test.rb
60
+ test/adapters/em_http_test.rb
61
+ test/adapters/em_synchrony_test.rb
62
+ test/adapters/excon_test.rb
63
+ test/adapters/httpclient_test.rb
64
+ test/adapters/integration.rb
65
+ test/adapters/logger_test.rb
66
+ test/adapters/net_http_persistent_test.rb
67
+ test/adapters/net_http_test.rb
68
+ test/adapters/patron_test.rb
69
+ test/adapters/rack_test.rb
70
+ test/adapters/test_middleware_test.rb
71
+ test/adapters/typhoeus_test.rb
72
+ test/authentication_middleware_test.rb
73
+ test/connection_test.rb
74
+ test/env_test.rb
75
+ test/helper.rb
76
+ test/live_server.rb
77
+ test/middleware/retry_test.rb
78
+ test/middleware_stack_test.rb
79
+ test/middleware_test.rb
80
+ test/request_middleware_test.rb
81
+ test/response_middleware_test.rb
82
+ ]
83
+ # = MANIFEST =
84
+
85
+ s.test_files = s.files.select { |path| path =~ %r{^test/*/.+\.rb} }
86
+ end