httpi 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.rspec +1 -0
- data/Gemfile +11 -0
- data/README.rdoc +85 -0
- data/Rakefile +13 -0
- data/autotest/discover.rb +1 -0
- data/lib/httpi.rb +2 -0
- data/lib/httpi/adapter.rb +40 -0
- data/lib/httpi/adapter/base.rb +16 -0
- data/lib/httpi/adapter/curb.rb +59 -0
- data/lib/httpi/adapter/httpclient.rb +51 -0
- data/lib/httpi/client.rb +12 -0
- data/lib/httpi/interface.rb +21 -0
- data/lib/httpi/response.rb +47 -0
- data/lib/httpi/version.rb +5 -0
- data/spec/fixtures/gzip.gz +0 -0
- data/spec/fixtures/xml.xml +0 -0
- data/spec/httpi/adapter/curb_spec.rb +89 -0
- data/spec/httpi/adapter/httpclient_spec.rb +86 -0
- data/spec/httpi/adapter_spec.rb +46 -0
- data/spec/httpi/client_spec.rb +22 -0
- data/spec/httpi/interface_spec.rb +33 -0
- data/spec/httpi/response_spec.rb +33 -0
- data/spec/spec_helper.rb +9 -0
- data/spec/support/helper_methods.rb +41 -0
- data/spec/support/matchers.rb +8 -0
- metadata +156 -0
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--color
|
data/Gemfile
ADDED
data/README.rdoc
ADDED
@@ -0,0 +1,85 @@
|
|
1
|
+
= HTTPI
|
2
|
+
|
3
|
+
HTTPI provides a common interface for different HTTP libraries.
|
4
|
+
|
5
|
+
== Installation
|
6
|
+
|
7
|
+
The gem is available through {Rubygems}[http://rubygems.org/gems/httpi] and can be installed via:
|
8
|
+
|
9
|
+
$ gem install httpi
|
10
|
+
|
11
|
+
== Supported libraries
|
12
|
+
|
13
|
+
* {httpclient}[http://rubygems.org/gems/httpclient] ~> 2.1.5
|
14
|
+
* {curb}[http://rubygems.org/gems/curb] ~> 0.7.8
|
15
|
+
|
16
|
+
== Getting started
|
17
|
+
|
18
|
+
To get started, simply create a new HTTPI::Client:
|
19
|
+
|
20
|
+
client = HTTPI::Client.new :curb
|
21
|
+
|
22
|
+
Notice that when you're not passing a library to use, HTTPI will default to use the HTTPClient library:
|
23
|
+
|
24
|
+
HTTPI::Adapter.use # => :httpclient
|
25
|
+
|
26
|
+
Changing the default is fairly easy:
|
27
|
+
|
28
|
+
HTTPI::Adapter.use = :curb
|
29
|
+
|
30
|
+
== Settings
|
31
|
+
|
32
|
+
=== #headers
|
33
|
+
|
34
|
+
Accessor for the HTTP request headers:
|
35
|
+
|
36
|
+
client.headers = { "Accept-Encoding" => "gzip" }
|
37
|
+
client.headers # => { "Accept-Encoding" => "gzip" }
|
38
|
+
|
39
|
+
=== #proxy
|
40
|
+
|
41
|
+
Accessor for the proxy server to use:
|
42
|
+
|
43
|
+
client.proxy = "http://proxy.example.com"
|
44
|
+
client.proxy # => #<URI::HTTP:0x1026240f0 URL:http://proxy.example.com>
|
45
|
+
|
46
|
+
=== #auth(username, password)
|
47
|
+
|
48
|
+
Setting authentication credentials:
|
49
|
+
|
50
|
+
client.auth "username", "password"
|
51
|
+
|
52
|
+
== Request methods
|
53
|
+
|
54
|
+
=== #get(url)
|
55
|
+
|
56
|
+
Sending an HTTP GET request:
|
57
|
+
|
58
|
+
client.get "http://example.com"
|
59
|
+
|
60
|
+
=== #post(url, body)
|
61
|
+
|
62
|
+
Sending an HTTP POST request:
|
63
|
+
|
64
|
+
client.post "http://example.com", "<some>xml</xml>"
|
65
|
+
|
66
|
+
== HTTPI::Response
|
67
|
+
|
68
|
+
Every HTTP request method is supposed to return an HTTPI::Response containing the response code, headers and body.
|
69
|
+
|
70
|
+
response = client.get "http://example.com"
|
71
|
+
|
72
|
+
response.code # => 200
|
73
|
+
response.headers # => { "Content-Encoding" => "gzip" }
|
74
|
+
response.body # => "<!DOCTYPE HTML PUBLIC ..."
|
75
|
+
|
76
|
+
== Participate
|
77
|
+
|
78
|
+
I would appreciate any help to support additional libraries and methods!
|
79
|
+
|
80
|
+
== TODO
|
81
|
+
|
82
|
+
Implement methods for:
|
83
|
+
|
84
|
+
* add SSL configuration method
|
85
|
+
* add timeout methods
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
Autotest.add_discovery { "rspec2" }
|
data/lib/httpi.rb
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
require "httpi/adapter/httpclient"
|
2
|
+
require "httpi/adapter/curb"
|
3
|
+
|
4
|
+
module HTTPI
|
5
|
+
module Adapter
|
6
|
+
|
7
|
+
# The default adapter.
|
8
|
+
DEFAULT = :httpclient
|
9
|
+
|
10
|
+
# Returns the adapter to use. Defaults to <tt>HTTPI::Adapter::DEFAULT</tt>.
|
11
|
+
def self.use
|
12
|
+
@use ||= DEFAULT
|
13
|
+
end
|
14
|
+
|
15
|
+
# Sets the +adapter+ to use. Raises an +ArgumentError+ unless the +adapter+ exists.
|
16
|
+
def self.use=(adapter)
|
17
|
+
validate_adapter! adapter
|
18
|
+
@use = adapter
|
19
|
+
end
|
20
|
+
|
21
|
+
# Returns a memoized +Hash+ of adapters.
|
22
|
+
def self.adapters
|
23
|
+
@adapters ||= { :httpclient => HTTPClient, :curb => Curb }
|
24
|
+
end
|
25
|
+
|
26
|
+
# Returns an +adapter+. Raises an +ArgumentError+ unless the +adapter+ exists.
|
27
|
+
def self.find(adapter)
|
28
|
+
validate_adapter! adapter
|
29
|
+
adapters[adapter]
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
# Raises an +ArgumentError+ unless the +adapter+ exists.
|
35
|
+
def self.validate_adapter!(adapter)
|
36
|
+
raise ArgumentError, "Invalid HTTPI adapter: #{adapter}" unless adapters[adapter]
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module HTTPI
|
2
|
+
module Adapter
|
3
|
+
module Base
|
4
|
+
|
5
|
+
# List of methods expected to be implemented by an adapter.
|
6
|
+
METHODS = %w(setup client headers headers= proxy proxy= get post auth)
|
7
|
+
|
8
|
+
METHODS.each do |method|
|
9
|
+
define_method method do |*args|
|
10
|
+
raise NotImplementedError, "#{Adapter.use} does not implement a #{method} method"
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
require "httpi/response"
|
2
|
+
require "httpi/adapter/base"
|
3
|
+
|
4
|
+
module HTTPI
|
5
|
+
module Adapter
|
6
|
+
module Curb
|
7
|
+
include Base
|
8
|
+
|
9
|
+
def setup
|
10
|
+
require "curb"
|
11
|
+
end
|
12
|
+
|
13
|
+
def client
|
14
|
+
@client ||= Curl::Easy.new
|
15
|
+
end
|
16
|
+
|
17
|
+
def headers
|
18
|
+
client.headers
|
19
|
+
end
|
20
|
+
|
21
|
+
def headers=(headers)
|
22
|
+
client.headers = headers
|
23
|
+
end
|
24
|
+
|
25
|
+
def proxy
|
26
|
+
proxy = client.proxy_url
|
27
|
+
proxy.kind_of?(URI) ? proxy : URI(proxy)
|
28
|
+
end
|
29
|
+
|
30
|
+
def proxy=(proxy)
|
31
|
+
client.proxy_url = proxy
|
32
|
+
end
|
33
|
+
|
34
|
+
def auth(username, password)
|
35
|
+
client.username = username
|
36
|
+
client.password = password
|
37
|
+
end
|
38
|
+
|
39
|
+
def get(url)
|
40
|
+
client.url = url.to_s
|
41
|
+
client.http_get
|
42
|
+
respond
|
43
|
+
end
|
44
|
+
|
45
|
+
def post(url, body)
|
46
|
+
client.url = url.to_s
|
47
|
+
client.http_post body
|
48
|
+
respond
|
49
|
+
end
|
50
|
+
|
51
|
+
private
|
52
|
+
|
53
|
+
def respond
|
54
|
+
Response.new client.response_code, client.headers, client.body_str
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
require "httpi/response"
|
2
|
+
require "httpi/adapter/base"
|
3
|
+
|
4
|
+
module HTTPI
|
5
|
+
module Adapter
|
6
|
+
module HTTPClient
|
7
|
+
include Base
|
8
|
+
|
9
|
+
def setup
|
10
|
+
require "httpclient"
|
11
|
+
end
|
12
|
+
|
13
|
+
def client
|
14
|
+
@client ||= ::HTTPClient.new
|
15
|
+
end
|
16
|
+
|
17
|
+
def headers
|
18
|
+
@headers ||= {}
|
19
|
+
end
|
20
|
+
|
21
|
+
attr_writer :headers
|
22
|
+
|
23
|
+
def proxy
|
24
|
+
client.proxy
|
25
|
+
end
|
26
|
+
|
27
|
+
def proxy=(proxy)
|
28
|
+
client.proxy = proxy
|
29
|
+
end
|
30
|
+
|
31
|
+
def auth(username, password)
|
32
|
+
client.set_auth nil, username, password
|
33
|
+
end
|
34
|
+
|
35
|
+
def get(url)
|
36
|
+
respond_with client.get(url)
|
37
|
+
end
|
38
|
+
|
39
|
+
def post(url, body)
|
40
|
+
respond_with client.post(url, body, headers)
|
41
|
+
end
|
42
|
+
|
43
|
+
private
|
44
|
+
|
45
|
+
def respond_with(response)
|
46
|
+
Response.new response.code, Hash[response.header.all], response.content
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
data/lib/httpi/client.rb
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
require "httpi/adapter"
|
2
|
+
|
3
|
+
module HTTPI
|
4
|
+
module Interface
|
5
|
+
|
6
|
+
# Loads a given +adapter+. Defaults to load <tt>HTTPI::Adapter::DEFAULT</tt>.
|
7
|
+
def load!(adapter = nil)
|
8
|
+
adapter ||= Adapter.use
|
9
|
+
include_adapter Adapter.find(adapter)
|
10
|
+
setup
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
# Includes a given +adapter+ into the current class.
|
16
|
+
def include_adapter(adapter)
|
17
|
+
self.class.send :include, adapter
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require "zlib"
|
2
|
+
require "stringio"
|
3
|
+
|
4
|
+
module HTTPI
|
5
|
+
class Response
|
6
|
+
|
7
|
+
# Range of HTTP response codes considered to be successful.
|
8
|
+
SuccessfulResponseCodes = 200..299
|
9
|
+
|
10
|
+
# Initializer expects an HTTP response +code+, +headers+ and +body+.
|
11
|
+
def initialize(code, headers, body)
|
12
|
+
self.code = code
|
13
|
+
self.headers = headers
|
14
|
+
self.raw_body = body
|
15
|
+
end
|
16
|
+
|
17
|
+
attr_accessor :code, :headers, :raw_body
|
18
|
+
|
19
|
+
# Returns whether the HTTP response is considered successful.
|
20
|
+
def error?
|
21
|
+
!SuccessfulResponseCodes.include? code.to_i
|
22
|
+
end
|
23
|
+
|
24
|
+
# Returns the HTTP response body.
|
25
|
+
def body
|
26
|
+
@body ||= gzipped_response? ? decoded_body : raw_body
|
27
|
+
end
|
28
|
+
|
29
|
+
attr_writer :body
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
# Returns whether the response is gzipped.
|
34
|
+
def gzipped_response?
|
35
|
+
headers["Content-Encoding"] == "gzip" || raw_body[0..1] == "\x1f\x8b"
|
36
|
+
end
|
37
|
+
|
38
|
+
# Returns the gzip decoded response body.
|
39
|
+
def decoded_body
|
40
|
+
gzip = Zlib::GzipReader.new StringIO.new(raw_body)
|
41
|
+
gzip.read
|
42
|
+
ensure
|
43
|
+
gzip.close
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
end
|
Binary file
|
File without changes
|
@@ -0,0 +1,89 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
require "httpi/adapter/curb"
|
3
|
+
|
4
|
+
describe HTTPI::Adapter::Curb do
|
5
|
+
before do
|
6
|
+
@adapter = Class.new { include HTTPI::Adapter::Curb }.new
|
7
|
+
end
|
8
|
+
|
9
|
+
describe "#setup" do
|
10
|
+
it "should require the Curb gem" do
|
11
|
+
@adapter.expects(:require).with("curb")
|
12
|
+
@adapter.setup
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
context "after #setup:" do
|
17
|
+
before { @adapter.setup }
|
18
|
+
|
19
|
+
describe "#client" do
|
20
|
+
it "should return a memoized Curl::Easy instance" do
|
21
|
+
client = @adapter.client
|
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
|
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
|
51
|
+
end
|
52
|
+
|
53
|
+
describe "#auth" do
|
54
|
+
it "should set authentication credentials" do
|
55
|
+
@adapter.client.expects(:username=).with("username")
|
56
|
+
@adapter.client.expects(:password=).with("password")
|
57
|
+
|
58
|
+
@adapter.auth "username", "password"
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
describe "#get" do
|
63
|
+
before do
|
64
|
+
@adapter.client.expects(:http_get)
|
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
|
73
|
+
end
|
74
|
+
|
75
|
+
describe "#post" do
|
76
|
+
before do
|
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
|
87
|
+
end
|
88
|
+
|
89
|
+
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
require "httpi/adapter/httpclient"
|
3
|
+
|
4
|
+
describe HTTPI::Adapter::HTTPClient do
|
5
|
+
before do
|
6
|
+
@adapter = Class.new { include HTTPI::Adapter::HTTPClient }.new
|
7
|
+
end
|
8
|
+
|
9
|
+
describe "#setup" do
|
10
|
+
it "should require the HTTPClient gem" do
|
11
|
+
@adapter.expects(:require).with("httpclient")
|
12
|
+
@adapter.setup
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
context "after #setup:" do
|
17
|
+
before { @adapter.setup }
|
18
|
+
|
19
|
+
describe "#client" do
|
20
|
+
it "should return a memoized HTTPClient instance" do
|
21
|
+
client = @adapter.client
|
22
|
+
|
23
|
+
client.should be_an(HTTPClient)
|
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
|
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
|
51
|
+
end
|
52
|
+
|
53
|
+
describe "#auth" do
|
54
|
+
it "should set authentication credentials" do
|
55
|
+
@adapter.client.expects(:set_auth).with(nil, "username", "password")
|
56
|
+
@adapter.auth "username", "password"
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
describe "#get" do
|
61
|
+
before do
|
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
|
70
|
+
end
|
71
|
+
|
72
|
+
describe "#post" do
|
73
|
+
before do
|
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
|
84
|
+
end
|
85
|
+
|
86
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
require "httpi/adapter"
|
3
|
+
|
4
|
+
describe HTTPI::Adapter do
|
5
|
+
|
6
|
+
describe ".use" do
|
7
|
+
it "should default to HTTPClient" do
|
8
|
+
HTTPI::Adapter.use.should == :httpclient
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
describe ".use=" do
|
13
|
+
it "should accept an adapter to use" do
|
14
|
+
HTTPI::Adapter.use = :curb
|
15
|
+
HTTPI::Adapter.use.should == :curb
|
16
|
+
|
17
|
+
# reset to default
|
18
|
+
HTTPI::Adapter.use = HTTPI::Adapter::DEFAULT
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should raise an ArgumentError in case of an invalid adapter" do
|
22
|
+
lambda { HTTPI::Adapter.use = :unknown }.should raise_error(ArgumentError)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
describe ".adapters" do
|
27
|
+
it "should return a memoized Hash of adapters" do
|
28
|
+
HTTPI::Adapter.adapters.should have(2).items
|
29
|
+
HTTPI::Adapter.adapters.should include(
|
30
|
+
:httpclient => HTTPI::Adapter::HTTPClient,
|
31
|
+
:curb => HTTPI::Adapter::Curb
|
32
|
+
)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
describe ".find" do
|
37
|
+
it "should return the adapter for a given Symbol" do
|
38
|
+
HTTPI::Adapter.find(:httpclient).should == HTTPI::Adapter::HTTPClient
|
39
|
+
end
|
40
|
+
|
41
|
+
it "should raise an ArgumentError in case of an invalid adapter" do
|
42
|
+
lambda { HTTPI::Adapter.find :unknown }.should raise_error(ArgumentError)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
require "httpi"
|
3
|
+
|
4
|
+
describe HTTPI::Client do
|
5
|
+
|
6
|
+
describe ".new" do
|
7
|
+
it "should default to use HTTPI::Adapter::DEFAULT" do
|
8
|
+
@httpi = HTTPI::Client.new
|
9
|
+
@httpi.client.should be_an(HTTPClient)
|
10
|
+
end
|
11
|
+
|
12
|
+
it "should accept an adapter to use" do
|
13
|
+
@httpi = HTTPI::Client.new :curb
|
14
|
+
@httpi.client.should be_a(Curl::Easy)
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should raise an ArgumentError in case of an invalid adapter" do
|
18
|
+
lambda { HTTPI::Client.new :unknown }.should raise_error(ArgumentError)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
require "httpi/interface"
|
3
|
+
|
4
|
+
describe HTTPI::Interface do
|
5
|
+
|
6
|
+
context "when included" do
|
7
|
+
before do
|
8
|
+
@httpi = Class.new { include HTTPI::Interface }.new
|
9
|
+
end
|
10
|
+
|
11
|
+
it "should offer a #load! method for loading an adapter" do
|
12
|
+
@httpi.load!
|
13
|
+
@httpi.client.should be_an(HTTPClient)
|
14
|
+
end
|
15
|
+
|
16
|
+
describe "#load!" do
|
17
|
+
it "should accept an adapter to use" do
|
18
|
+
@httpi.load! :curb
|
19
|
+
@httpi.client.should be_a(Curl::Easy)
|
20
|
+
end
|
21
|
+
|
22
|
+
it "should raise an ArgumentError in case of an invalid adapter" do
|
23
|
+
lambda { @httpi.load! :unknown }.should raise_error(ArgumentError)
|
24
|
+
end
|
25
|
+
|
26
|
+
it "should call the adapter's #setup method" do
|
27
|
+
@httpi.expects(:setup)
|
28
|
+
@httpi.load!
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
require "httpi/response"
|
3
|
+
|
4
|
+
describe HTTPI::Response do
|
5
|
+
before do
|
6
|
+
@response = HTTPI::Response.new Some.response_code, Some.headers, Fixture.gzip
|
7
|
+
end
|
8
|
+
|
9
|
+
describe "#code" do
|
10
|
+
it "should return the HTTP response code" do
|
11
|
+
@response.code.should == Some.response_code
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
describe "#code" do
|
16
|
+
it "should return the HTTP response headers" do
|
17
|
+
@response.headers.should == Some.headers
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
describe "#body" do
|
22
|
+
it "should return the (gzip decoded) HTTP response body" do
|
23
|
+
@response.body.should == "A short gzip encoded message\n"
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
describe "#raw_body" do
|
28
|
+
it "should return the raw HTML response body" do
|
29
|
+
@response.raw_body.should == Fixture.gzip
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
class Some
|
2
|
+
class << self
|
3
|
+
|
4
|
+
def url
|
5
|
+
@url ||= "http://example.com"
|
6
|
+
end
|
7
|
+
|
8
|
+
def proxy_url
|
9
|
+
@proxy_url ||= "http://proxy.example.com"
|
10
|
+
end
|
11
|
+
|
12
|
+
def headers
|
13
|
+
@headers ||= { "Content-Type" => "text/html; charset=utf-8" }
|
14
|
+
end
|
15
|
+
|
16
|
+
def response_code
|
17
|
+
@code ||= 200
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
class Fixture
|
24
|
+
class << self
|
25
|
+
|
26
|
+
def xml
|
27
|
+
@xml ||= load :xml
|
28
|
+
end
|
29
|
+
|
30
|
+
def gzip
|
31
|
+
@gzip ||= load :gzip, :gz
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
|
+
def load(fixture, type = :xml)
|
37
|
+
File.read File.expand_path("../../fixtures/#{fixture}.#{type}", __FILE__)
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
end
|
metadata
ADDED
@@ -0,0 +1,156 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: httpi
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 27
|
5
|
+
prerelease: false
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 1
|
9
|
+
- 0
|
10
|
+
version: 0.1.0
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Daniel Harrington
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2010-09-12 00:00:00 +02:00
|
19
|
+
default_executable:
|
20
|
+
dependencies:
|
21
|
+
- !ruby/object:Gem::Dependency
|
22
|
+
name: httpclient
|
23
|
+
prerelease: false
|
24
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ~>
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
hash: 1
|
30
|
+
segments:
|
31
|
+
- 2
|
32
|
+
- 1
|
33
|
+
- 5
|
34
|
+
version: 2.1.5
|
35
|
+
type: :development
|
36
|
+
version_requirements: *id001
|
37
|
+
- !ruby/object:Gem::Dependency
|
38
|
+
name: curb
|
39
|
+
prerelease: false
|
40
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ~>
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
hash: 19
|
46
|
+
segments:
|
47
|
+
- 0
|
48
|
+
- 7
|
49
|
+
- 8
|
50
|
+
version: 0.7.8
|
51
|
+
type: :development
|
52
|
+
version_requirements: *id002
|
53
|
+
- !ruby/object:Gem::Dependency
|
54
|
+
name: rspec
|
55
|
+
prerelease: false
|
56
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - "="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
hash: 62196421
|
62
|
+
segments:
|
63
|
+
- 2
|
64
|
+
- 0
|
65
|
+
- 0
|
66
|
+
- beta
|
67
|
+
- 19
|
68
|
+
version: 2.0.0.beta.19
|
69
|
+
type: :development
|
70
|
+
version_requirements: *id003
|
71
|
+
- !ruby/object:Gem::Dependency
|
72
|
+
name: mocha
|
73
|
+
prerelease: false
|
74
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
75
|
+
none: false
|
76
|
+
requirements:
|
77
|
+
- - ~>
|
78
|
+
- !ruby/object:Gem::Version
|
79
|
+
hash: 43
|
80
|
+
segments:
|
81
|
+
- 0
|
82
|
+
- 9
|
83
|
+
- 8
|
84
|
+
version: 0.9.8
|
85
|
+
type: :development
|
86
|
+
version_requirements: *id004
|
87
|
+
description: HTTPI provides a common interface for different HTTP libraries.
|
88
|
+
email: me@rubiii.com
|
89
|
+
executables: []
|
90
|
+
|
91
|
+
extensions: []
|
92
|
+
|
93
|
+
extra_rdoc_files: []
|
94
|
+
|
95
|
+
files:
|
96
|
+
- Gemfile
|
97
|
+
- Rakefile
|
98
|
+
- README.rdoc
|
99
|
+
- autotest/discover.rb
|
100
|
+
- lib/httpi/adapter/base.rb
|
101
|
+
- lib/httpi/adapter/curb.rb
|
102
|
+
- lib/httpi/adapter/httpclient.rb
|
103
|
+
- lib/httpi/adapter.rb
|
104
|
+
- lib/httpi/client.rb
|
105
|
+
- lib/httpi/interface.rb
|
106
|
+
- lib/httpi/response.rb
|
107
|
+
- lib/httpi/version.rb
|
108
|
+
- lib/httpi.rb
|
109
|
+
- spec/fixtures/gzip.gz
|
110
|
+
- spec/fixtures/xml.xml
|
111
|
+
- spec/httpi/adapter/curb_spec.rb
|
112
|
+
- spec/httpi/adapter/httpclient_spec.rb
|
113
|
+
- spec/httpi/adapter_spec.rb
|
114
|
+
- spec/httpi/client_spec.rb
|
115
|
+
- spec/httpi/interface_spec.rb
|
116
|
+
- spec/httpi/response_spec.rb
|
117
|
+
- spec/spec_helper.rb
|
118
|
+
- spec/support/helper_methods.rb
|
119
|
+
- spec/support/matchers.rb
|
120
|
+
- .rspec
|
121
|
+
has_rdoc: true
|
122
|
+
homepage: http://github.com/rubiii/httpi
|
123
|
+
licenses: []
|
124
|
+
|
125
|
+
post_install_message:
|
126
|
+
rdoc_options: []
|
127
|
+
|
128
|
+
require_paths:
|
129
|
+
- lib
|
130
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
131
|
+
none: false
|
132
|
+
requirements:
|
133
|
+
- - ">="
|
134
|
+
- !ruby/object:Gem::Version
|
135
|
+
hash: 3
|
136
|
+
segments:
|
137
|
+
- 0
|
138
|
+
version: "0"
|
139
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
140
|
+
none: false
|
141
|
+
requirements:
|
142
|
+
- - ">="
|
143
|
+
- !ruby/object:Gem::Version
|
144
|
+
hash: 3
|
145
|
+
segments:
|
146
|
+
- 0
|
147
|
+
version: "0"
|
148
|
+
requirements: []
|
149
|
+
|
150
|
+
rubyforge_project: httpi
|
151
|
+
rubygems_version: 1.3.7
|
152
|
+
signing_key:
|
153
|
+
specification_version: 3
|
154
|
+
summary: Common interface for Ruby HTTP libraries
|
155
|
+
test_files: []
|
156
|
+
|