faraday 0.3.1 → 0.4.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.
@@ -26,6 +26,9 @@ This mess is gonna get raw, like sushi. So, haters to the left.
26
26
  req.body = {:name => 'Unagi'}
27
27
  end
28
28
 
29
+ # If you're ready to roll with just the bare minimum (net/http):
30
+ resp1 = Faraday.get 'http://sushi.com/nigiri/sake.json'
31
+
29
32
  == Testing
30
33
 
31
34
  # It's possible to define stubbed request outside a test adapter block.
@@ -63,7 +66,7 @@ This mess is gonna get raw, like sushi. So, haters to the left.
63
66
 
64
67
  * Add curb/em-http support
65
68
  * Add xml parsing
66
- * Support timeouts, proxy servers, ssl options
69
+ * Support timeouts, proxy servers, ssl options on Typhoeus/Patron
67
70
  * Add streaming requests and responses
68
71
  * Add default middleware load out for common cases
69
72
  * Add symbol => string index for mime types (:json => 'application/json')
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.3.1
1
+ 0.4.0
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{faraday}
8
- s.version = "0.3.1"
8
+ s.version = "0.4.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["rick"]
12
- s.date = %q{2010-04-22}
12
+ s.date = %q{2010-04-27}
13
13
  s.description = %q{HTTP/REST API client library with pluggable components}
14
14
  s.email = %q{technoweenie@gmail.com}
15
15
  s.extra_rdoc_files = [
@@ -1,6 +1,62 @@
1
1
  require 'rack/utils'
2
2
 
3
3
  module Faraday
4
+ class << self
5
+ attr_accessor :default_adapter
6
+ attr_writer :default_connection
7
+ end
8
+
9
+ self.default_adapter = :net_http
10
+
11
+ def self.default_connection
12
+ @default_connection ||= Connection.new
13
+ end
14
+
15
+ # use the method signature from Faraday::Connection
16
+ def self.build(options = {}, &block)
17
+ default_connection.build(options, &block)
18
+ end
19
+
20
+ def self.get(url = nil, headers = nil, &block)
21
+ default_connection.get(url, headers, &block)
22
+ end
23
+
24
+ def self.post(url = nil, body = nil, headers = nil, &block)
25
+ default_connection.post(url, body, headers, &block)
26
+ end
27
+
28
+ def self.put(url = nil, body = nil, headers = nil, &block)
29
+ default_connection.put(url, body, headers, &block)
30
+ end
31
+
32
+ def self.head(url = nil, headers = nil, &block)
33
+ default_connection.head(url, headers, &block)
34
+ end
35
+
36
+ def self.delete(url = nil, headers = nil, &block)
37
+ default_connection.delete(url, headers, &block)
38
+ end
39
+
40
+ def self.in_parallel?
41
+ default_connection.in_parallel?
42
+ end
43
+
44
+ def self.in_parallel(manager)
45
+ default_connection.in_parallel(manager)
46
+ end
47
+
48
+ def self.proxy(arg = nil)
49
+ default_connection.proxy(arg)
50
+ end
51
+
52
+ def self.url_prefix=(url)
53
+ default_connection.url_prefix = url
54
+ end
55
+
56
+ def self.path_prefix=(value)
57
+ default_connection.path_prefix = value
58
+ end
59
+
4
60
  module AutoloadHelper
5
61
  def register_lookup_modules(mods)
6
62
  (@lookup_module_index ||= {}).update(mods)
@@ -1,11 +1,34 @@
1
- require 'net/http'
1
+ begin
2
+ require 'net/https'
3
+ rescue LoadError
4
+ puts "no such file to load -- net/https. Make sure openssl is installed if you want ssl support"
5
+ require 'net/http'
6
+ end
7
+
2
8
  module Faraday
3
9
  module Adapter
4
10
  class NetHttp < Middleware
5
11
  def call(env)
6
12
  process_body_for_request(env)
7
13
 
8
- http = Net::HTTP.new(env[:url].host, env[:url].port)
14
+ is_ssl = env[:url].scheme == 'https'
15
+
16
+ http = net_http_class(env).new(env[:url].host, env[:url].port || (is_ssl ? 443 : 80))
17
+ if http.use_ssl = is_ssl
18
+ ssl = env[:ssl]
19
+ if ssl[:verify] == false
20
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE
21
+ else
22
+ http.verify_mode = ssl[:verify]
23
+ end
24
+ http.cert = ssl[:client_cert] if ssl[:client_cert]
25
+ http.key = ssl[:client_key] if ssl[:client_key]
26
+ http.ca_file = ssl[:ca_file] if ssl[:ca_file]
27
+ end
28
+ req = env[:request]
29
+ http.read_timeout = net.open_timeout = req[:timeout] if req[:timeout]
30
+ http.open_timeout = req[:open_timeout] if req[:open_timeout]
31
+
9
32
  full_path = full_path_for(env[:url].path, env[:url].query, env[:url].fragment)
10
33
  http_resp = http.send_request(env[:method].to_s.upcase, full_path, env[:body], env[:request_headers])
11
34
 
@@ -23,6 +46,14 @@ module Faraday
23
46
  rescue Errno::ECONNREFUSED
24
47
  raise Error::ConnectionFailed, "connection refused"
25
48
  end
49
+
50
+ def net_http_class(env)
51
+ if proxy = env[:request][:proxy]
52
+ Net::HTTP::Proxy(proxy[:uri].host, proxy[:uri].port, proxy[:user], proxy[:password])
53
+ else
54
+ Net::HTTP
55
+ end
56
+ end
26
57
  end
27
58
  end
28
59
  end
@@ -20,7 +20,8 @@ module Faraday
20
20
  req = ::Typhoeus::Request.new env[:url].to_s,
21
21
  :method => env[:method],
22
22
  :body => env[:body],
23
- :headers => env[:request_headers]
23
+ :headers => env[:request_headers],
24
+ :disable_ssl_peer_verification => (env[:ssl][:verify] == false)
24
25
 
25
26
  req.on_complete do |resp|
26
27
  env.update \
@@ -24,9 +24,13 @@ module Faraday
24
24
  build(&block) if block_given?
25
25
  end
26
26
 
27
- def build(&block)
27
+ def build(options = {}, &block)
28
+ inner = @handlers.shift
29
+ if !options[:keep]
30
+ @handlers.clear
31
+ end
28
32
  block.call(self)
29
- run(self.class.inner_app)
33
+ run(inner || self.class.inner_app)
30
34
  end
31
35
 
32
36
  def [](index)
@@ -39,6 +43,10 @@ module Faraday
39
43
  end
40
44
 
41
45
  def to_app
46
+ if @handlers.empty?
47
+ build { |b| b.adapter Faraday.default_adapter }
48
+ end
49
+
42
50
  inner_app = @handlers.first
43
51
  @handlers[1..-1].inject(inner_app) { |app, middleware| middleware.call(app) }
44
52
  end
@@ -16,11 +16,13 @@ module Faraday
16
16
  METHODS_WITH_BODIES = Set.new [:post, :put]
17
17
 
18
18
  attr_accessor :host, :port, :scheme, :params, :headers, :parallel_manager
19
- attr_reader :path_prefix, :builder
19
+ attr_reader :path_prefix, :builder, :options, :ssl
20
20
 
21
21
  # :url
22
22
  # :params
23
23
  # :headers
24
+ # :request
25
+ # :ssl
24
26
  def initialize(url = nil, options = {}, &block)
25
27
  if url.is_a?(Hash)
26
28
  options = url
@@ -28,8 +30,11 @@ module Faraday
28
30
  end
29
31
  @headers = HeaderHash.new
30
32
  @params = {}
33
+ @options = options[:request] || {}
34
+ @ssl = options[:ssl] || {}
31
35
  @parallel_manager = options[:parallel]
32
36
  self.url_prefix = url if url
37
+ proxy(options[:proxy])
33
38
  merge_params @params, options[:params] if options[:params]
34
39
  merge_headers @headers, options[:headers] if options[:headers]
35
40
  if block
@@ -39,8 +44,8 @@ module Faraday
39
44
  end
40
45
  end
41
46
 
42
- def build(&block)
43
- @builder.build(&block)
47
+ def build(options = {}, &block)
48
+ @builder.build(options, &block)
44
49
  end
45
50
 
46
51
  def get(url = nil, headers = nil, &block)
@@ -63,19 +68,6 @@ module Faraday
63
68
  run_request :delete, url, nil, headers, &block
64
69
  end
65
70
 
66
- def run_request(method, url, body, headers)
67
- if !METHODS.include?(method)
68
- raise ArgumentError, "unknown http method: #{method}"
69
- end
70
-
71
- Request.run(self, method) do |req|
72
- req.url(url) if url
73
- req.headers.update(headers) if headers
74
- req.body = body if body
75
- yield req if block_given?
76
- end
77
- end
78
-
79
71
  def in_parallel?
80
72
  !!@parallel_manager
81
73
  end
@@ -88,9 +80,20 @@ module Faraday
88
80
  @parallel_manager = nil
89
81
  end
90
82
 
91
- # return the assembled Rack application for this instance.
92
- def to_app
93
- @builder.to_app
83
+ def proxy(arg = nil)
84
+ return @proxy if arg.nil?
85
+
86
+ @proxy =
87
+ case arg
88
+ when String then {:uri => proxy_arg_to_uri(arg)}
89
+ when URI then {:uri => arg}
90
+ when Hash then arg
91
+ if arg[:uri] = proxy_arg_to_uri(arg[:uri])
92
+ arg
93
+ else
94
+ raise ArgumentError, "no :uri option."
95
+ end
96
+ end
94
97
  end
95
98
 
96
99
  # Parses the giving url with Addressable::URI and stores the individual
@@ -124,6 +127,24 @@ module Faraday
124
127
  @path_prefix = value
125
128
  end
126
129
 
130
+ # return the assembled Rack application for this instance.
131
+ def to_app
132
+ @builder.to_app
133
+ end
134
+
135
+ def run_request(method, url, body, headers)
136
+ if !METHODS.include?(method)
137
+ raise ArgumentError, "unknown http method: #{method}"
138
+ end
139
+
140
+ Request.run(self, method) do |req|
141
+ req.url(url) if url
142
+ req.headers.update(headers) if headers
143
+ req.body = body if body
144
+ yield req if block_given?
145
+ end
146
+ end
147
+
127
148
  # Takes a relative url for a request and combines it with the defaults
128
149
  # set on the connection instance.
129
150
  #
@@ -137,9 +158,9 @@ module Faraday
137
158
  #
138
159
  def build_url(url, params = nil)
139
160
  uri = URI.parse(url.to_s)
140
- uri.scheme ||= @scheme
141
161
  uri.host ||= @host
142
162
  uri.port ||= @port
163
+ uri.scheme ||= @scheme
143
164
  if @path_prefix && uri.path !~ /^\//
144
165
  uri.path = "#{@path_prefix.size > 1 ? @path_prefix : nil}/#{uri.path}"
145
166
  end
@@ -189,5 +210,12 @@ module Faraday
189
210
  '%' << $1.unpack('H2'*bytesize($1)).join('%').tap { |c| c.upcase! }
190
211
  end
191
212
  end
213
+
214
+ def proxy_arg_to_uri(arg)
215
+ case arg
216
+ when String then URI.parse(arg)
217
+ when URI then arg
218
+ end
219
+ end
192
220
  end
193
221
  end
@@ -54,6 +54,14 @@ module Faraday
54
54
  # :response_headers - Hash of HTTP headers from the server
55
55
  # :parallel_manager - sent if the connection is in parallel mode
56
56
  # :response - the actual response object that stores the rack response
57
+ # :request - Hash of options for configuring the request.
58
+ # :timeout - open/read timeout Integer in seconds
59
+ # :open_timeout - read timeout Integer in seconds
60
+ # :proxy - Hash of proxy options
61
+ # :uri - Proxy Server URI
62
+ # :user - Proxy server username
63
+ # :password - Proxy server password
64
+ # :ssl - Hash of options for configuring SSL requests.
57
65
  def to_env_hash(connection, request_method)
58
66
  env_headers = connection.headers.dup
59
67
  env_params = connection.params.dup
@@ -65,7 +73,9 @@ module Faraday
65
73
  :url => connection.build_url(path, env_params),
66
74
  :request_headers => env_headers.update(headers),
67
75
  :parallel_manager => connection.parallel_manager,
68
- :response => Response.new}
76
+ :response => Response.new,
77
+ :request => connection.options.merge(:proxy => connection.proxy),
78
+ :ssl => connection.ssl}
69
79
  end
70
80
 
71
81
  def run(connection, request_method)
@@ -3,7 +3,7 @@ require File.expand_path(File.join(File.dirname(__FILE__), '..', 'helper'))
3
3
  if Faraday::TestCase::LIVE_SERVER
4
4
  module Adapters
5
5
  class LiveTest < Faraday::TestCase
6
- Faraday::Adapter.all_loaded_constants.each do |adapter|
6
+ (Faraday::Adapter.all_loaded_constants + [:default]).each do |adapter|
7
7
  define_method "test_#{adapter}_GET_retrieves_the_response_body" do
8
8
  assert_equal 'hello world', create_connection(adapter).get('hello_world').body
9
9
  end
@@ -100,6 +100,7 @@ if Faraday::TestCase::LIVE_SERVER
100
100
  resp1, resp2 = nil, nil
101
101
 
102
102
  connection = create_connection(adapter)
103
+ adapter = real_adapter_for(adapter)
103
104
 
104
105
  connection.in_parallel(adapter.setup_parallel_manager) do
105
106
  resp1 = connection.get('json')
@@ -117,8 +118,22 @@ if Faraday::TestCase::LIVE_SERVER
117
118
  end
118
119
 
119
120
  def create_connection(adapter)
120
- Faraday::Connection.new LIVE_SERVER do |b|
121
- b.use adapter
121
+ if adapter == :default
122
+ conn = Faraday.default_connection
123
+ conn.url_prefix = LIVE_SERVER
124
+ conn
125
+ else
126
+ Faraday::Connection.new LIVE_SERVER do |b|
127
+ b.use adapter
128
+ end
129
+ end
130
+ end
131
+
132
+ def real_adapter_for(adapter)
133
+ if adapter == :default
134
+ Faraday::Adapter.lookup_module(Faraday.default_adapter)
135
+ else
136
+ adapter
122
137
  end
123
138
  end
124
139
  end
@@ -139,16 +139,61 @@ class TestConnection < Faraday::TestCase
139
139
  assert_no_match /token=abc/, url.query
140
140
  end
141
141
 
142
- def test_build_url_parses_url_into_host
142
+ def test_build_url_parses_url
143
143
  conn = Faraday::Connection.new
144
144
  uri = conn.build_url("http://sushi.com/sake.html")
145
- assert_equal "sushi.com", uri.host
145
+ assert_equal "http", uri.scheme
146
+ assert_equal "sushi.com", uri.host
147
+ assert_equal '/sake.html', uri.path
148
+ assert_nil uri.port
149
+ end
150
+
151
+ def test_build_url_parses_url_and_changes_scheme
152
+ conn = Faraday::Connection.new :url => "http://sushi.com/sushi"
153
+ conn.scheme = 'https'
154
+ uri = conn.build_url("sake.html")
155
+ assert_equal 'https://sushi.com/sushi/sake.html', uri.to_s
146
156
  end
147
157
 
148
- def test_build_url_parses_url_into_port
158
+ def test_proxy_accepts_string
149
159
  conn = Faraday::Connection.new
150
- uri = conn.build_url("http://sushi.com/sake.html")
151
- assert_nil uri.port
160
+ conn.proxy 'http://proxy.com'
161
+ assert_equal 'proxy.com', conn.proxy.host
162
+ end
163
+
164
+ def test_proxy_accepts_string
165
+ conn = Faraday::Connection.new
166
+ conn.proxy 'http://proxy.com'
167
+ assert_equal 'proxy.com', conn.proxy[:uri].host
168
+ assert_equal [:uri], conn.proxy.keys
169
+ end
170
+
171
+ def test_proxy_accepts_uri
172
+ conn = Faraday::Connection.new
173
+ conn.proxy Addressable::URI.parse('http://proxy.com')
174
+ assert_equal 'proxy.com', conn.proxy[:uri].host
175
+ assert_equal [:uri], conn.proxy.keys
176
+ end
177
+
178
+ def test_proxy_accepts_hash_with_string_uri
179
+ conn = Faraday::Connection.new
180
+ conn.proxy :uri => 'http://proxy.com', :user => 'rick'
181
+ assert_equal 'proxy.com', conn.proxy[:uri].host
182
+ assert_equal 'rick', conn.proxy[:user]
183
+ end
184
+
185
+ def test_proxy_accepts_hash
186
+ conn = Faraday::Connection.new
187
+ conn.proxy :uri => Addressable::URI.parse('http://proxy.com'), :user => 'rick'
188
+ assert_equal 'proxy.com', conn.proxy[:uri].host
189
+ assert_equal 'rick', conn.proxy[:user]
190
+ end
191
+
192
+ def test_proxy_requires_uri
193
+ conn = Faraday::Connection.new
194
+ assert_raises ArgumentError do
195
+ conn.proxy :uri => :bad_uri, :user => 'rick'
196
+ end
152
197
  end
153
198
 
154
199
  def test_params_to_query_converts_hash_of_params_to_uri_escaped_query_string
@@ -173,4 +218,43 @@ class TestConnection < Faraday::TestCase
173
218
  assert_not_equal conn.send(attr).object_id, duped.send(attr).object_id
174
219
  end
175
220
  end
176
- end
221
+
222
+ def test_allows_rebuilding_of_connection_handlers
223
+ conn = Faraday::Connection.new
224
+ conn.to_app
225
+ inner = conn.builder.handlers[0]
226
+ mware = conn.builder.handlers[1].call({})
227
+ assert_kind_of Faraday::Adapter::NetHttp, mware
228
+
229
+ conn.build do |b|
230
+ b.adapter :test
231
+ end
232
+ mware = conn.builder.handlers[1].call({})
233
+ assert_kind_of Faraday::Adapter::Test, mware
234
+ assert_equal inner, conn.builder.handlers[0]
235
+ end
236
+
237
+ def test_allows_extending_of_existing_connection_handlers
238
+ conn = Faraday::Connection.new
239
+ conn.to_app
240
+ mware = conn.builder.handlers[1].call({})
241
+ assert_kind_of Faraday::Adapter::NetHttp, mware
242
+ assert_equal 2, conn.builder.handlers.size
243
+
244
+ conn.build :keep => true do |b|
245
+ b.adapter :test
246
+ end
247
+ mware = conn.builder.handlers[1].call({})
248
+ assert_kind_of Faraday::Adapter::Test, mware
249
+ assert_equal 3, conn.builder.handlers.size
250
+ end
251
+
252
+ def test_sets_default_adapter_if_none_set
253
+ conn = Faraday::Connection.new
254
+ assert_equal 0, conn.builder.handlers.size
255
+
256
+ app = conn.to_app
257
+ mware = conn.builder.handlers[1].call({})
258
+ assert_kind_of Faraday::Adapter::NetHttp, mware
259
+ end
260
+ end
@@ -3,15 +3,18 @@ require File.expand_path(File.join(File.dirname(__FILE__), 'helper'))
3
3
  class TestEnv < Faraday::TestCase
4
4
  def setup
5
5
  @conn = Faraday::Connection.new :url => 'http://sushi.com/api', :headers => {'Mime-Version' => '1.0'}
6
+ @conn.options[:timeout] = 3
7
+ @conn.options[:open_timeout] = 5
8
+ @conn.ssl[:verify] = false
9
+ @conn.proxy 'http://proxy.com'
6
10
  @input = {
7
11
  :body => 'abc',
8
12
  :headers => {'Server' => 'Faraday'}}
9
- @env_setup = Faraday::Request.create do |req|
13
+ @env = env_for @conn do |req|
10
14
  req.url 'foo.json', 'a' => 1
11
15
  req['Server'] = 'Faraday'
12
16
  req.body = @input[:body]
13
17
  end
14
- @env = @env_setup.to_env_hash(@conn, :get)
15
18
  end
16
19
 
17
20
  def test_request_create_stores_method
@@ -30,4 +33,24 @@ class TestEnv < Faraday::TestCase
30
33
  def test_request_create_stores_body
31
34
  assert_equal @input[:body], @env[:body]
32
35
  end
36
+
37
+ def test_request_create_stores_ssl_options
38
+ assert_equal 3, @env[:request][:timeout]
39
+ assert_equal 5, @env[:request][:open_timeout]
40
+ end
41
+
42
+ def test_request_create_stores_ssl_options
43
+ assert_equal false, @env[:ssl][:verify]
44
+ end
45
+
46
+ def test_request_create_stores_proxy_options
47
+ assert_equal 'proxy.com', @env[:request][:proxy][:uri].host
48
+ end
49
+
50
+ def env_for(connection)
51
+ env_setup = Faraday::Request.create do |req|
52
+ yield req
53
+ end
54
+ env_setup.to_env_hash(connection, :get)
55
+ end
33
56
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: faraday
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.1
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - rick
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2010-04-22 00:00:00 -04:00
12
+ date: 2010-04-27 00:00:00 -04:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency