faraday 0.1.0 → 0.1.1
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/VERSION +1 -1
- data/faraday.gemspec +5 -2
- data/lib/faraday.rb +9 -1
- data/lib/faraday/adapter/mock_request.rb +58 -9
- data/lib/faraday/adapter/net_http.rb +24 -4
- data/lib/faraday/adapter/typhoeus.rb +22 -1
- data/lib/faraday/connection.rb +39 -0
- data/lib/faraday/error.rb +1 -0
- data/lib/faraday/loadable.rb +13 -0
- data/lib/faraday/request/post_request.rb +30 -0
- data/lib/faraday/request/yajl_request.rb +27 -0
- data/lib/faraday/response.rb +2 -7
- data/test/adapter_test.rb +55 -6
- data/test/helper.rb +1 -0
- data/test/live_server.rb +30 -1
- metadata +5 -2
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.1.
|
1
|
+
0.1.1
|
data/faraday.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{faraday}
|
8
|
-
s.version = "0.1.
|
8
|
+
s.version = "0.1.1"
|
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-01-
|
12
|
+
s.date = %q{2010-01-05}
|
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 = [
|
@@ -30,6 +30,9 @@ Gem::Specification.new do |s|
|
|
30
30
|
"lib/faraday/adapter/typhoeus.rb",
|
31
31
|
"lib/faraday/connection.rb",
|
32
32
|
"lib/faraday/error.rb",
|
33
|
+
"lib/faraday/loadable.rb",
|
34
|
+
"lib/faraday/request/post_request.rb",
|
35
|
+
"lib/faraday/request/yajl_request.rb",
|
33
36
|
"lib/faraday/response.rb",
|
34
37
|
"lib/faraday/response/yajl_response.rb",
|
35
38
|
"lib/faraday/test_connection.rb",
|
data/lib/faraday.rb
CHANGED
@@ -21,7 +21,15 @@ module Faraday
|
|
21
21
|
:Connection => 'connection',
|
22
22
|
:TestConnection => 'test_connection',
|
23
23
|
:Response => 'response',
|
24
|
-
:Error => 'error'
|
24
|
+
:Error => 'error',
|
25
|
+
:Loadable => 'loadable'
|
26
|
+
|
27
|
+
module Request
|
28
|
+
extend AutoloadHelper
|
29
|
+
autoload_all 'faraday/request',
|
30
|
+
:YajlRequest => 'yajl_request',
|
31
|
+
:PostRequest => 'post_request'
|
32
|
+
end
|
25
33
|
|
26
34
|
module Adapter
|
27
35
|
extend AutoloadHelper
|
@@ -17,27 +17,42 @@ module Faraday
|
|
17
17
|
@stack.empty?
|
18
18
|
end
|
19
19
|
|
20
|
-
def match(request_method, path, request_headers)
|
20
|
+
def match(request_method, path, data, request_headers)
|
21
21
|
return false if !@stack.key?(request_method)
|
22
|
-
@stack[request_method].detect { |stub| stub.matches?(path, request_headers) }
|
22
|
+
stub = @stack[request_method].detect { |stub| stub.matches?(path, data, request_headers) }
|
23
|
+
@stack[request_method].delete(stub) if stub
|
23
24
|
end
|
24
25
|
|
25
26
|
def get(path, request_headers = {}, &block)
|
26
|
-
(@stack[:get] ||= []) << new_stub(path, request_headers, block)
|
27
|
+
(@stack[:get] ||= []) << new_stub(path, {}, request_headers, block)
|
27
28
|
end
|
28
29
|
|
29
|
-
def
|
30
|
+
def delete(path, request_headers = {}, &block)
|
31
|
+
(@stack[:delete] ||= []) << new_stub(path, {}, request_headers, block)
|
32
|
+
end
|
33
|
+
|
34
|
+
def post(path, data, request_headers = {}, &block)
|
35
|
+
(@stack[:post] ||= []) << new_stub(path, data, request_headers, block)
|
36
|
+
end
|
37
|
+
|
38
|
+
def put(path, data, request_headers = {}, &block)
|
39
|
+
(@stack[:put] ||= []) << new_stub(path, data, request_headers, block)
|
40
|
+
end
|
41
|
+
|
42
|
+
def new_stub(path, data, request_headers, block)
|
30
43
|
status, response_headers, body = block.call
|
31
|
-
Stub.new(path, request_headers, status, response_headers, body)
|
44
|
+
Stub.new(path, request_headers, status, response_headers, body, data)
|
32
45
|
end
|
33
46
|
end
|
34
47
|
|
35
|
-
class Stub < Struct.new(:path, :request_headers, :status, :response_headers, :body)
|
36
|
-
def matches?(request_path, headers)
|
48
|
+
class Stub < Struct.new(:path, :request_headers, :status, :response_headers, :body, :data)
|
49
|
+
def matches?(request_path, params, headers)
|
37
50
|
return false if request_path != path
|
51
|
+
return false if params != data
|
52
|
+
return true if request_headers.empty?
|
38
53
|
request_headers.each do |key, value|
|
39
54
|
return false if headers[key] != value
|
40
|
-
end
|
55
|
+
end
|
41
56
|
true
|
42
57
|
end
|
43
58
|
end
|
@@ -57,7 +72,41 @@ module Faraday
|
|
57
72
|
|
58
73
|
def _get(uri, headers)
|
59
74
|
raise ConnectionFailed, "no stubbed requests" if stubs.empty?
|
60
|
-
if stub = @stubs.match(:get, uri.path, headers)
|
75
|
+
if stub = @stubs.match(:get, uri.path, {}, headers)
|
76
|
+
response_class.new do |resp|
|
77
|
+
resp.headers = stub.response_headers
|
78
|
+
resp.process stub.body
|
79
|
+
end
|
80
|
+
else
|
81
|
+
nil
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def _delete(uri, headers)
|
86
|
+
raise ConnectionFailed, "no stubbed requests" if stubs.empty?
|
87
|
+
if stub = @stubs.match(:delete, uri.path, {}, headers)
|
88
|
+
response_class.new do |resp|
|
89
|
+
resp.headers = stub.response_headers
|
90
|
+
resp.process stub.body
|
91
|
+
end
|
92
|
+
else
|
93
|
+
nil
|
94
|
+
end
|
95
|
+
end
|
96
|
+
def _post(uri, data, headers)
|
97
|
+
raise ConnectionFailed, "no stubbed requests" if stubs.empty?
|
98
|
+
if stub = @stubs.match(:post, uri.path, data, headers)
|
99
|
+
response_class.new do |resp|
|
100
|
+
resp.headers = stub.response_headers
|
101
|
+
resp.process stub.body
|
102
|
+
end
|
103
|
+
else
|
104
|
+
nil
|
105
|
+
end
|
106
|
+
end
|
107
|
+
def _put(uri, data, headers)
|
108
|
+
raise ConnectionFailed, "no stubbed requests" if stubs.empty?
|
109
|
+
if stub = @stubs.match(:put, uri.path, data, headers)
|
61
110
|
response_class.new do |resp|
|
62
111
|
resp.headers = stub.response_headers
|
63
112
|
resp.process stub.body
|
@@ -1,15 +1,16 @@
|
|
1
1
|
require 'net/http'
|
2
|
+
require 'cgi'
|
2
3
|
module Faraday
|
3
4
|
module Adapter
|
4
5
|
module NetHttp
|
5
6
|
extend Faraday::Connection::Options
|
6
7
|
|
7
|
-
def
|
8
|
+
def _perform(method, uri, data, request_headers)
|
8
9
|
http = Net::HTTP.new(uri.host, uri.port)
|
9
10
|
response_class.new do |resp|
|
10
|
-
http_resp = http.
|
11
|
-
|
12
|
-
|
11
|
+
http_resp = http.send_request(method, path_for(uri), data, request_headers)
|
12
|
+
raise Faraday::Error::ResourceNotFound if http_resp.code == '404'
|
13
|
+
resp.process http_resp.body
|
13
14
|
http_resp.each_header do |key, value|
|
14
15
|
resp.headers[key] = value
|
15
16
|
end
|
@@ -17,6 +18,25 @@ module Faraday
|
|
17
18
|
rescue Errno::ECONNREFUSED
|
18
19
|
raise Faraday::Error::ConnectionFailed, "connection refused"
|
19
20
|
end
|
21
|
+
|
22
|
+
def _put(uri, data, request_headers)
|
23
|
+
request = request_class.new(data, request_headers)
|
24
|
+
_perform('PUT', uri, request.body, request.headers)
|
25
|
+
end
|
26
|
+
|
27
|
+
def _post(uri, data, request_headers)
|
28
|
+
request = request_class.new(data, request_headers)
|
29
|
+
_perform('POST', uri, request.body, request.headers)
|
30
|
+
end
|
31
|
+
|
32
|
+
def _get(uri, request_headers)
|
33
|
+
_perform('GET', uri, uri.query, request_headers)
|
34
|
+
end
|
35
|
+
|
36
|
+
def _delete(uri, request_headers)
|
37
|
+
_perform('DELETE', uri, uri.query, request_headers)
|
38
|
+
end
|
39
|
+
|
20
40
|
end
|
21
41
|
end
|
22
42
|
end
|
@@ -25,12 +25,32 @@ module Faraday
|
|
25
25
|
@parallel_manager = nil
|
26
26
|
end
|
27
27
|
|
28
|
+
def _post(uri, data, request_headers)
|
29
|
+
request = request_class.new(data, request_headers)
|
30
|
+
_perform(:post, uri, :headers => request.headers, :body => request.body)
|
31
|
+
end
|
32
|
+
|
28
33
|
def _get(uri, request_headers)
|
34
|
+
_perform(:get, uri, :headers => request_headers)
|
35
|
+
end
|
36
|
+
|
37
|
+
def _put(uri, data, request_headers)
|
38
|
+
request = request_class.new(data, request_headers)
|
39
|
+
_perform(:put, uri, :headers => request.headers, :body => request.body)
|
40
|
+
end
|
41
|
+
|
42
|
+
def _delete(uri, request_headers)
|
43
|
+
_perform(:delete, uri, :headers => request_headers)
|
44
|
+
end
|
45
|
+
|
46
|
+
def _perform method, uri, params
|
29
47
|
response_class.new do |resp|
|
30
48
|
is_async = in_parallel?
|
31
49
|
setup_parallel_manager
|
32
|
-
|
50
|
+
params[:method] = method
|
51
|
+
req = ::Typhoeus::Request.new(uri.to_s, params)
|
33
52
|
req.on_complete do |response|
|
53
|
+
raise Faraday::Error::ResourceNotFound if response.code == 404
|
34
54
|
resp.process!(response.body)
|
35
55
|
resp.headers = parse_response_headers(response.headers)
|
36
56
|
end
|
@@ -42,6 +62,7 @@ module Faraday
|
|
42
62
|
end
|
43
63
|
|
44
64
|
def parse_response_headers(header_string)
|
65
|
+
return {} unless header_string # XXX
|
45
66
|
Hash[*header_string.split(/\r\n/).
|
46
67
|
tap { |a| a.shift }. # drop the HTTP status line
|
47
68
|
map! { |h| h.split(/:\s+/,2) }. # split key and value
|
data/lib/faraday/connection.rb
CHANGED
@@ -38,6 +38,34 @@ module Faraday
|
|
38
38
|
self.path_prefix = uri.path
|
39
39
|
end
|
40
40
|
|
41
|
+
|
42
|
+
# Override in a subclass, or include an adapter
|
43
|
+
#
|
44
|
+
# def _post(uri, post_params, headers)
|
45
|
+
# end
|
46
|
+
#
|
47
|
+
def post(uri, params = {}, headers = {})
|
48
|
+
_post build_uri(uri), build_params(params), build_headers(headers)
|
49
|
+
end
|
50
|
+
|
51
|
+
# Override in a subclass, or include an adapter
|
52
|
+
#
|
53
|
+
# def _put(uri, post_params, headers)
|
54
|
+
# end
|
55
|
+
#
|
56
|
+
def put(uri, params = {}, headers = {})
|
57
|
+
_put build_uri(uri), build_params(params), build_headers(headers)
|
58
|
+
end
|
59
|
+
|
60
|
+
# Override in a subclass, or include an adapter
|
61
|
+
#
|
62
|
+
# def _delete(uri, headers)
|
63
|
+
# end
|
64
|
+
#
|
65
|
+
def delete(uri, params = {}, headers = {})
|
66
|
+
_delete build_uri(uri, build_params(params)), build_headers(headers)
|
67
|
+
end
|
68
|
+
|
41
69
|
# Override in a subclass, or include an adapter
|
42
70
|
#
|
43
71
|
# def _get(uri, headers)
|
@@ -48,6 +76,10 @@ module Faraday
|
|
48
76
|
_get(uri, build_headers(headers))
|
49
77
|
end
|
50
78
|
|
79
|
+
def request_class
|
80
|
+
@request_class || Request::PostRequest
|
81
|
+
end
|
82
|
+
|
51
83
|
def response_class
|
52
84
|
@response_class || Response
|
53
85
|
end
|
@@ -59,6 +91,13 @@ module Faraday
|
|
59
91
|
@response_class = v
|
60
92
|
end
|
61
93
|
|
94
|
+
def request_class=(v)
|
95
|
+
if v.respond_to?(:loaded?) && !v.loaded?
|
96
|
+
raise ArgumentError, "The request class: #{v.inspect} does not appear to be loaded."
|
97
|
+
end
|
98
|
+
@request_class = v
|
99
|
+
end
|
100
|
+
|
62
101
|
def in_parallel?
|
63
102
|
!!@parallel_manager
|
64
103
|
end
|
data/lib/faraday/error.rb
CHANGED
@@ -0,0 +1,30 @@
|
|
1
|
+
module Faraday
|
2
|
+
module Request
|
3
|
+
class PostRequest
|
4
|
+
extend Loadable
|
5
|
+
|
6
|
+
def initialize params, headers={}
|
7
|
+
@params = params
|
8
|
+
@headers = headers
|
9
|
+
end
|
10
|
+
|
11
|
+
def headers
|
12
|
+
@headers.merge('Content-Type' => 'application/x-www-form-urlencoded')
|
13
|
+
end
|
14
|
+
|
15
|
+
def body
|
16
|
+
create_post_params @params
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
def create_post_params(params, base = "")
|
21
|
+
[].tap do |toreturn|
|
22
|
+
params.each_key do |key|
|
23
|
+
keystring = base == '' ? key : "#{base}[#{key}]"
|
24
|
+
toreturn << (params[key].kind_of?(Hash) ? create_post_params(params[key], keystring) : "#{keystring}=#{CGI.escape(params[key].to_s)}")
|
25
|
+
end
|
26
|
+
end.join('&')
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Faraday
|
2
|
+
module Request
|
3
|
+
class YajlRequest
|
4
|
+
extend Loadable
|
5
|
+
|
6
|
+
begin
|
7
|
+
require 'yajl'
|
8
|
+
|
9
|
+
def initialize params, headers={}
|
10
|
+
@params = params
|
11
|
+
@headers = headers
|
12
|
+
end
|
13
|
+
|
14
|
+
def headers
|
15
|
+
@headers.merge('Content-Type' => 'application/json')
|
16
|
+
end
|
17
|
+
|
18
|
+
# TODO streaming
|
19
|
+
def body
|
20
|
+
Yajl::Encoder.encode @params
|
21
|
+
end
|
22
|
+
rescue LoadError => e
|
23
|
+
self.load_error = e
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
data/lib/faraday/response.rb
CHANGED
@@ -1,11 +1,6 @@
|
|
1
1
|
module Faraday
|
2
2
|
class Response < Struct.new(:headers, :body)
|
3
|
-
|
4
|
-
attr_accessor :load_error
|
5
|
-
def loaded?
|
6
|
-
!load_error
|
7
|
-
end
|
8
|
-
end
|
3
|
+
extend Loadable
|
9
4
|
|
10
5
|
extend AutoloadHelper
|
11
6
|
autoload_all 'faraday/response',
|
@@ -40,4 +35,4 @@ module Faraday
|
|
40
35
|
self.body = body.join if body.respond_to?(:join)
|
41
36
|
end
|
42
37
|
end
|
43
|
-
end
|
38
|
+
end
|
data/test/adapter_test.rb
CHANGED
@@ -6,11 +6,23 @@ class AdapterTest < Faraday::TestCase
|
|
6
6
|
end
|
7
7
|
|
8
8
|
Faraday::Adapter.loaded_adapters.each do |adapter|
|
9
|
-
describe "
|
9
|
+
describe "with #{adapter} adapter" do
|
10
10
|
before do
|
11
11
|
@connection.extend adapter
|
12
12
|
end
|
13
13
|
|
14
|
+
describe "#delete" do
|
15
|
+
it "retrieves the response body with YajlResponse" do
|
16
|
+
@connection.response_class = Faraday::Response::YajlResponse
|
17
|
+
assert_equal({'deleted' => true},
|
18
|
+
@connection.delete('delete_with_json').body)
|
19
|
+
end
|
20
|
+
|
21
|
+
it "send url-encoded params" do
|
22
|
+
assert_equal('foobar', @connection.delete('delete_with_params', 'deleted' => 'foobar').body)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
14
26
|
it "passes params" do
|
15
27
|
@connection.params = {:a => 1}
|
16
28
|
assert_equal "params[:a] == 1", @connection.get('params').body
|
@@ -25,13 +37,50 @@ class AdapterTest < Faraday::TestCase
|
|
25
37
|
assert_equal 'hello world', @connection.get('hello_world').body
|
26
38
|
end
|
27
39
|
|
28
|
-
|
29
|
-
|
30
|
-
|
40
|
+
describe "#put" do
|
41
|
+
it "sends params" do
|
42
|
+
assert_equal 'hello zack', @connection.put('hello', 'name' => 'zack').body
|
43
|
+
end
|
44
|
+
|
45
|
+
it "retrieves the response body with YajlResponse" do
|
46
|
+
@connection.response_class = Faraday::Response::YajlResponse
|
47
|
+
assert_equal({'name' => 'zack'},
|
48
|
+
@connection.put('echo_name', 'name' => 'zack').body)
|
49
|
+
end
|
31
50
|
end
|
32
51
|
|
33
|
-
|
34
|
-
|
52
|
+
describe "#post" do
|
53
|
+
it "sends params" do
|
54
|
+
assert_equal 'hello zack', @connection.post('hello', 'name' => 'zack').body
|
55
|
+
end
|
56
|
+
|
57
|
+
it "retrieves the response body with YajlResponse" do
|
58
|
+
@connection.response_class = Faraday::Response::YajlResponse
|
59
|
+
assert_equal({'name' => 'zack'},
|
60
|
+
@connection.post('echo_name', 'name' => 'zack').body)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
describe "#get" do
|
65
|
+
it "raises on 404" do
|
66
|
+
assert_raise(Faraday::Error::ResourceNotFound) { @connection.get('/nothing') }
|
67
|
+
end
|
68
|
+
it "retrieves the response body" do
|
69
|
+
assert_equal 'hello world', @connection.get('hello_world').body
|
70
|
+
end
|
71
|
+
|
72
|
+
it "send url-encoded params" do
|
73
|
+
assert_equal('hello zack', @connection.get('hello', 'name' => 'zack').body)
|
74
|
+
end
|
75
|
+
|
76
|
+
it "retrieves the response body with YajlResponse" do
|
77
|
+
@connection.response_class = Faraday::Response::YajlResponse
|
78
|
+
assert_equal [1,2,3], @connection.get('json').body
|
79
|
+
end
|
80
|
+
|
81
|
+
it "retrieves the response headers" do
|
82
|
+
assert_equal 'text/html', @connection.get('hello_world').headers['content-type']
|
83
|
+
end
|
35
84
|
end
|
36
85
|
end
|
37
86
|
|
data/test/helper.rb
CHANGED
data/test/live_server.rb
CHANGED
@@ -9,10 +9,39 @@ get '/json' do
|
|
9
9
|
"[1,2,3]"
|
10
10
|
end
|
11
11
|
|
12
|
+
post '/hello' do
|
13
|
+
"hello #{params[:name]}"
|
14
|
+
end
|
15
|
+
|
16
|
+
get '/hello' do
|
17
|
+
"hello #{params[:name]}"
|
18
|
+
end
|
19
|
+
|
20
|
+
put '/hello' do
|
21
|
+
"hello #{params[:name]}"
|
22
|
+
end
|
23
|
+
|
24
|
+
post '/echo_name' do
|
25
|
+
%/{"name":#{params[:name].inspect}}/
|
26
|
+
end
|
27
|
+
|
28
|
+
put '/echo_name' do
|
29
|
+
%/{"name":#{params[:name].inspect}}/
|
30
|
+
end
|
31
|
+
|
32
|
+
delete '/delete_with_json' do
|
33
|
+
%/{"deleted":true}/
|
34
|
+
end
|
35
|
+
|
36
|
+
delete '/delete_with_params' do
|
37
|
+
params[:deleted]
|
38
|
+
end
|
39
|
+
|
12
40
|
get '/params' do
|
13
41
|
%(params[:a] == #{params[:a]})
|
14
42
|
end
|
15
43
|
|
16
44
|
get "/headers" do
|
17
45
|
%(env[HTTP_X_TEST] == #{env["HTTP_X_TEST"]})
|
18
|
-
end
|
46
|
+
end
|
47
|
+
|
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.1.
|
4
|
+
version: 0.1.1
|
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-01-
|
12
|
+
date: 2010-01-05 00:00:00 -08:00
|
13
13
|
default_executable:
|
14
14
|
dependencies: []
|
15
15
|
|
@@ -36,6 +36,9 @@ files:
|
|
36
36
|
- lib/faraday/adapter/typhoeus.rb
|
37
37
|
- lib/faraday/connection.rb
|
38
38
|
- lib/faraday/error.rb
|
39
|
+
- lib/faraday/loadable.rb
|
40
|
+
- lib/faraday/request/post_request.rb
|
41
|
+
- lib/faraday/request/yajl_request.rb
|
39
42
|
- lib/faraday/response.rb
|
40
43
|
- lib/faraday/response/yajl_response.rb
|
41
44
|
- lib/faraday/test_connection.rb
|