faraday 0.6.1 → 0.7.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/Gemfile +24 -14
- data/{LICENSE → LICENSE.md} +1 -1
- data/README.md +29 -27
- data/Rakefile +10 -2
- data/config.ru +6 -0
- data/faraday.gemspec +10 -7
- data/lib/faraday/adapter/net_http.rb +7 -7
- data/lib/faraday/adapter/patron.rb +11 -5
- data/lib/faraday/adapter/test.rb +30 -4
- data/lib/faraday/adapter/typhoeus.rb +7 -0
- data/lib/faraday/builder.rb +24 -1
- data/lib/faraday/connection.rb +51 -29
- data/lib/faraday/error.rb +2 -0
- data/lib/faraday/request/json.rb +5 -1
- data/lib/faraday/request.rb +19 -26
- data/lib/faraday/response.rb +2 -2
- data/lib/faraday/utils.rb +79 -18
- data/lib/faraday.rb +1 -1
- data/test/adapters/live_test.rb +30 -11
- data/test/adapters/test_middleware_test.rb +28 -1
- data/test/connection_test.rb +29 -20
- data/test/env_test.rb +45 -21
- data/test/helper.rb +4 -8
- data/test/live_server.rb +7 -3
- data/test/middleware_stack_test.rb +29 -2
- data/test/request_middleware_test.rb +33 -2
- data/test/response_middleware_test.rb +27 -0
- metadata +35 -13
data/Gemfile
CHANGED
|
@@ -1,19 +1,29 @@
|
|
|
1
|
-
source
|
|
1
|
+
source 'http://rubygems.org'
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
gem 'sinatra', '~> 1.
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
3
|
+
gem 'addressable', '~> 2.2.6'
|
|
4
|
+
gem 'multipart-post', '~> 1.1.0'
|
|
5
|
+
gem 'rack', ['>= 1.1.0', '<= 1.2.0']
|
|
6
|
+
|
|
7
|
+
group :development do
|
|
8
|
+
gem 'sinatra', '~> 1.2'
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
group :test do
|
|
12
|
+
gem 'em-http-request', '~> 0.3', :require => 'em-http'
|
|
12
13
|
gem 'em-synchrony', '~> 0.2', :require => ['em-synchrony', 'em-synchrony/em-http'], :platforms => :ruby_19
|
|
13
|
-
gem '
|
|
14
|
+
gem 'excon', '~> 0.6'
|
|
15
|
+
gem 'leftright', '~> 0.9', :require => false
|
|
16
|
+
gem 'patron', '~> 0.4'
|
|
17
|
+
gem 'rake', '~> 0.8'
|
|
18
|
+
gem 'test-unit', '~> 2.3'
|
|
19
|
+
gem 'typhoeus', '~> 0.2'
|
|
20
|
+
gem 'webmock', '~> 1.6'
|
|
14
21
|
# ActiveSupport::JSON will be used in ruby 1.8 and Yajl in 1.9; this is to test against both adapters
|
|
15
|
-
gem 'activesupport', '~> 2.3
|
|
16
|
-
gem 'yajl-ruby', :require => 'yajl', :platforms => :ruby_19
|
|
22
|
+
gem 'activesupport', '~> 2.3', :require => nil, :platforms => [:ruby_18, :jruby]
|
|
23
|
+
gem 'yajl-ruby', '~> 0.8', :require => 'yajl', :platforms => :ruby_19
|
|
17
24
|
end
|
|
18
25
|
|
|
19
|
-
|
|
26
|
+
platforms :jruby do
|
|
27
|
+
gem 'jruby-openssl', '~> 0.7'
|
|
28
|
+
gem 'ffi-ncurses', '~> 0.3'
|
|
29
|
+
end
|
data/{LICENSE → LICENSE.md}
RENAMED
data/README.md
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
faraday
|
|
2
|
+
=======
|
|
3
3
|
Modular HTTP client library using middleware heavily inspired by Rack.
|
|
4
4
|
|
|
5
5
|
This mess is gonna get raw, like sushi. So, haters to the left.
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
Usage
|
|
8
|
+
-----
|
|
9
9
|
conn = Faraday.new(:url => 'http://sushi.com') do |builder|
|
|
10
10
|
builder.use Faraday::Request::UrlEncoded # convert request params as "www-form-urlencoded"
|
|
11
11
|
builder.use Faraday::Request::JSON # encode request params as json
|
|
@@ -18,23 +18,23 @@ This mess is gonna get raw, like sushi. So, haters to the left.
|
|
|
18
18
|
builder.response :logger
|
|
19
19
|
builder.adapter :net_http
|
|
20
20
|
end
|
|
21
|
-
|
|
21
|
+
|
|
22
22
|
## GET ##
|
|
23
23
|
|
|
24
24
|
response = conn.get '/nigiri/sake.json' # GET http://sushi.com/nigiri/sake.json
|
|
25
25
|
response.body
|
|
26
26
|
|
|
27
27
|
conn.get '/nigiri', 'X-Awesome' => true # custom request header
|
|
28
|
-
|
|
28
|
+
|
|
29
29
|
conn.get do |req| # GET http://sushi.com/search?page=2&limit=100
|
|
30
30
|
req.url '/search', :page => 2
|
|
31
31
|
req.params['limit'] = 100
|
|
32
32
|
end
|
|
33
|
-
|
|
33
|
+
|
|
34
34
|
## POST ##
|
|
35
|
-
|
|
35
|
+
|
|
36
36
|
conn.post '/nigiri', { :name => 'Maguro' } # POST "name=maguro" to http://sushi.com/nigiri
|
|
37
|
-
|
|
37
|
+
|
|
38
38
|
# post payload as JSON instead of "www-form-urlencoded" encoding:
|
|
39
39
|
conn.post '/nigiri', payload, 'Content-Type' => 'application/json'
|
|
40
40
|
|
|
@@ -50,8 +50,8 @@ If you're ready to roll with just the bare minimum:
|
|
|
50
50
|
# default stack (net/http), no extra middleware:
|
|
51
51
|
response = Faraday.get 'http://sushi.com/nigiri/sake.json'
|
|
52
52
|
|
|
53
|
-
|
|
54
|
-
|
|
53
|
+
Advanced middleware usage
|
|
54
|
+
-------------------------
|
|
55
55
|
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
56
|
|
|
57
57
|
conn = Faraday.new(:url => 'http://sushi.com') do |builder|
|
|
@@ -59,7 +59,7 @@ The order in which middleware is stacked is important. Like with Rack, the first
|
|
|
59
59
|
builder.request :multipart
|
|
60
60
|
builder.request :url_encoded
|
|
61
61
|
builder.request :json
|
|
62
|
-
|
|
62
|
+
|
|
63
63
|
builder.adapter :net_http
|
|
64
64
|
end
|
|
65
65
|
|
|
@@ -74,23 +74,23 @@ Because "UrlEncoded" is higher on the stack than JSON encoder, it will get to pr
|
|
|
74
74
|
Examples:
|
|
75
75
|
|
|
76
76
|
payload = { :name => 'Maguro' }
|
|
77
|
-
|
|
77
|
+
|
|
78
78
|
# post payload as JSON instead of urlencoded:
|
|
79
79
|
conn.post '/nigiri', payload, 'Content-Type' => 'application/json'
|
|
80
|
-
|
|
80
|
+
|
|
81
81
|
# uploading a file:
|
|
82
82
|
payload = { :profile_pic => Faraday::UploadIO.new('avatar.jpg', 'image/jpeg') }
|
|
83
|
-
|
|
83
|
+
|
|
84
84
|
# "Multipart" middleware detects files and encodes with "multipart/form-data":
|
|
85
85
|
conn.put '/profile', payload
|
|
86
86
|
|
|
87
|
-
|
|
88
|
-
|
|
87
|
+
Writing middleware
|
|
88
|
+
------------------
|
|
89
89
|
Middleware are classes that respond to `call()`. They wrap the request/response cycle.
|
|
90
90
|
|
|
91
91
|
def call(env)
|
|
92
92
|
# do something with the request
|
|
93
|
-
|
|
93
|
+
|
|
94
94
|
@app.call(env).on_complete do
|
|
95
95
|
# do something with the response
|
|
96
96
|
end
|
|
@@ -111,8 +111,8 @@ The `env` is a hash with symbol keys that contains info about the request and, l
|
|
|
111
111
|
:body - the response body
|
|
112
112
|
:response_headers
|
|
113
113
|
|
|
114
|
-
|
|
115
|
-
|
|
114
|
+
Testing
|
|
115
|
+
-------
|
|
116
116
|
# It's possible to define stubbed request outside a test adapter block.
|
|
117
117
|
stubs = Faraday::Adapter::Test::Stubs.new do |stub|
|
|
118
118
|
stub.get('/tamago') { [200, {}, 'egg'] }
|
|
@@ -138,21 +138,21 @@ The `env` is a hash with symbol keys that contains info about the request and, l
|
|
|
138
138
|
resp.body # => 'urchin'
|
|
139
139
|
resp = test.get '/else' #=> raises "no such stub" error
|
|
140
140
|
|
|
141
|
-
# If you like, you can treat your stubs as mocks by verifying that all of
|
|
141
|
+
# If you like, you can treat your stubs as mocks by verifying that all of
|
|
142
142
|
# the stubbed calls were made. NOTE that this feature is still fairly
|
|
143
143
|
# experimental: It will not verify the order or count of any stub, only that
|
|
144
144
|
# it was called once during the course of the test.
|
|
145
145
|
stubs.verify_stubbed_calls
|
|
146
146
|
|
|
147
|
-
|
|
148
|
-
|
|
147
|
+
TODO
|
|
148
|
+
----
|
|
149
149
|
* support streaming requests/responses
|
|
150
150
|
* better stubbing API
|
|
151
151
|
* Support timeouts
|
|
152
152
|
* Add curb, em-http, fast_http
|
|
153
153
|
|
|
154
|
-
|
|
155
|
-
|
|
154
|
+
Note on Patches/Pull Requests
|
|
155
|
+
-----------------------------
|
|
156
156
|
* Fork the project.
|
|
157
157
|
* Make your feature addition or bug fix.
|
|
158
158
|
* Add tests for it. This is important so I don't break it in a
|
|
@@ -161,6 +161,8 @@ The `env` is a hash with symbol keys that contains info about the request and, l
|
|
|
161
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
162
|
* Send me a pull request. Bonus points for topic branches.
|
|
163
163
|
|
|
164
|
-
|
|
164
|
+
Copyright
|
|
165
|
+
---------
|
|
166
|
+
Copyright (c) 2009-2011 rick, hobson. See [LICENSE][license] for details.
|
|
165
167
|
|
|
166
|
-
|
|
168
|
+
[license]: https://github.com/technoweenie/faraday/blob/master/LICENSE.md
|
data/Rakefile
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
#!/usr/bin/env rake
|
|
2
|
+
|
|
3
3
|
require 'date'
|
|
4
4
|
|
|
5
5
|
#############################################################################
|
|
@@ -52,6 +52,14 @@ Rake::TestTask.new(:test) do |test|
|
|
|
52
52
|
test.verbose = true
|
|
53
53
|
end
|
|
54
54
|
|
|
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
|
|
60
|
+
Rake::Task[:test].invoke
|
|
61
|
+
end
|
|
62
|
+
|
|
55
63
|
desc "Open an irb session preloaded with this library"
|
|
56
64
|
task :console do
|
|
57
65
|
sh "irb -rubygems -r ./lib/#{name}.rb"
|
data/config.ru
ADDED
data/faraday.gemspec
CHANGED
|
@@ -12,8 +12,8 @@ Gem::Specification.new do |s|
|
|
|
12
12
|
## If your rubyforge_project name is different, then edit it and comment out
|
|
13
13
|
## the sub! line in the Rakefile
|
|
14
14
|
s.name = 'faraday'
|
|
15
|
-
s.version = '0.
|
|
16
|
-
s.date = '2011-
|
|
15
|
+
s.version = '0.7.4'
|
|
16
|
+
s.date = '2011-07-08'
|
|
17
17
|
s.rubyforge_project = 'faraday'
|
|
18
18
|
|
|
19
19
|
## Make sure your summary is short. The description may be as long
|
|
@@ -32,10 +32,12 @@ Gem::Specification.new do |s|
|
|
|
32
32
|
## require 'NAME.rb' or'/lib/NAME/file.rb' can be as require 'NAME/file.rb'
|
|
33
33
|
s.require_paths = %w[lib]
|
|
34
34
|
|
|
35
|
-
s.add_development_dependency
|
|
36
|
-
s.
|
|
37
|
-
s.
|
|
38
|
-
s.add_runtime_dependency
|
|
35
|
+
s.add_development_dependency 'rake', '~> 0.9'
|
|
36
|
+
s.add_development_dependency 'test-unit', '~> 2.3'
|
|
37
|
+
s.add_development_dependency 'webmock', '~> 1.6'
|
|
38
|
+
s.add_runtime_dependency 'addressable', '~> 2.2.6'
|
|
39
|
+
s.add_runtime_dependency 'multipart-post', '~> 1.1.0'
|
|
40
|
+
s.add_runtime_dependency 'rack', ['>= 1.1.0', '< 2']
|
|
39
41
|
|
|
40
42
|
## Leave this section as-is. It will be automatically generated from the
|
|
41
43
|
## contents of your Git repository via the gemspec task. DO NOT REMOVE
|
|
@@ -43,9 +45,10 @@ Gem::Specification.new do |s|
|
|
|
43
45
|
# = MANIFEST =
|
|
44
46
|
s.files = %w[
|
|
45
47
|
Gemfile
|
|
46
|
-
LICENSE
|
|
48
|
+
LICENSE.md
|
|
47
49
|
README.md
|
|
48
50
|
Rakefile
|
|
51
|
+
config.ru
|
|
49
52
|
faraday.gemspec
|
|
50
53
|
lib/faraday.rb
|
|
51
54
|
lib/faraday/adapter.rb
|
|
@@ -15,15 +15,15 @@ module Faraday
|
|
|
15
15
|
|
|
16
16
|
http = net_http_class(env).new(url.host, url.inferred_port)
|
|
17
17
|
|
|
18
|
-
if http.use_ssl = (url.scheme == 'https' && env[:ssl])
|
|
19
|
-
ssl = env[:ssl]
|
|
18
|
+
if http.use_ssl = (url.scheme == 'https' && (ssl = env[:ssl]) && true)
|
|
20
19
|
http.verify_mode = ssl[:verify_mode] || ssl.fetch(:verify, true) ?
|
|
21
20
|
OpenSSL::SSL::VERIFY_PEER : OpenSSL::SSL::VERIFY_NONE
|
|
22
|
-
http.cert
|
|
23
|
-
http.key
|
|
24
|
-
http.ca_file
|
|
25
|
-
http.ca_path
|
|
26
|
-
http.cert_store
|
|
21
|
+
http.cert = ssl[:client_cert] if ssl[:client_cert]
|
|
22
|
+
http.key = ssl[:client_key] if ssl[:client_key]
|
|
23
|
+
http.ca_file = ssl[:ca_file] if ssl[:ca_file]
|
|
24
|
+
http.ca_path = ssl[:ca_path] if ssl[:ca_path]
|
|
25
|
+
http.cert_store = ssl[:cert_store] if ssl[:cert_store]
|
|
26
|
+
http.verify_depth = ssl[:verify_depth] if ssl[:verify_depth]
|
|
27
27
|
end
|
|
28
28
|
|
|
29
29
|
http.read_timeout = http.open_timeout = req[:timeout] if req[:timeout]
|
|
@@ -12,11 +12,8 @@ module Faraday
|
|
|
12
12
|
session = ::Patron::Session.new
|
|
13
13
|
|
|
14
14
|
response = begin
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
else
|
|
18
|
-
session.send(env[:method], env[:url].to_s, env[:request_headers])
|
|
19
|
-
end
|
|
15
|
+
data = Connection::METHODS_WITH_BODIES.include?(env[:method]) ? env[:body].to_s : nil
|
|
16
|
+
session.request(env[:method], env[:url].to_s, env[:request_headers], :data => data)
|
|
20
17
|
rescue Errno::ECONNREFUSED
|
|
21
18
|
raise Error::ConnectionFailed, $!
|
|
22
19
|
end
|
|
@@ -25,6 +22,15 @@ module Faraday
|
|
|
25
22
|
|
|
26
23
|
@app.call env
|
|
27
24
|
end
|
|
25
|
+
|
|
26
|
+
if loaded? && defined?(::Patron::Request::VALID_ACTIONS)
|
|
27
|
+
# HAX: helps but doesn't work completely
|
|
28
|
+
# https://github.com/toland/patron/issues/34
|
|
29
|
+
::Patron::Request::VALID_ACTIONS.tap do |actions|
|
|
30
|
+
actions << :patch unless actions.include? :patch
|
|
31
|
+
actions << :options unless actions.include? :options
|
|
32
|
+
end
|
|
33
|
+
end
|
|
28
34
|
end
|
|
29
35
|
end
|
|
30
36
|
end
|
data/lib/faraday/adapter/test.rb
CHANGED
|
@@ -17,6 +17,9 @@ module Faraday
|
|
|
17
17
|
def self.loaded?() false end
|
|
18
18
|
|
|
19
19
|
class Stubs
|
|
20
|
+
class NotFound < StandardError
|
|
21
|
+
end
|
|
22
|
+
|
|
20
23
|
def initialize
|
|
21
24
|
# {:get => [Stub, Stub]}
|
|
22
25
|
@stack, @consumed = {}, {}
|
|
@@ -84,9 +87,29 @@ module Faraday
|
|
|
84
87
|
end
|
|
85
88
|
end
|
|
86
89
|
|
|
87
|
-
class Stub < Struct.new(:path, :body, :block)
|
|
88
|
-
def
|
|
89
|
-
|
|
90
|
+
class Stub < Struct.new(:path, :params, :body, :block)
|
|
91
|
+
def initialize(full, body, block)
|
|
92
|
+
path, query = full.split('?')
|
|
93
|
+
params = query ?
|
|
94
|
+
Rack::Utils.parse_nested_query(query) :
|
|
95
|
+
{}
|
|
96
|
+
super path, params, body, block
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
def matches?(request_uri, request_body)
|
|
100
|
+
request_path, request_query = request_uri.split('?')
|
|
101
|
+
request_params = request_query ?
|
|
102
|
+
Rack::Utils.parse_nested_query(request_query) :
|
|
103
|
+
{}
|
|
104
|
+
request_path == path &&
|
|
105
|
+
params_match?(request_params) &&
|
|
106
|
+
(body.to_s.size.zero? || request_body == body)
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
def params_match?(request_params)
|
|
110
|
+
params.keys.all? do |key|
|
|
111
|
+
request_params[key] == params[key]
|
|
112
|
+
end
|
|
90
113
|
end
|
|
91
114
|
|
|
92
115
|
def to_s
|
|
@@ -109,10 +132,13 @@ module Faraday
|
|
|
109
132
|
normalized_path = Faraday::Utils.normalize_path(env[:url])
|
|
110
133
|
|
|
111
134
|
if stub = stubs.match(env[:method], normalized_path, env[:body])
|
|
135
|
+
env[:params] = (query = env[:url].query) ?
|
|
136
|
+
Rack::Utils.parse_nested_query(query) :
|
|
137
|
+
{}
|
|
112
138
|
status, headers, body = stub.block.call(env)
|
|
113
139
|
save_response(env, status, body, headers)
|
|
114
140
|
else
|
|
115
|
-
raise "no stubbed request for #{env[:method]} #{normalized_path} #{env[:body]}"
|
|
141
|
+
raise Stubs::NotFound, "no stubbed request for #{env[:method]} #{normalized_path} #{env[:body]}"
|
|
116
142
|
end
|
|
117
143
|
@app.call(env)
|
|
118
144
|
end
|
|
@@ -21,6 +21,13 @@ module Faraday
|
|
|
21
21
|
:headers => env[:request_headers],
|
|
22
22
|
:disable_ssl_peer_verification => (env[:ssl] && !env[:ssl].fetch(:verify, true))
|
|
23
23
|
|
|
24
|
+
if ssl = env[:ssl]
|
|
25
|
+
req.ssl_cert = ssl[:client_cert_file] if ssl[:client_cert_file]
|
|
26
|
+
req.ssl_key = ssl[:client_key_file] if ssl[:client_key_file]
|
|
27
|
+
req.ssl_cacert = ssl[:ca_file] if ssl[:ca_file]
|
|
28
|
+
req.ssl_capath = ssl[:ca_path] if ssl[:ca_path]
|
|
29
|
+
end
|
|
30
|
+
|
|
24
31
|
env_req = env[:request]
|
|
25
32
|
req.timeout = req.connect_timeout = (env_req[:timeout] * 1000) if env_req[:timeout]
|
|
26
33
|
req.connect_timeout = (env_req[:open_timeout] * 1000) if env_req[:open_timeout]
|
data/lib/faraday/builder.rb
CHANGED
|
@@ -12,6 +12,9 @@ module Faraday
|
|
|
12
12
|
new { |builder| yield builder }
|
|
13
13
|
end
|
|
14
14
|
|
|
15
|
+
# Error raised when trying to modify the stack after calling `lock!`
|
|
16
|
+
class StackLocked < RuntimeError; end
|
|
17
|
+
|
|
15
18
|
# borrowed from ActiveSupport::Dependencies::Reference &
|
|
16
19
|
# ActionDispatch::MiddlewareStack::Middleware
|
|
17
20
|
class Handler
|
|
@@ -31,7 +34,9 @@ module Faraday
|
|
|
31
34
|
def inspect() @name end
|
|
32
35
|
|
|
33
36
|
def ==(other)
|
|
34
|
-
if other.
|
|
37
|
+
if other.is_a? Handler
|
|
38
|
+
self.name == other.name
|
|
39
|
+
elsif other.respond_to? :name
|
|
35
40
|
klass == other
|
|
36
41
|
else
|
|
37
42
|
@name == other.to_s
|
|
@@ -55,6 +60,7 @@ module Faraday
|
|
|
55
60
|
end
|
|
56
61
|
|
|
57
62
|
def build(options = {})
|
|
63
|
+
raise_if_locked
|
|
58
64
|
@handlers.clear unless options[:keep]
|
|
59
65
|
yield self if block_given?
|
|
60
66
|
end
|
|
@@ -76,7 +82,17 @@ module Faraday
|
|
|
76
82
|
@handlers.reverse.inject(inner_app) { |app, handler| handler.build(app) }
|
|
77
83
|
end
|
|
78
84
|
|
|
85
|
+
# Locks the middleware stack to ensure no further modifications are possible.
|
|
86
|
+
def lock!
|
|
87
|
+
@handlers.freeze
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def locked?
|
|
91
|
+
@handlers.frozen?
|
|
92
|
+
end
|
|
93
|
+
|
|
79
94
|
def use(klass, *args)
|
|
95
|
+
raise_if_locked
|
|
80
96
|
block = block_given? ? Proc.new : nil
|
|
81
97
|
@handlers << self.class::Handler.new(klass, *args, &block)
|
|
82
98
|
end
|
|
@@ -99,6 +115,7 @@ module Faraday
|
|
|
99
115
|
## methods to push onto the various positions in the stack:
|
|
100
116
|
|
|
101
117
|
def insert(index, *args, &block)
|
|
118
|
+
raise_if_locked
|
|
102
119
|
index = assert_index(index)
|
|
103
120
|
handler = self.class::Handler.new(*args, &block)
|
|
104
121
|
@handlers.insert(index, handler)
|
|
@@ -112,17 +129,23 @@ module Faraday
|
|
|
112
129
|
end
|
|
113
130
|
|
|
114
131
|
def swap(index, *args, &block)
|
|
132
|
+
raise_if_locked
|
|
115
133
|
index = assert_index(index)
|
|
116
134
|
@handlers.delete_at(index)
|
|
117
135
|
insert(index, *args, &block)
|
|
118
136
|
end
|
|
119
137
|
|
|
120
138
|
def delete(handler)
|
|
139
|
+
raise_if_locked
|
|
121
140
|
@handlers.delete(handler)
|
|
122
141
|
end
|
|
123
142
|
|
|
124
143
|
private
|
|
125
144
|
|
|
145
|
+
def raise_if_locked
|
|
146
|
+
raise StackLocked, "can't modify middleware stack after making a request" if locked?
|
|
147
|
+
end
|
|
148
|
+
|
|
126
149
|
def use_symbol(mod, key, *args)
|
|
127
150
|
block = block_given? ? Proc.new : nil
|
|
128
151
|
use(mod.lookup_module(key), *args, &block)
|
data/lib/faraday/connection.rb
CHANGED
|
@@ -4,10 +4,10 @@ require 'base64'
|
|
|
4
4
|
|
|
5
5
|
module Faraday
|
|
6
6
|
class Connection
|
|
7
|
-
include Addressable
|
|
7
|
+
include Addressable
|
|
8
8
|
|
|
9
|
-
METHODS = Set.new [:get, :post, :put, :delete, :head]
|
|
10
|
-
METHODS_WITH_BODIES = Set.new [:post, :put]
|
|
9
|
+
METHODS = Set.new [:get, :post, :put, :delete, :head, :patch, :options]
|
|
10
|
+
METHODS_WITH_BODIES = Set.new [:post, :put, :patch, :options]
|
|
11
11
|
|
|
12
12
|
attr_accessor :host, :port, :scheme, :params, :headers, :parallel_manager
|
|
13
13
|
attr_reader :path_prefix, :builder, :options, :ssl
|
|
@@ -22,15 +22,17 @@ module Faraday
|
|
|
22
22
|
options = url
|
|
23
23
|
url = options[:url]
|
|
24
24
|
end
|
|
25
|
-
@headers = Headers.new
|
|
26
|
-
@params =
|
|
25
|
+
@headers = Utils::Headers.new
|
|
26
|
+
@params = Utils::ParamsHash.new
|
|
27
27
|
@options = options[:request] || {}
|
|
28
28
|
@ssl = options[:ssl] || {}
|
|
29
29
|
@parallel_manager = options[:parallel]
|
|
30
|
+
|
|
30
31
|
self.url_prefix = url if url
|
|
31
32
|
proxy(options[:proxy])
|
|
32
|
-
|
|
33
|
-
|
|
33
|
+
|
|
34
|
+
@params.update options[:params] if options[:params]
|
|
35
|
+
@headers.update options[:headers] if options[:headers]
|
|
34
36
|
|
|
35
37
|
if block_given?
|
|
36
38
|
@builder = Builder.create { |b| yield b }
|
|
@@ -59,6 +61,25 @@ module Faraday
|
|
|
59
61
|
@builder.build(options, &block)
|
|
60
62
|
end
|
|
61
63
|
|
|
64
|
+
# The "rack app" wrapped in middleware. All requests are sent here.
|
|
65
|
+
#
|
|
66
|
+
# The builder is responsible for creating the app object. After this,
|
|
67
|
+
# the builder gets locked to ensure no further modifications are made
|
|
68
|
+
# to the middleware stack.
|
|
69
|
+
#
|
|
70
|
+
# Returns an object that responds to `call` and returns a Response.
|
|
71
|
+
def app
|
|
72
|
+
@app ||= begin
|
|
73
|
+
builder.lock!
|
|
74
|
+
builder.to_app(lambda { |env|
|
|
75
|
+
# the inner app that creates and returns the Response object
|
|
76
|
+
response = Response.new
|
|
77
|
+
response.finish(env) unless env[:parallel_manager]
|
|
78
|
+
env[:response] = response
|
|
79
|
+
})
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
|
|
62
83
|
def get(url = nil, headers = nil)
|
|
63
84
|
block = block_given? ? Proc.new : nil
|
|
64
85
|
run_request(:get, url, nil, headers, &block)
|
|
@@ -74,6 +95,11 @@ module Faraday
|
|
|
74
95
|
run_request(:put, url, body, headers, &block)
|
|
75
96
|
end
|
|
76
97
|
|
|
98
|
+
def patch(url = nil, body = nil, headers = nil)
|
|
99
|
+
block = block_given? ? Proc.new : nil
|
|
100
|
+
run_request(:patch, url, body, headers, &block)
|
|
101
|
+
end
|
|
102
|
+
|
|
77
103
|
def head(url = nil, headers = nil)
|
|
78
104
|
block = block_given? ? Proc.new : nil
|
|
79
105
|
run_request(:head, url, nil, headers, &block)
|
|
@@ -145,12 +171,11 @@ module Faraday
|
|
|
145
171
|
self.host = uri.host
|
|
146
172
|
self.port = uri.port
|
|
147
173
|
self.path_prefix = uri.path
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
end
|
|
174
|
+
|
|
175
|
+
@params.merge_query(uri.query)
|
|
176
|
+
basic_auth(uri.user, uri.password) if uri.user && uri.password
|
|
177
|
+
|
|
178
|
+
uri
|
|
154
179
|
end
|
|
155
180
|
|
|
156
181
|
# Ensures that the path prefix always has a leading / and no trailing /
|
|
@@ -167,12 +192,15 @@ module Faraday
|
|
|
167
192
|
raise ArgumentError, "unknown http method: #{method}"
|
|
168
193
|
end
|
|
169
194
|
|
|
170
|
-
Request.
|
|
195
|
+
request = Request.create(method) do |req|
|
|
171
196
|
req.url(url) if url
|
|
172
197
|
req.headers.update(headers) if headers
|
|
173
198
|
req.body = body if body
|
|
174
199
|
yield req if block_given?
|
|
175
200
|
end
|
|
201
|
+
|
|
202
|
+
env = request.to_env(self)
|
|
203
|
+
self.app.call(env)
|
|
176
204
|
end
|
|
177
205
|
|
|
178
206
|
# Takes a relative url for a request and combines it with the defaults
|
|
@@ -186,15 +214,21 @@ module Faraday
|
|
|
186
214
|
# conn.build_url("nigiri?page=2") # => https://sushi.com/api/nigiri?token=abc&page=2
|
|
187
215
|
# conn.build_url("nigiri", :page => 2) # => https://sushi.com/api/nigiri?token=abc&page=2
|
|
188
216
|
#
|
|
189
|
-
def build_url(url,
|
|
217
|
+
def build_url(url, extra_params = nil)
|
|
190
218
|
uri = URI.parse(url.to_s)
|
|
191
219
|
if @path_prefix && uri.path !~ /^\//
|
|
192
|
-
|
|
220
|
+
new_path = @path_prefix.size > 1 ? @path_prefix.dup : ''
|
|
221
|
+
new_path << "/#{uri.path}" unless uri.path.empty?
|
|
222
|
+
uri.path = new_path
|
|
193
223
|
end
|
|
194
224
|
uri.host ||= @host
|
|
195
225
|
uri.port ||= @port
|
|
196
226
|
uri.scheme ||= @scheme
|
|
197
|
-
|
|
227
|
+
|
|
228
|
+
params = @params.dup.merge_query(uri.query)
|
|
229
|
+
params.update extra_params if extra_params
|
|
230
|
+
uri.query = params.empty? ? nil : params.to_query
|
|
231
|
+
|
|
198
232
|
uri
|
|
199
233
|
end
|
|
200
234
|
|
|
@@ -202,18 +236,6 @@ module Faraday
|
|
|
202
236
|
self.class.new(build_url(''), :headers => headers.dup, :params => params.dup, :builder => builder.dup)
|
|
203
237
|
end
|
|
204
238
|
|
|
205
|
-
def replace_query(uri, params)
|
|
206
|
-
url_params = @params.dup
|
|
207
|
-
if uri.query && !uri.query.empty?
|
|
208
|
-
merge_params(url_params, parse_query(uri.query))
|
|
209
|
-
end
|
|
210
|
-
if params && !params.empty?
|
|
211
|
-
merge_params(url_params, params)
|
|
212
|
-
end
|
|
213
|
-
uri.query = url_params.empty? ? nil : build_query(url_params)
|
|
214
|
-
uri
|
|
215
|
-
end
|
|
216
|
-
|
|
217
239
|
def proxy_arg_to_uri(arg)
|
|
218
240
|
case arg
|
|
219
241
|
when String then URI.parse(arg)
|
data/lib/faraday/error.rb
CHANGED
data/lib/faraday/request/json.rb
CHANGED
|
@@ -3,7 +3,11 @@ module Faraday
|
|
|
3
3
|
self.mime_type = 'application/json'.freeze
|
|
4
4
|
|
|
5
5
|
class << self
|
|
6
|
-
|
|
6
|
+
attr_writer :adapter
|
|
7
|
+
|
|
8
|
+
def adapter
|
|
9
|
+
@adapter or raise Error::MissingDependency, "No JSON adapter available. Install either activesupport or yajl-ruby."
|
|
10
|
+
end
|
|
7
11
|
end
|
|
8
12
|
|
|
9
13
|
# loads the JSON encoder either from yajl-ruby or activesupport
|