httpi 0.1.0 → 0.2.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.
- data/Gemfile +1 -1
- data/Gemfile.lock +28 -0
- data/README.rdoc +68 -39
- data/Rakefile +28 -2
- data/lib/httpi/adapter.rb +1 -1
- data/lib/httpi/adapter/curb.rb +26 -34
- data/lib/httpi/adapter/httpclient.rb +23 -25
- data/lib/httpi/client.rb +63 -5
- data/lib/httpi/request.rb +73 -0
- data/lib/httpi/version.rb +1 -1
- data/spec/fixtures/xml.gz +0 -0
- data/spec/fixtures/xml.xml +10 -0
- data/spec/httpi/adapter/curb_spec.rb +29 -69
- data/spec/httpi/adapter/httpclient_spec.rb +25 -66
- data/spec/httpi/adapter_spec.rb +11 -12
- data/spec/httpi/client_spec.rb +89 -8
- data/spec/httpi/request_spec.rb +104 -0
- data/spec/httpi/response_spec.rb +6 -8
- data/spec/spec_helper.rb +1 -1
- data/spec/support/fixture.rb +19 -0
- data/spec/support/matchers.rb +2 -2
- metadata +13 -12
- data/lib/httpi/adapter/base.rb +0 -16
- data/lib/httpi/interface.rb +0 -21
- data/spec/fixtures/gzip.gz +0 -0
- data/spec/httpi/interface_spec.rb +0 -33
- data/spec/support/helper_methods.rb +0 -41
@@ -0,0 +1,73 @@
|
|
1
|
+
require "uri"
|
2
|
+
|
3
|
+
module HTTPI
|
4
|
+
class Request
|
5
|
+
|
6
|
+
# Request accessor methods.
|
7
|
+
ACCESSORS = [:url, :proxy, :headers, :body, :open_timeout, :read_timeout]
|
8
|
+
|
9
|
+
# Request authentication methods.
|
10
|
+
AUTHENTICATION = [:basic_auth]
|
11
|
+
|
12
|
+
# Accepts a Hash of +options+ which may contain any number of ACCESSORS and/or
|
13
|
+
# AUTHENTICATION credentials to set.
|
14
|
+
def initialize(options = {})
|
15
|
+
assign_accessors options
|
16
|
+
assign_authentication options
|
17
|
+
end
|
18
|
+
|
19
|
+
# Sets the +url+ to access. Raises an +ArgumentError+ unless the +url+ is valid.
|
20
|
+
def url=(url)
|
21
|
+
@url = normalize_url! url
|
22
|
+
end
|
23
|
+
|
24
|
+
# Returns the +url+ to access.
|
25
|
+
attr_reader :url
|
26
|
+
|
27
|
+
# Sets the +proxy+ to use. Raises an +ArgumentError+ unless the +proxy+ is valid.
|
28
|
+
def proxy=(proxy)
|
29
|
+
@proxy = normalize_url! proxy
|
30
|
+
end
|
31
|
+
|
32
|
+
# Returns the +proxy+ to use.
|
33
|
+
attr_reader :proxy
|
34
|
+
|
35
|
+
# Returns a Hash of HTTP headers. Defaults to return an empty Hash.
|
36
|
+
def headers
|
37
|
+
@headers ||= {}
|
38
|
+
end
|
39
|
+
|
40
|
+
# Sets the Hash of HTTP headers.
|
41
|
+
attr_writer :headers
|
42
|
+
|
43
|
+
attr_accessor :body, :open_timeout, :read_timeout
|
44
|
+
|
45
|
+
# Sets the HTTP basic auth credentials. Accepts an Array or two arguments for the
|
46
|
+
# +username+ and +password+. Resets the credentials when +nil+ is passed and returns
|
47
|
+
# an Array of credentials when no +args+ where given.
|
48
|
+
def basic_auth(*args)
|
49
|
+
@basic_auth = extract_credentials @basic_auth, args.flatten
|
50
|
+
end
|
51
|
+
|
52
|
+
private
|
53
|
+
|
54
|
+
def assign_accessors(options)
|
55
|
+
ACCESSORS.each { |a| send("#{a}=", options[a]) if options[a] }
|
56
|
+
end
|
57
|
+
|
58
|
+
def assign_authentication(options)
|
59
|
+
AUTHENTICATION.each { |c| send(c, options[c]) if options[c] }
|
60
|
+
end
|
61
|
+
|
62
|
+
def normalize_url!(url)
|
63
|
+
raise ArgumentError, "Invalid URL: #{url}" unless url.to_s =~ /^http/
|
64
|
+
url.kind_of?(URI) ? url : URI(url)
|
65
|
+
end
|
66
|
+
|
67
|
+
def extract_credentials(credentials, args)
|
68
|
+
return unless args.empty? || args.first
|
69
|
+
args[1] ? args[0, 2] : credentials
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
73
|
+
end
|
data/lib/httpi/version.rb
CHANGED
Binary file
|
data/spec/fixtures/xml.xml
CHANGED
@@ -0,0 +1,10 @@
|
|
1
|
+
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ex="http://service.example.com/">
|
2
|
+
<soapenv:Header/>
|
3
|
+
<soapenv:Body>
|
4
|
+
<ex:findUser>
|
5
|
+
<request>
|
6
|
+
<id>1</id>
|
7
|
+
</request>
|
8
|
+
</ex:findUser>
|
9
|
+
</soapenv:Body>
|
10
|
+
</soapenv:Envelope>
|
@@ -1,89 +1,49 @@
|
|
1
1
|
require "spec_helper"
|
2
2
|
require "httpi/adapter/curb"
|
3
|
+
require "httpi/request"
|
4
|
+
|
5
|
+
require "curb"
|
3
6
|
|
4
7
|
describe HTTPI::Adapter::Curb do
|
5
|
-
|
6
|
-
@adapter = Class.new { include HTTPI::Adapter::Curb }.new
|
7
|
-
end
|
8
|
+
let(:adapter) { HTTPI::Adapter::Curb.new }
|
8
9
|
|
9
|
-
describe "
|
10
|
+
describe ".new" do
|
10
11
|
it "should require the Curb gem" do
|
11
|
-
|
12
|
-
|
12
|
+
HTTPI::Adapter::Curb.any_instance.expects(:require).with("curb")
|
13
|
+
HTTPI::Adapter::Curb.new
|
13
14
|
end
|
14
15
|
end
|
15
16
|
|
16
|
-
|
17
|
-
before
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
client.should be_an(Curl::Easy)
|
24
|
-
client.should equal(@adapter.client)
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
describe "#headers" do
|
29
|
-
it "should default to return an empty Hash" do
|
30
|
-
@adapter.headers.should == {}
|
31
|
-
end
|
32
|
-
end
|
33
|
-
|
34
|
-
describe "#headers=" do
|
35
|
-
it "should set a given Hash of HTTP headers" do
|
36
|
-
@adapter.headers = Some.headers
|
37
|
-
@adapter.headers.should == Some.headers
|
38
|
-
end
|
17
|
+
describe "#get" do
|
18
|
+
before do
|
19
|
+
curb.expects(:http_get)
|
20
|
+
curb.expects(:response_code).returns(200)
|
21
|
+
curb.expects(:headers).returns(Hash.new)
|
22
|
+
curb.expects(:body_str).returns(Fixture.xml)
|
39
23
|
end
|
40
24
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
@adapter.proxy.should == URI(Some.proxy_url)
|
45
|
-
end
|
46
|
-
|
47
|
-
it "should accept a URI" do
|
48
|
-
@adapter.proxy = URI(Some.proxy_url)
|
49
|
-
@adapter.proxy.should == URI(Some.proxy_url)
|
50
|
-
end
|
25
|
+
it "should return a valid HTTPI::Response" do
|
26
|
+
request = HTTPI::Request.new :url => "http://example.com"
|
27
|
+
adapter.get(request).should be_a_valid_httpi_response
|
51
28
|
end
|
29
|
+
end
|
52
30
|
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
end
|
31
|
+
describe "#post" do
|
32
|
+
before do
|
33
|
+
curb.expects(:http_post)
|
34
|
+
curb.expects(:response_code).returns(200)
|
35
|
+
curb.expects(:headers).returns(Hash.new)
|
36
|
+
curb.expects(:body_str).returns(Fixture.xml)
|
60
37
|
end
|
61
38
|
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
@adapter.client.expects(:response_code).returns(Some.response_code)
|
66
|
-
@adapter.client.expects(:headers).returns(Some.headers)
|
67
|
-
@adapter.client.expects(:body_str).returns(Fixture.xml)
|
68
|
-
end
|
69
|
-
|
70
|
-
it "should return a valid HTTPI::Response" do
|
71
|
-
@adapter.get(Some.url).should be_a_valid_httpi_response
|
72
|
-
end
|
39
|
+
it "should return a valid HTTPI::Response" do
|
40
|
+
request = HTTPI::Request.new :url => "http://example.com"
|
41
|
+
adapter.post(request).should be_a_valid_httpi_response
|
73
42
|
end
|
43
|
+
end
|
74
44
|
|
75
|
-
|
76
|
-
|
77
|
-
@adapter.client.expects(:http_post)
|
78
|
-
@adapter.client.expects(:response_code).returns(Some.response_code)
|
79
|
-
@adapter.client.expects(:headers).returns(Some.headers)
|
80
|
-
@adapter.client.expects(:body_str).returns(Fixture.xml)
|
81
|
-
end
|
82
|
-
|
83
|
-
it "should return a valid HTTPI::Response" do
|
84
|
-
@adapter.post(Some.url, Fixture.xml).should be_a_valid_httpi_response
|
85
|
-
end
|
86
|
-
end
|
45
|
+
def curb
|
46
|
+
Curl::Easy.any_instance
|
87
47
|
end
|
88
48
|
|
89
49
|
end
|
@@ -1,86 +1,45 @@
|
|
1
1
|
require "spec_helper"
|
2
2
|
require "httpi/adapter/httpclient"
|
3
|
+
require "httpi/request"
|
4
|
+
|
5
|
+
require "httpclient"
|
3
6
|
|
4
7
|
describe HTTPI::Adapter::HTTPClient do
|
5
|
-
|
6
|
-
@adapter = Class.new { include HTTPI::Adapter::HTTPClient }.new
|
7
|
-
end
|
8
|
+
let(:adapter) { HTTPI::Adapter::HTTPClient.new }
|
8
9
|
|
9
|
-
describe "
|
10
|
+
describe ".new" do
|
10
11
|
it "should require the HTTPClient gem" do
|
11
|
-
|
12
|
-
|
12
|
+
HTTPI::Adapter::HTTPClient.any_instance.expects(:require).with("httpclient")
|
13
|
+
HTTPI::Adapter::HTTPClient.new
|
13
14
|
end
|
14
15
|
end
|
15
16
|
|
16
|
-
|
17
|
-
before
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
client = @adapter.client
|
22
|
-
|
23
|
-
client.should be_an(HTTPClient)
|
24
|
-
client.should equal(@adapter.client)
|
25
|
-
end
|
17
|
+
describe "#get" do
|
18
|
+
before do
|
19
|
+
@request = HTTPI::Request.new :url => "http://example.com"
|
20
|
+
response = HTTP::Message.new_response Fixture.xml
|
21
|
+
httpclient.expects(:get).with(@request.url, nil, @request.headers).returns(response)
|
26
22
|
end
|
27
23
|
|
28
|
-
|
29
|
-
|
30
|
-
@adapter.headers.should == {}
|
31
|
-
end
|
32
|
-
end
|
33
|
-
|
34
|
-
describe "#headers=" do
|
35
|
-
it "should set a given Hash of HTTP headers" do
|
36
|
-
@adapter.headers = Some.headers
|
37
|
-
@adapter.headers.should == Some.headers
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
|
-
describe "#proxy" do
|
42
|
-
it "should set the proxy server to use" do
|
43
|
-
@adapter.proxy = Some.proxy_url
|
44
|
-
@adapter.proxy.should == URI(Some.proxy_url)
|
45
|
-
end
|
46
|
-
|
47
|
-
it "should accept a URI" do
|
48
|
-
@adapter.proxy = URI(Some.proxy_url)
|
49
|
-
@adapter.proxy.should == URI(Some.proxy_url)
|
50
|
-
end
|
24
|
+
it "should return a valid HTTPI::Response" do
|
25
|
+
adapter.get(@request).should be_a_valid_httpi_response
|
51
26
|
end
|
27
|
+
end
|
52
28
|
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
29
|
+
describe "#post" do
|
30
|
+
before do
|
31
|
+
@request = HTTPI::Request.new :url => "http://example.com", :body => Fixture.xml
|
32
|
+
response = HTTP::Message.new_response Fixture.xml
|
33
|
+
httpclient.expects(:post).with(@request.url, @request.body, @request.headers).returns(response)
|
58
34
|
end
|
59
35
|
|
60
|
-
|
61
|
-
|
62
|
-
response = HTTP::Message.new_response Fixture.xml
|
63
|
-
response.header.add *Some.headers.to_a.first
|
64
|
-
@adapter.client.expects(:get).with(Some.url).returns(response)
|
65
|
-
end
|
66
|
-
|
67
|
-
it "should return a valid HTTPI::Response" do
|
68
|
-
@adapter.get(Some.url).should be_a_valid_httpi_response
|
69
|
-
end
|
36
|
+
it "should return a valid HTTPI::Response" do
|
37
|
+
adapter.post(@request).should be_a_valid_httpi_response
|
70
38
|
end
|
39
|
+
end
|
71
40
|
|
72
|
-
|
73
|
-
|
74
|
-
response = HTTP::Message.new_response Fixture.xml
|
75
|
-
response.header.add *Some.headers.to_a.first
|
76
|
-
@adapter.headers = Some.headers
|
77
|
-
@adapter.client.expects(:post).with(Some.url, Fixture.xml, Some.headers).returns(response)
|
78
|
-
end
|
79
|
-
|
80
|
-
it "should return a valid HTTPI::Response" do
|
81
|
-
@adapter.post(Some.url, Fixture.xml).should be_a_valid_httpi_response
|
82
|
-
end
|
83
|
-
end
|
41
|
+
def httpclient
|
42
|
+
HTTPClient.any_instance
|
84
43
|
end
|
85
44
|
|
86
45
|
end
|
data/spec/httpi/adapter_spec.rb
CHANGED
@@ -2,31 +2,30 @@ require "spec_helper"
|
|
2
2
|
require "httpi/adapter"
|
3
3
|
|
4
4
|
describe HTTPI::Adapter do
|
5
|
+
let(:adapter) { HTTPI::Adapter }
|
5
6
|
|
6
7
|
describe ".use" do
|
7
8
|
it "should default to HTTPClient" do
|
8
|
-
|
9
|
+
adapter.use.should == :httpclient
|
9
10
|
end
|
10
|
-
|
11
|
-
|
12
|
-
describe ".use=" do
|
11
|
+
|
13
12
|
it "should accept an adapter to use" do
|
14
|
-
|
15
|
-
|
13
|
+
adapter.use = :curb
|
14
|
+
adapter.use.should == :curb
|
16
15
|
|
17
16
|
# reset to default
|
18
|
-
|
17
|
+
adapter.use = HTTPI::Adapter::DEFAULT
|
19
18
|
end
|
20
19
|
|
21
20
|
it "should raise an ArgumentError in case of an invalid adapter" do
|
22
|
-
lambda {
|
21
|
+
lambda { adapter.use = :unknown }.should raise_error(ArgumentError)
|
23
22
|
end
|
24
23
|
end
|
25
24
|
|
26
25
|
describe ".adapters" do
|
27
26
|
it "should return a memoized Hash of adapters" do
|
28
|
-
|
29
|
-
|
27
|
+
adapter.adapters.should have(2).items
|
28
|
+
adapter.adapters.should include(
|
30
29
|
:httpclient => HTTPI::Adapter::HTTPClient,
|
31
30
|
:curb => HTTPI::Adapter::Curb
|
32
31
|
)
|
@@ -35,11 +34,11 @@ describe HTTPI::Adapter do
|
|
35
34
|
|
36
35
|
describe ".find" do
|
37
36
|
it "should return the adapter for a given Symbol" do
|
38
|
-
|
37
|
+
adapter.find(:httpclient).should == HTTPI::Adapter::HTTPClient
|
39
38
|
end
|
40
39
|
|
41
40
|
it "should raise an ArgumentError in case of an invalid adapter" do
|
42
|
-
lambda {
|
41
|
+
lambda { adapter.find :unknown }.should raise_error(ArgumentError)
|
43
42
|
end
|
44
43
|
end
|
45
44
|
|
data/spec/httpi/client_spec.rb
CHANGED
@@ -2,20 +2,101 @@ require "spec_helper"
|
|
2
2
|
require "httpi"
|
3
3
|
|
4
4
|
describe HTTPI::Client do
|
5
|
+
let(:client) { HTTPI::Client }
|
6
|
+
let(:default_adapter) { HTTPI::Adapter.find HTTPI::Adapter.use }
|
7
|
+
let(:curb) { HTTPI::Adapter.find :curb }
|
5
8
|
|
6
|
-
describe ".
|
7
|
-
it "should
|
8
|
-
|
9
|
-
|
9
|
+
describe ".get(request)" do
|
10
|
+
it "should execute an HTTP GET request using the default adapter" do
|
11
|
+
request = HTTPI::Request.new
|
12
|
+
default_adapter.any_instance.expects(:get).with(request)
|
13
|
+
|
14
|
+
client.get request
|
10
15
|
end
|
16
|
+
end
|
11
17
|
|
12
|
-
|
13
|
-
|
14
|
-
|
18
|
+
describe ".get(request, adapter)" do
|
19
|
+
it "should execute an HTTP GET request using the given adapter" do
|
20
|
+
request = HTTPI::Request.new
|
21
|
+
curb.any_instance.expects(:get).with(request)
|
22
|
+
|
23
|
+
client.get request, :curb
|
15
24
|
end
|
25
|
+
end
|
16
26
|
|
27
|
+
describe ".get(url)" do
|
28
|
+
it "should execute an HTTP GET request using the default adapter" do
|
29
|
+
HTTPI::Request.any_instance.expects(:url=).with("http://example.com")
|
30
|
+
default_adapter.any_instance.expects(:get).with(instance_of(HTTPI::Request))
|
31
|
+
|
32
|
+
client.get "http://example.com"
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
describe ".get(url, adapter)" do
|
37
|
+
it "should execute an HTTP GET request using the given adapter" do
|
38
|
+
HTTPI::Request.any_instance.expects(:url=).with("http://example.com")
|
39
|
+
curb.any_instance.expects(:get).with(instance_of(HTTPI::Request))
|
40
|
+
|
41
|
+
client.get "http://example.com", :curb
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
describe ".get" do
|
17
46
|
it "should raise an ArgumentError in case of an invalid adapter" do
|
18
|
-
lambda { HTTPI::
|
47
|
+
lambda { client.get HTTPI::Request.new, :invalid }.should raise_error(ArgumentError)
|
48
|
+
end
|
49
|
+
|
50
|
+
it "should raise an ArgumentError in case of an invalid URL" do
|
51
|
+
lambda { client.get "invalid" }.should raise_error(ArgumentError)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
describe ".post(request)" do
|
56
|
+
it "should execute an HTTP POST request using the default adapter" do
|
57
|
+
request = HTTPI::Request.new
|
58
|
+
default_adapter.any_instance.expects(:post).with(request)
|
59
|
+
|
60
|
+
client.post request
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
describe ".post(request, adapter)" do
|
65
|
+
it "should execute an HTTP POST request using the given adapter" do
|
66
|
+
request = HTTPI::Request.new
|
67
|
+
curb.any_instance.expects(:post).with(request)
|
68
|
+
|
69
|
+
client.post request, :curb
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
describe ".post(url, body)" do
|
74
|
+
it "should execute an HTTP POST request using the default adapter" do
|
75
|
+
HTTPI::Request.any_instance.expects(:url=).with("http://example.com")
|
76
|
+
HTTPI::Request.any_instance.expects(:body=).with("<some>xml</some>")
|
77
|
+
default_adapter.any_instance.expects(:post).with(instance_of(HTTPI::Request))
|
78
|
+
|
79
|
+
client.post "http://example.com", "<some>xml</some>"
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
describe ".post(url, body, adapter)" do
|
84
|
+
it "should execute an HTTP POST request using the given adapter" do
|
85
|
+
HTTPI::Request.any_instance.expects(:url=).with("http://example.com")
|
86
|
+
HTTPI::Request.any_instance.expects(:body=).with("<some>xml</some>")
|
87
|
+
curb.any_instance.expects(:post).with(instance_of(HTTPI::Request))
|
88
|
+
|
89
|
+
client.post "http://example.com", "<some>xml</some>", :curb
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
describe ".post" do
|
94
|
+
it "should raise an ArgumentError in case of an invalid adapter" do
|
95
|
+
lambda { client.post HTTPI::Request.new, :invalid }.should raise_error(ArgumentError)
|
96
|
+
end
|
97
|
+
|
98
|
+
it "should raise an ArgumentError in case of an invalid URL" do
|
99
|
+
lambda { client.post "invalid" }.should raise_error(ArgumentError)
|
19
100
|
end
|
20
101
|
end
|
21
102
|
|