faraday 0.1.0 → 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|