faraday 0.8.11 → 0.9.0

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.
Files changed (68) hide show
  1. checksums.yaml +4 -4
  2. data/.document +6 -0
  3. data/CHANGELOG.md +15 -0
  4. data/CONTRIBUTING.md +36 -0
  5. data/Gemfile +10 -3
  6. data/LICENSE.md +1 -1
  7. data/README.md +17 -51
  8. data/Rakefile +2 -18
  9. data/faraday.gemspec +34 -0
  10. data/lib/faraday/adapter/em_http.rb +34 -0
  11. data/lib/faraday/adapter/em_http_ssl_patch.rb +56 -0
  12. data/lib/faraday/adapter/em_synchrony.rb +11 -24
  13. data/lib/faraday/adapter/excon.rb +12 -2
  14. data/lib/faraday/adapter/httpclient.rb +106 -0
  15. data/lib/faraday/adapter/net_http.rb +10 -6
  16. data/lib/faraday/adapter/patron.rb +2 -8
  17. data/lib/faraday/adapter/rack.rb +0 -2
  18. data/lib/faraday/adapter/test.rb +39 -39
  19. data/lib/faraday/adapter/typhoeus.rb +12 -3
  20. data/lib/faraday/adapter.rb +20 -35
  21. data/lib/faraday/autoload.rb +85 -0
  22. data/lib/faraday/connection.rb +232 -125
  23. data/lib/faraday/error.rb +42 -34
  24. data/lib/faraday/options.rb +350 -0
  25. data/lib/faraday/parameters.rb +193 -0
  26. data/lib/faraday/{builder.rb → rack_builder.rb} +79 -22
  27. data/lib/faraday/request/authorization.rb +7 -5
  28. data/lib/faraday/request/basic_authentication.rb +1 -1
  29. data/lib/faraday/request/instrumentation.rb +36 -0
  30. data/lib/faraday/request/multipart.rb +10 -9
  31. data/lib/faraday/request/retry.rb +99 -4
  32. data/lib/faraday/request/token_authentication.rb +2 -2
  33. data/lib/faraday/request/url_encoded.rb +7 -6
  34. data/lib/faraday/request.rb +21 -30
  35. data/lib/faraday/response/logger.rb +4 -4
  36. data/lib/faraday/response/raise_error.rb +4 -2
  37. data/lib/faraday/response.rb +17 -23
  38. data/lib/faraday/utils.rb +81 -71
  39. data/lib/faraday.rb +187 -68
  40. data/script/console +7 -0
  41. data/script/proxy-server +1 -0
  42. data/script/release +6 -3
  43. data/script/test +4 -2
  44. data/test/adapters/em_http_test.rb +6 -1
  45. data/test/adapters/em_synchrony_test.rb +7 -1
  46. data/test/adapters/httpclient_test.rb +21 -0
  47. data/test/adapters/integration.rb +23 -8
  48. data/test/adapters/logger_test.rb +1 -1
  49. data/test/adapters/net_http_persistent_test.rb +10 -1
  50. data/test/adapters/net_http_test.rb +0 -31
  51. data/test/adapters/patron_test.rb +4 -1
  52. data/test/adapters/test_middleware_test.rb +48 -4
  53. data/test/adapters/typhoeus_test.rb +8 -1
  54. data/test/authentication_middleware_test.rb +2 -2
  55. data/test/connection_test.rb +160 -84
  56. data/test/env_test.rb +51 -24
  57. data/test/helper.rb +13 -13
  58. data/test/live_server.rb +8 -0
  59. data/test/middleware/instrumentation_test.rb +88 -0
  60. data/test/middleware/retry_test.rb +88 -35
  61. data/test/middleware_stack_test.rb +13 -12
  62. data/test/options_test.rb +252 -0
  63. data/test/request_middleware_test.rb +11 -1
  64. data/test/response_middleware_test.rb +2 -4
  65. data/test/strawberry.rb +2 -0
  66. data/test/utils_test.rb +34 -6
  67. metadata +71 -11
  68. data/test/parameters_test.rb +0 -24
@@ -21,53 +21,52 @@ module Faraday
21
21
  def initialize
22
22
  # {:get => [Stub, Stub]}
23
23
  @stack, @consumed = {}, {}
24
- yield self if block_given?
24
+ yield(self) if block_given?
25
25
  end
26
26
 
27
27
  def empty?
28
28
  @stack.empty?
29
29
  end
30
30
 
31
- def match(request_method, path, body)
31
+ def match(request_method, path, headers, body)
32
32
  return false if !@stack.key?(request_method)
33
33
  stack = @stack[request_method]
34
34
  consumed = (@consumed[request_method] ||= [])
35
- path = normalize_path(path)
36
35
 
37
- if stub = matches?(stack, path, body)
36
+ if stub = matches?(stack, path, headers, body)
38
37
  consumed << stack.delete(stub)
39
38
  stub
40
39
  else
41
- matches?(consumed, path, body)
40
+ matches?(consumed, path, headers, body)
42
41
  end
43
42
  end
44
43
 
45
- def get(path, &block)
46
- new_stub(:get, path, &block)
44
+ def get(path, headers = {}, &block)
45
+ new_stub(:get, path, headers, &block)
47
46
  end
48
47
 
49
- def head(path, &block)
50
- new_stub(:head, path, &block)
48
+ def head(path, headers = {}, &block)
49
+ new_stub(:head, path, headers, &block)
51
50
  end
52
51
 
53
- def post(path, body=nil, &block)
54
- new_stub(:post, path, body, &block)
52
+ def post(path, body=nil, headers = {}, &block)
53
+ new_stub(:post, path, headers, body, &block)
55
54
  end
56
55
 
57
- def put(path, body=nil, &block)
58
- new_stub(:put, path, body, &block)
56
+ def put(path, body=nil, headers = {}, &block)
57
+ new_stub(:put, path, headers, body, &block)
59
58
  end
60
59
 
61
- def patch(path, body=nil, &block)
62
- new_stub(:patch, path, body, &block)
60
+ def patch(path, body=nil, headers = {}, &block)
61
+ new_stub(:patch, path, headers, body, &block)
63
62
  end
64
63
 
65
- def delete(path, &block)
66
- new_stub(:delete, path, &block)
64
+ def delete(path, headers = {}, &block)
65
+ new_stub(:delete, path, headers, &block)
67
66
  end
68
67
 
69
- def options(path, &block)
70
- new_stub(:options, path, &block)
68
+ def options(path, headers = {}, &block)
69
+ new_stub(:options, path, headers, &block)
71
70
  end
72
71
 
73
72
  # Raises an error if any of the stubbed calls have not been made.
@@ -85,40 +84,34 @@ module Faraday
85
84
 
86
85
  protected
87
86
 
88
- def new_stub(request_method, path, body=nil, &block)
89
- (@stack[request_method] ||= []) << Stub.new(normalize_path(path), body, block)
87
+ def new_stub(request_method, path, headers = {}, body=nil, &block)
88
+ normalized_path = Faraday::Utils.normalize_path(path)
89
+ (@stack[request_method] ||= []) << Stub.new(normalized_path, headers, body, block)
90
90
  end
91
91
 
92
- def matches?(stack, path, body)
93
- stack.detect { |stub| stub.matches?(path, body) }
94
- end
95
-
96
- # ensure leading + trailing slash
97
- def normalize_path(path)
98
- path = '/' + path if path.index('/') != 0
99
- path = path.sub('?', '/?')
100
- path = path + '/' unless $&
101
- path.gsub('//', '/')
92
+ def matches?(stack, path, headers, body)
93
+ stack.detect { |stub| stub.matches?(path, headers, body) }
102
94
  end
103
95
  end
104
96
 
105
- class Stub < Struct.new(:path, :params, :body, :block)
106
- def initialize(full, body, block)
97
+ class Stub < Struct.new(:path, :params, :headers, :body, :block)
98
+ def initialize(full, headers, body, block)
107
99
  path, query = full.split('?')
108
100
  params = query ?
109
101
  Faraday::Utils.parse_nested_query(query) :
110
102
  {}
111
- super path, params, body, block
103
+ super(path, params, headers, body, block)
112
104
  end
113
105
 
114
- def matches?(request_uri, request_body)
106
+ def matches?(request_uri, request_headers, request_body)
115
107
  request_path, request_query = request_uri.split('?')
116
108
  request_params = request_query ?
117
109
  Faraday::Utils.parse_nested_query(request_query) :
118
110
  {}
119
111
  request_path == path &&
120
112
  params_match?(request_params) &&
121
- (body.to_s.size.zero? || request_body == body)
113
+ (body.to_s.size.zero? || request_body == body) &&
114
+ headers_match?(request_headers)
122
115
  end
123
116
 
124
117
  def params_match?(request_params)
@@ -127,6 +120,12 @@ module Faraday
127
120
  end
128
121
  end
129
122
 
123
+ def headers_match?(request_headers)
124
+ headers.keys.all? do |key|
125
+ request_headers[key] == headers[key]
126
+ end
127
+ end
128
+
130
129
  def to_s
131
130
  "#{path} #{body}"
132
131
  end
@@ -139,16 +138,17 @@ module Faraday
139
138
  end
140
139
 
141
140
  def configure
142
- yield stubs
141
+ yield(stubs)
143
142
  end
144
143
 
145
144
  def call(env)
146
145
  super
147
146
  normalized_path = Faraday::Utils.normalize_path(env[:url])
147
+ params_encoder = env.request.params_encoder || Faraday::Utils.default_params_encoder
148
148
 
149
- if stub = stubs.match(env[:method], normalized_path, env[:body])
149
+ if stub = stubs.match(env[:method], normalized_path, env.request_headers, env[:body])
150
150
  env[:params] = (query = env[:url].query) ?
151
- Faraday::Utils.parse_nested_query(query) :
151
+ params_encoder.decode(query) :
152
152
  {}
153
153
  status, headers, body = stub.block.call(env)
154
154
  save_response(env, status, body, headers)
@@ -40,11 +40,12 @@ module Faraday
40
40
  :method => method,
41
41
  :body => env[:body],
42
42
  :headers => env[:request_headers],
43
- :disable_ssl_peer_verification => (env[:ssl] && !env[:ssl].fetch(:verify, true))
43
+ :disable_ssl_peer_verification => (env[:ssl] && env[:ssl].disable?)
44
44
 
45
45
  configure_ssl req, env
46
46
  configure_proxy req, env
47
47
  configure_timeout req, env
48
+ configure_socket req, env
48
49
 
49
50
  req.on_complete do |resp|
50
51
  if resp.timed_out?
@@ -60,6 +61,8 @@ module Faraday
60
61
  # everything OK
61
62
  when 7
62
63
  raise Error::ConnectionFailed, resp.curl_error_message
64
+ when 60
65
+ raise Faraday::SSLError, resp.curl_error_message
63
66
  else
64
67
  raise Error::ClientError, resp.curl_error_message
65
68
  end
@@ -78,8 +81,8 @@ module Faraday
78
81
  ssl = env[:ssl]
79
82
 
80
83
  req.ssl_version = ssl[:version] if ssl[:version]
81
- req.ssl_cert = ssl[:client_cert_file] if ssl[:client_cert_file]
82
- req.ssl_key = ssl[:client_key_file] if ssl[:client_key_file]
84
+ req.ssl_cert = ssl[:client_cert] if ssl[:client_cert]
85
+ req.ssl_key = ssl[:client_key] if ssl[:client_key]
83
86
  req.ssl_cacert = ssl[:ca_file] if ssl[:ca_file]
84
87
  req.ssl_capath = ssl[:ca_path] if ssl[:ca_path]
85
88
  end
@@ -102,6 +105,12 @@ module Faraday
102
105
  req.connect_timeout = (env_req[:open_timeout] * 1000) if env_req[:open_timeout]
103
106
  end
104
107
 
108
+ def configure_socket(req, env)
109
+ if bind = request_options(env)[:bind]
110
+ req.interface = bind[:host]
111
+ end
112
+ end
113
+
105
114
  def request_options(env)
106
115
  env[:request]
107
116
  end
@@ -1,32 +1,22 @@
1
1
  module Faraday
2
+ # Public: This is a base class for all Faraday adapters. Adapters are
3
+ # responsible for fulfilling a Faraday request.
2
4
  class Adapter < Middleware
3
5
  CONTENT_LENGTH = 'Content-Length'.freeze
4
6
 
5
- extend AutoloadHelper
6
- extend MiddlewareRegistry
7
-
8
- autoload_all 'faraday/adapter',
9
- :NetHttp => 'net_http',
10
- :NetHttpPersistent => 'net_http_persistent',
11
- :Typhoeus => 'typhoeus',
12
- :EMSynchrony => 'em_synchrony',
13
- :EMHttp => 'em_http',
14
- :Patron => 'patron',
15
- :Excon => 'excon',
16
- :Test => 'test',
17
- :Rack => 'rack'
18
-
19
- register_middleware \
20
- :test => :Test,
21
- :net_http => :NetHttp,
22
- :net_http_persistent => :NetHttpPersistent,
23
- :typhoeus => :Typhoeus,
24
- :patron => :Patron,
25
- :em_synchrony => :EMSynchrony,
26
- :em_http => :EMHttp,
27
- :excon => :Excon,
28
- :rack => :Rack
29
-
7
+ register_middleware File.expand_path('../adapter', __FILE__),
8
+ :test => [:Test, 'test'],
9
+ :net_http => [:NetHttp, 'net_http'],
10
+ :net_http_persistent => [:NetHttpPersistent, 'net_http_persistent'],
11
+ :typhoeus => [:Typhoeus, 'typhoeus'],
12
+ :patron => [:Patron, 'patron'],
13
+ :em_synchrony => [:EMSynchrony, 'em_synchrony'],
14
+ :em_http => [:EMHttp, 'em_http'],
15
+ :excon => [:Excon, 'excon'],
16
+ :rack => [:Rack, 'rack'],
17
+ :httpclient => [:HTTPClient, 'httpclient']
18
+
19
+ # Public: This module marks an Adapter as supporting parallel requests.
30
20
  module Parallelism
31
21
  attr_writer :supports_parallel
32
22
  def supports_parallel?() @supports_parallel end
@@ -41,20 +31,15 @@ module Faraday
41
31
  self.supports_parallel = false
42
32
 
43
33
  def call(env)
44
- if !env[:body] and Connection::METHODS_WITH_BODIES.include? env[:method]
45
- # play nice and indicate we're sending an empty body
46
- env[:request_headers][CONTENT_LENGTH] = "0"
47
- # Typhoeus hangs on PUT requests if body is nil
48
- env[:body] = ''
49
- end
34
+ env.clear_body if env.needs_body?
50
35
  end
51
36
 
52
37
  def save_response(env, status, body, headers = nil)
53
- env[:status] = status
54
- env[:body] = body
55
- env[:response_headers] = Utils::Headers.new.tap do |response_headers|
38
+ env.status = status
39
+ env.body = body
40
+ env.response_headers = Utils::Headers.new.tap do |response_headers|
56
41
  response_headers.update headers unless headers.nil?
57
- yield response_headers if block_given?
42
+ yield(response_headers) if block_given?
58
43
  end
59
44
  end
60
45
  end
@@ -0,0 +1,85 @@
1
+ module Faraday
2
+ # Internal: Adds the ability for other modules to manage autoloadable
3
+ # constants.
4
+ module AutoloadHelper
5
+ # Internal: Registers the constants to be auto loaded.
6
+ #
7
+ # prefix - The String require prefix. If the path is inside Faraday, then
8
+ # it will be prefixed with the root path of this loaded Faraday
9
+ # version.
10
+ # options - Hash of Symbol => String library names.
11
+ #
12
+ # Examples.
13
+ #
14
+ # Faraday.autoload_all 'faraday/foo',
15
+ # :Bar => 'bar'
16
+ #
17
+ # # requires faraday/foo/bar to load Faraday::Bar.
18
+ # Faraday::Bar
19
+ #
20
+ #
21
+ # Returns nothing.
22
+ def autoload_all(prefix, options)
23
+ if prefix =~ /^faraday(\/|$)/i
24
+ prefix = File.join(Faraday.root_path, prefix)
25
+ end
26
+ options.each do |const_name, path|
27
+ autoload const_name, File.join(prefix, path)
28
+ end
29
+ end
30
+
31
+ # Internal: Loads each autoloaded constant. If thread safety is a concern,
32
+ # wrap this in a Mutex.
33
+ #
34
+ # Returns nothing.
35
+ def load_autoloaded_constants
36
+ constants.each do |const|
37
+ const_get(const) if autoload?(const)
38
+ end
39
+ end
40
+
41
+ # Internal: Filters the module's contents with those that have been already
42
+ # autoloaded.
43
+ #
44
+ # Returns an Array of Class/Module objects.
45
+ def all_loaded_constants
46
+ constants.map { |c| const_get(c) }.
47
+ select { |a| a.respond_to?(:loaded?) && a.loaded? }
48
+ end
49
+ end
50
+
51
+ class Adapter
52
+ extend AutoloadHelper
53
+ autoload_all 'faraday/adapter',
54
+ :NetHttp => 'net_http',
55
+ :NetHttpPersistent => 'net_http_persistent',
56
+ :Typhoeus => 'typhoeus',
57
+ :EMSynchrony => 'em_synchrony',
58
+ :EMHttp => 'em_http',
59
+ :Patron => 'patron',
60
+ :Excon => 'excon',
61
+ :Test => 'test',
62
+ :Rack => 'rack',
63
+ :HTTPClient => 'httpclient'
64
+ end
65
+
66
+ class Request
67
+ extend AutoloadHelper
68
+ autoload_all 'faraday/request',
69
+ :UrlEncoded => 'url_encoded',
70
+ :Multipart => 'multipart',
71
+ :Retry => 'retry',
72
+ :Timeout => 'timeout',
73
+ :Authorization => 'authorization',
74
+ :BasicAuthentication => 'basic_authentication',
75
+ :TokenAuthentication => 'token_authentication',
76
+ :Instrumentation => 'instrumentation'
77
+ end
78
+
79
+ class Response
80
+ extend AutoloadHelper
81
+ autoload_all 'faraday/response',
82
+ :RaiseError => 'raise_error',
83
+ :Logger => 'logger'
84
+ end
85
+ end