faraday 0.8.11 → 0.9.0.rc1

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 (70) hide show
  1. data/.document +6 -0
  2. data/CONTRIBUTING.md +36 -0
  3. data/Gemfile +7 -6
  4. data/LICENSE.md +1 -1
  5. data/README.md +38 -51
  6. data/Rakefile +2 -18
  7. data/faraday.gemspec +34 -0
  8. data/lib/faraday.rb +181 -67
  9. data/lib/faraday/adapter.rb +19 -34
  10. data/lib/faraday/adapter/em_http.rb +24 -10
  11. data/lib/faraday/adapter/em_synchrony.rb +1 -15
  12. data/lib/faraday/adapter/excon.rb +6 -12
  13. data/lib/faraday/adapter/httpclient.rb +92 -0
  14. data/lib/faraday/adapter/net_http.rb +2 -3
  15. data/lib/faraday/adapter/net_http_persistent.rb +3 -15
  16. data/lib/faraday/adapter/patron.rb +13 -21
  17. data/lib/faraday/adapter/rack.rb +0 -2
  18. data/lib/faraday/adapter/test.rb +35 -36
  19. data/lib/faraday/adapter/typhoeus.rb +10 -12
  20. data/lib/faraday/autoload.rb +87 -0
  21. data/lib/faraday/connection.rb +196 -99
  22. data/lib/faraday/error.rb +33 -33
  23. data/lib/faraday/options.rb +215 -0
  24. data/lib/faraday/parameters.rb +193 -0
  25. data/lib/faraday/{builder.rb → rack_builder.rb} +78 -21
  26. data/lib/faraday/request.rb +12 -25
  27. data/lib/faraday/request/authorization.rb +3 -3
  28. data/lib/faraday/request/basic_authentication.rb +1 -1
  29. data/lib/faraday/request/instrumentation.rb +38 -0
  30. data/lib/faraday/request/multipart.rb +10 -9
  31. data/lib/faraday/request/retry.rb +70 -6
  32. data/lib/faraday/request/token_authentication.rb +2 -2
  33. data/lib/faraday/request/url_encoded.rb +7 -6
  34. data/lib/faraday/response.rb +17 -22
  35. data/lib/faraday/response/logger.rb +4 -4
  36. data/lib/faraday/response/raise_error.rb +4 -5
  37. data/lib/faraday/utils.rb +54 -67
  38. data/script/console +7 -0
  39. data/script/release +6 -3
  40. data/script/server +3 -1
  41. data/script/test +7 -33
  42. data/test/adapters/em_http_test.rb +6 -1
  43. data/test/adapters/em_synchrony_test.rb +7 -1
  44. data/test/adapters/excon_test.rb +0 -7
  45. data/test/adapters/httpclient_test.rb +16 -0
  46. data/test/adapters/integration.rb +8 -39
  47. data/test/adapters/logger_test.rb +1 -1
  48. data/test/adapters/net_http_test.rb +0 -31
  49. data/test/adapters/patron_test.rb +1 -1
  50. data/test/adapters/rack_test.rb +0 -5
  51. data/test/adapters/test_middleware_test.rb +19 -4
  52. data/test/adapters/typhoeus_test.rb +20 -3
  53. data/test/authentication_middleware_test.rb +7 -7
  54. data/test/connection_test.rb +52 -75
  55. data/test/env_test.rb +33 -24
  56. data/test/helper.rb +15 -13
  57. data/test/live_server.rb +10 -4
  58. data/test/middleware/instrumentation_test.rb +75 -0
  59. data/test/middleware/retry_test.rb +44 -38
  60. data/test/middleware_stack_test.rb +12 -11
  61. data/test/options_test.rb +126 -0
  62. data/test/request_middleware_test.rb +17 -7
  63. data/test/response_middleware_test.rb +2 -4
  64. data/test/strawberry.rb +2 -0
  65. metadata +82 -28
  66. checksums.yaml +0 -7
  67. data/script/proxy-server +0 -41
  68. data/test/multibyte.txt +0 -1
  69. data/test/parameters_test.rb +0 -24
  70. data/test/utils_test.rb +0 -30
@@ -28,46 +28,45 @@ module Faraday
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
@@ -146,7 +145,7 @@ module Faraday
146
145
  super
147
146
  normalized_path = Faraday::Utils.normalize_path(env[:url])
148
147
 
149
- if stub = stubs.match(env[:method], normalized_path, env[:body])
148
+ if stub = stubs.match(env[:method], normalized_path, env.request_headers, env[:body])
150
149
  env[:params] = (query = env[:url].query) ?
151
150
  Faraday::Utils.parse_nested_query(query) :
152
151
  {}
@@ -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?
@@ -55,15 +56,6 @@ module Faraday
55
56
  end
56
57
  end
57
58
 
58
- case resp.curl_return_code
59
- when 0
60
- # everything OK
61
- when 7
62
- raise Error::ConnectionFailed, resp.curl_error_message
63
- else
64
- raise Error::ClientError, resp.curl_error_message
65
- end
66
-
67
59
  save_response(env, resp.code, resp.body) do |response_headers|
68
60
  response_headers.parse resp.headers
69
61
  end
@@ -78,8 +70,8 @@ module Faraday
78
70
  ssl = env[:ssl]
79
71
 
80
72
  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]
73
+ req.ssl_cert = ssl[:client_cert] if ssl[:client_cert]
74
+ req.ssl_key = ssl[:client_key] if ssl[:client_key]
83
75
  req.ssl_cacert = ssl[:ca_file] if ssl[:ca_file]
84
76
  req.ssl_capath = ssl[:ca_path] if ssl[:ca_path]
85
77
  end
@@ -102,6 +94,12 @@ module Faraday
102
94
  req.connect_timeout = (env_req[:open_timeout] * 1000) if env_req[:open_timeout]
103
95
  end
104
96
 
97
+ def configure_socket(req, env)
98
+ if bind = request_options(env)[:bind]
99
+ req.interface = bind[:host]
100
+ end
101
+ end
102
+
105
103
  def request_options(env)
106
104
  env[:request]
107
105
  end
@@ -0,0 +1,87 @@
1
+ require 'faraday'
2
+
3
+ module Faraday
4
+ # Internal: Adds the ability for other modules to manage autoloadable
5
+ # constants.
6
+ module AutoloadHelper
7
+ # Internal: Registers the constants to be auto loaded.
8
+ #
9
+ # prefix - The String require prefix. If the path is inside Faraday, then
10
+ # it will be prefixed with the root path of this loaded Faraday
11
+ # version.
12
+ # options - Hash of Symbol => String library names.
13
+ #
14
+ # Examples.
15
+ #
16
+ # Faraday.autoload_all 'faraday/foo',
17
+ # :Bar => 'bar'
18
+ #
19
+ # # requires faraday/foo/bar to load Faraday::Bar.
20
+ # Faraday::Bar
21
+ #
22
+ #
23
+ # Returns nothing.
24
+ def autoload_all(prefix, options)
25
+ if prefix =~ /^faraday(\/|$)/i
26
+ prefix = File.join(Faraday.root_path, prefix)
27
+ end
28
+ options.each do |const_name, path|
29
+ autoload const_name, File.join(prefix, path)
30
+ end
31
+ end
32
+
33
+ # Internal: Loads each autoloaded constant. If thread safety is a concern,
34
+ # wrap this in a Mutex.
35
+ #
36
+ # Returns nothing.
37
+ def load_autoloaded_constants
38
+ constants.each do |const|
39
+ const_get(const) if autoload?(const)
40
+ end
41
+ end
42
+
43
+ # Internal: Filters the module's contents with those that have been already
44
+ # autoloaded.
45
+ #
46
+ # Returns an Array of Class/Module objects.
47
+ def all_loaded_constants
48
+ constants.map { |c| const_get(c) }.
49
+ select { |a| a.respond_to?(:loaded?) && a.loaded? }
50
+ end
51
+ end
52
+
53
+ class Adapter
54
+ extend AutoloadHelper
55
+ autoload_all 'faraday/adapter',
56
+ :NetHttp => 'net_http',
57
+ :NetHttpPersistent => 'net_http_persistent',
58
+ :Typhoeus => 'typhoeus',
59
+ :EMSynchrony => 'em_synchrony',
60
+ :EMHttp => 'em_http',
61
+ :Patron => 'patron',
62
+ :Excon => 'excon',
63
+ :Test => 'test',
64
+ :Rack => 'rack',
65
+ :HTTPClient => 'httpclient'
66
+ end
67
+
68
+ class Request
69
+ extend AutoloadHelper
70
+ autoload_all 'faraday/request',
71
+ :UrlEncoded => 'url_encoded',
72
+ :Multipart => 'multipart',
73
+ :Retry => 'retry',
74
+ :Timeout => 'timeout',
75
+ :Authorization => 'authorization',
76
+ :BasicAuthentication => 'basic_authentication',
77
+ :TokenAuthentication => 'token_authentication'
78
+ end
79
+
80
+ class Response
81
+ extend AutoloadHelper
82
+ autoload_all 'faraday/response',
83
+ :RaiseError => 'raise_error',
84
+ :Logger => 'logger'
85
+ end
86
+ end
87
+
@@ -1,24 +1,49 @@
1
- require 'cgi'
2
- require 'set'
3
- require 'forwardable'
4
- require 'uri'
5
-
6
- Faraday.require_libs 'builder', 'request', 'response', 'utils'
7
-
8
1
  module Faraday
2
+ # Public: Connection objects manage the default properties and the middleware
3
+ # stack for fulfilling an HTTP request.
4
+ #
5
+ # Examples
6
+ #
7
+ # conn = Faraday::Connection.new 'http://sushi.com'
8
+ #
9
+ # # GET http://sushi.com/nigiri
10
+ # conn.get 'nigiri'
11
+ # # => #<Faraday::Response>
12
+ #
9
13
  class Connection
14
+ # A Set of allowed HTTP verbs.
10
15
  METHODS = Set.new [:get, :post, :put, :delete, :head, :patch, :options]
11
- METHODS_WITH_BODIES = Set.new [:post, :put, :patch, :options]
12
16
 
13
- attr_reader :params, :headers, :url_prefix, :builder, :options, :ssl, :parallel_manager
17
+ # Public: Returns a Hash of URI query unencoded key/value pairs.
18
+ attr_reader :params
19
+
20
+ # Public: Returns a Hash of unencoded HTTP header key/value pairs.
21
+ attr_reader :headers
22
+
23
+ # Public: Returns a URI with the prefix used for all requests from this
24
+ # Connection. This includes a default host name, scheme, port, and path.
25
+ attr_reader :url_prefix
26
+
27
+ # Public: Returns the Faraday::Builder for this Connection.
28
+ attr_reader :builder
29
+
30
+ # Public: Returns a Hash of the request options.
31
+ attr_reader :options
32
+
33
+ # Public: Returns a Hash of the SSL options.
34
+ attr_reader :ssl
35
+
36
+ # Public: Returns the parallel manager for this Connection.
37
+ attr_reader :parallel_manager
38
+
39
+ # Public: Sets the default parallel manager for this connection.
14
40
  attr_writer :default_parallel_manager
15
41
 
16
42
  # Public: Initializes a new Faraday::Connection.
17
43
  #
18
44
  # url - URI or String base URL to use as a prefix for all
19
45
  # requests (optional).
20
- # options - Hash of settings that will be applied to every request made
21
- # from this Connection (default: {}).
46
+ # options - Hash or Faraday::ConnectionOptions.
22
47
  # :url - URI or String base URL (default: "http:/").
23
48
  # :params - Hash of URI query unencoded key/value pairs.
24
49
  # :headers - Hash of unencoded HTTP header key/value pairs.
@@ -29,77 +54,79 @@ module Faraday
29
54
  # :uri - URI or String
30
55
  # :user - String (optional)
31
56
  # :password - String (optional)
32
- def initialize(url = nil, options = {})
57
+ def initialize(url = nil, options = nil)
33
58
  if url.is_a?(Hash)
34
- options = url
35
- url = options[:url]
59
+ options = ConnectionOptions.from(url)
60
+ url = options.url
61
+ else
62
+ options = ConnectionOptions.from(options)
36
63
  end
37
- @headers = Utils::Headers.new
38
- @params = Utils::ParamsHash.new
39
- @options = options[:request] || {}
40
- @ssl = options[:ssl] || {}
41
64
 
42
65
  @parallel_manager = nil
43
- @default_parallel_manager = options[:parallel_manager]
66
+ @headers = Utils::Headers.new
67
+ @params = Utils::ParamsHash.new
68
+ @options = options.request
69
+ @ssl = options.ssl
70
+ @default_parallel_manager = options.parallel_manager
44
71
 
45
- @builder = options[:builder] || begin
72
+ @builder = options.builder || begin
46
73
  # pass an empty block to Builder so it doesn't assume default middleware
47
- block = block_given?? Proc.new {|b| } : nil
48
- Builder.new(&block)
74
+ options.new_builder(block_given? ? Proc.new { |b| } : nil)
49
75
  end
50
76
 
51
77
  self.url_prefix = url || 'http:/'
52
78
 
53
- @params.update options[:params] if options[:params]
54
- @headers.update options[:headers] if options[:headers]
79
+ @params.update(options.params) if options.params
80
+ @headers.update(options.headers) if options.headers
55
81
 
56
- @proxy = nil
57
- proxy(options.fetch(:proxy) {
58
- uri = ENV['http_proxy']
59
- if uri && !uri.empty?
60
- uri = 'http://' + uri if uri !~ /^http/i
61
- uri
62
- end
63
- })
82
+ proxy(options.fetch(:proxy) { ENV['http_proxy'] })
64
83
 
65
84
  yield self if block_given?
66
85
 
67
86
  @headers[:user_agent] ||= "Faraday v#{VERSION}"
68
87
  end
69
88
 
70
- # Public: Replace default query parameters.
89
+ # Public: Sets the Hash of URI query unencoded key/value pairs.
71
90
  def params=(hash)
72
91
  @params.replace hash
73
92
  end
74
93
 
75
- # Public: Replace default request headers.
94
+ # Public: Sets the Hash of unencoded HTTP header key/value pairs.
76
95
  def headers=(hash)
77
96
  @headers.replace hash
78
97
  end
79
98
 
80
99
  extend Forwardable
81
- def_delegators :builder, :build, :use, :request, :response, :adapter
82
-
83
- # The "rack app" wrapped in middleware. All requests are sent here.
84
- #
85
- # The builder is responsible for creating the app object. After this,
86
- # the builder gets locked to ensure no further modifications are made
87
- # to the middleware stack.
88
- #
89
- # Returns an object that responds to `call` and returns a Response.
90
- def app
91
- @app ||= begin
92
- builder.lock!
93
- builder.to_app(lambda { |env|
94
- # the inner app that creates and returns the Response object
95
- response = Response.new
96
- response.finish(env) unless env[:parallel_manager]
97
- env[:response] = response
98
- })
99
- end
100
- end
101
100
 
102
- # get/head/delete(url, params, headers)
101
+ def_delegators :builder, :build, :use, :request, :response, :adapter, :app
102
+
103
+ # Public: Makes an HTTP request without a body.
104
+ #
105
+ # url - The optional String base URL to use as a prefix for all
106
+ # requests. Can also be the options Hash.
107
+ # params - Hash of URI query unencoded key/value pairs.
108
+ # headers - Hash of unencoded HTTP header key/value pairs.
109
+ #
110
+ # Examples
111
+ #
112
+ # conn.get '/items', {:page => 1}, :accept => 'application/json'
113
+ # conn.head '/items/1'
114
+ #
115
+ # # ElasticSearch example sending a body with GET.
116
+ # conn.get '/twitter/tweet/_search' do |req|
117
+ # req.headers[:content_type] = 'application/json'
118
+ # req.params[:routing] = 'kimchy'
119
+ # req.body = JSON.generate(:query => {...})
120
+ # end
121
+ #
122
+ # Yields a Faraday::Response for further request customizations.
123
+ # Returns a Faraday::Response.
124
+ #
125
+ # Signature
126
+ #
127
+ # <verb>(url = nil, params = nil, headers = nil)
128
+ #
129
+ # verb - An HTTP verb: get, head, or delete.
103
130
  %w[get head delete].each do |method|
104
131
  class_eval <<-RUBY, __FILE__, __LINE__ + 1
105
132
  def #{method}(url = nil, params = nil, headers = nil)
@@ -111,7 +138,32 @@ module Faraday
111
138
  RUBY
112
139
  end
113
140
 
114
- # post/put/patch(url, body, headers)
141
+ # Public: Makes an HTTP request with a body.
142
+ #
143
+ # url - The optional String base URL to use as a prefix for all
144
+ # requests. Can also be the options Hash.
145
+ # body - The String body for the request.
146
+ # headers - Hash of unencoded HTTP header key/value pairs.
147
+ #
148
+ # Examples
149
+ #
150
+ # conn.post '/items', data, :content_type => 'application/json'
151
+ #
152
+ # # Simple ElasticSearch indexing sample.
153
+ # conn.post '/twitter/tweet' do |req|
154
+ # req.headers[:content_type] = 'application/json'
155
+ # req.params[:routing] = 'kimchy'
156
+ # req.body = JSON.generate(:user => 'kimchy', ...)
157
+ # end
158
+ #
159
+ # Yields a Faraday::Response for further request customizations.
160
+ # Returns a Faraday::Response.
161
+ #
162
+ # Signature
163
+ #
164
+ # <verb>(url = nil, body = nil, headers = nil)
165
+ #
166
+ # verb - An HTTP verb: post, put, or patch.
115
167
  %w[post put patch].each do |method|
116
168
  class_eval <<-RUBY, __FILE__, __LINE__ + 1
117
169
  def #{method}(url = nil, body = nil, headers = nil, &block)
@@ -120,16 +172,60 @@ module Faraday
120
172
  RUBY
121
173
  end
122
174
 
175
+ # Public: Sets up the Authorization header with these credentials, encoded
176
+ # with base64.
177
+ #
178
+ # login - The authentication login.
179
+ # pass - The authentication password.
180
+ #
181
+ # Examples
182
+ #
183
+ # conn.basic_auth 'Aladdin', 'open sesame'
184
+ # conn.headers['Authorization']
185
+ # # => "Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ=="
186
+ #
187
+ # Returns nothing.
123
188
  def basic_auth(login, pass)
124
189
  headers[Faraday::Request::Authorization::KEY] =
125
190
  Faraday::Request::BasicAuthentication.header(login, pass)
126
191
  end
127
192
 
193
+ # Public: Sets up the Authorization header with the given token.
194
+ #
195
+ # token - The String token.
196
+ # options - Optional Hash of extra token options.
197
+ #
198
+ # Examples
199
+ #
200
+ # conn.token_auth 'abcdef', :foo => 'bar'
201
+ # conn.headers['Authorization']
202
+ # # => "Token token=\"abcdef\",
203
+ # foo=\"bar\""
204
+ #
205
+ # Returns nothing.
128
206
  def token_auth(token, options = nil)
129
207
  headers[Faraday::Request::Authorization::KEY] =
130
208
  Faraday::Request::TokenAuthentication.header(token, options)
131
209
  end
132
210
 
211
+ # Public: Sets up a custom Authorization header.
212
+ #
213
+ # type - The String authorization type.
214
+ # token - The String or Hash token. A String value is taken literally, and
215
+ # a Hash is encoded into comma separated key/value pairs.
216
+ #
217
+ # Examples
218
+ #
219
+ # conn.authorization :Bearer, 'mF_9.B5f-4.1JqM'
220
+ # conn.headers['Authorization']
221
+ # # => "Bearer mF_9.B5f-4.1JqM"
222
+ #
223
+ # conn.authorization :Token, :token => 'abcdef', :foo => 'bar'
224
+ # conn.headers['Authorization']
225
+ # # => "Token token=\"abcdef\",
226
+ # foo=\"bar\""
227
+ #
228
+ # Returns nothing.
133
229
  def authorization(type, token)
134
230
  headers[Faraday::Request::Authorization::KEY] =
135
231
  Faraday::Request::Authorization.header(type, token)
@@ -153,10 +249,19 @@ module Faraday
153
249
  end
154
250
  end
155
251
 
252
+ # Public: Determine if this Faraday::Connection can make parallel requests.
253
+ #
254
+ # Returns true or false.
156
255
  def in_parallel?
157
256
  !!@parallel_manager
158
257
  end
159
258
 
259
+ # Public: Sets up the parallel manager to make a set of requests.
260
+ #
261
+ # manager - The parallel manager that this Connection's Adapter uses.
262
+ #
263
+ # Yields a block to execute multiple requests.
264
+ # Returns nothing.
160
265
  def in_parallel(manager = nil)
161
266
  @parallel_manager = manager || default_parallel_manager {
162
267
  warn "Warning: `in_parallel` called but no parallel-capable adapter on Faraday stack"
@@ -169,43 +274,23 @@ module Faraday
169
274
  @parallel_manager = nil
170
275
  end
171
276
 
277
+ # Public: Gets or Sets the Hash proxy options.
172
278
  def proxy(arg = nil)
173
279
  return @proxy if arg.nil?
174
-
175
- @proxy = if arg.is_a? Hash
176
- uri = self.class.URI arg.fetch(:uri) { raise ArgumentError, "missing :uri" }
177
- arg.merge :uri => uri
178
- else
179
- uri = self.class.URI(arg)
180
- {:uri => uri}
181
- end
182
-
183
- with_uri_credentials(uri) do |user, password|
184
- @proxy[:user] ||= user
185
- @proxy[:password] ||= password
186
- end
187
-
188
- @proxy
189
- end
190
-
191
- # normalize URI() behavior across Ruby versions
192
- def self.URI(url)
193
- if url.respond_to?(:host)
194
- url
195
- elsif url.respond_to?(:to_str)
196
- Kernel.URI(url)
197
- else
198
- raise ArgumentError, "bad argument (expected URI object or URI string)"
199
- end
280
+ @proxy = ProxyOptions.from(arg)
200
281
  end
201
282
 
202
283
  def_delegators :url_prefix, :scheme, :scheme=, :host, :host=, :port, :port=
203
284
  def_delegator :url_prefix, :path, :path_prefix
204
285
 
205
- # Parses the giving url with URI and stores the individual
286
+ # Public: Parses the giving url with URI and stores the individual
206
287
  # components in this connection. These components serve as defaults for
207
288
  # requests made by this connection.
208
289
  #
290
+ # url - A String or URI.
291
+ #
292
+ # Examples
293
+ #
209
294
  # conn = Faraday::Connection.new { ... }
210
295
  # conn.url_prefix = "https://sushi.com/api"
211
296
  # conn.scheme # => https
@@ -213,11 +298,12 @@ module Faraday
213
298
  #
214
299
  # conn.get("nigiri?page=2") # accesses https://sushi.com/api/nigiri
215
300
  #
216
- def url_prefix=(url)
217
- uri = @url_prefix = self.class.URI(url)
301
+ # Returns the parsed URI from teh given input..
302
+ def url_prefix=(url, encoder = nil)
303
+ uri = @url_prefix = Utils.URI(url)
218
304
  self.path_prefix = uri.path
219
305
 
220
- params.merge_query(uri.query)
306
+ params.merge_query(uri.query, encoder)
221
307
  uri.query = nil
222
308
 
223
309
  with_uri_credentials(uri) do |user, password|
@@ -228,7 +314,12 @@ module Faraday
228
314
  uri
229
315
  end
230
316
 
231
- # Ensures that the path prefix always has a leading but no trailing slash
317
+ # Public: Sets the path prefix and ensures that it always has a leading
318
+ # but no trailing slash.
319
+ #
320
+ # value - A String.
321
+ #
322
+ # Returns the new String path prefix.
232
323
  def path_prefix=(value)
233
324
  url_prefix.path = if value
234
325
  value = value.chomp '/'
@@ -237,6 +328,14 @@ module Faraday
237
328
  end
238
329
  end
239
330
 
331
+ # Builds and runs the Faraday::Request.
332
+ #
333
+ # method - The Symbol HTTP method.
334
+ # url - The String or URI to access.
335
+ # body - The String body
336
+ # headers - Hash of unencoded HTTP header key/value pairs.
337
+ #
338
+ # Returns a Faraday::Response.
240
339
  def run_request(method, url, body, headers)
241
340
  if !METHODS.include?(method)
242
341
  raise ArgumentError, "unknown http method: #{method}"
@@ -249,11 +348,10 @@ module Faraday
249
348
  yield req if block_given?
250
349
  end
251
350
 
252
- env = request.to_env(self)
253
- self.app.call(env)
351
+ builder.build_response(self, request)
254
352
  end
255
353
 
256
- # Internal: Creates and configures the request object.
354
+ # Creates and configures the request object.
257
355
  #
258
356
  # Returns the new Request.
259
357
  def build_request(method)
@@ -279,9 +377,9 @@ module Faraday
279
377
  def build_url(url, extra_params = nil)
280
378
  uri = build_exclusive_url(url)
281
379
 
282
- query_values = self.params.dup.merge_query(uri.query)
380
+ query_values = self.params.dup.merge_query(uri.query, options.params_encoder)
283
381
  query_values.update extra_params if extra_params
284
- uri.query = query_values.empty? ? nil : query_values.to_query
382
+ uri.query = query_values.empty? ? nil : query_values.to_query(options.params_encoder)
285
383
 
286
384
  uri
287
385
  end
@@ -301,18 +399,16 @@ module Faraday
301
399
  base.path = base.path + '/' # ensure trailing slash
302
400
  end
303
401
  uri = url ? base + url : base
304
- uri.query = params.to_query if params
402
+ uri.query = params.to_query(options.params_encoder) if params
305
403
  uri.query = nil if uri.query and uri.query.empty?
306
404
  uri
307
405
  end
308
406
 
407
+ # Internal: Creates a duplicate of this Faraday::Connection.
408
+ #
409
+ # Returns a Faraday::Connection.
309
410
  def dup
310
- self.class.new(build_url(''),
311
- :headers => headers.dup,
312
- :params => params.dup,
313
- :builder => builder.dup,
314
- :ssl => ssl.dup,
315
- :request => options.dup)
411
+ self.class.new(build_url(''), :headers => headers.dup, :params => params.dup, :builder => builder.dup, :ssl => ssl.dup)
316
412
  end
317
413
 
318
414
  # Internal: Yields username and password extracted from a URI if they both exist.
@@ -323,3 +419,4 @@ module Faraday
323
419
  end
324
420
  end
325
421
  end
422
+