httpi 0.3.0 → 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.
data/.autotest ADDED
@@ -0,0 +1,5 @@
1
+ Autotest.add_hook(:initialize) do |at|
2
+ at.clear_mappings
3
+ at.add_mapping(%r%^spec/httpi/.*_spec.rb$%) { |filename, _| filename }
4
+ at.add_mapping(%r%^lib/(.*)\.rb$%) { |_, m| ["spec/#{m[1]}_spec.rb"] }
5
+ end
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- httpi (0.2.0)
4
+ httpi (0.3.0)
5
5
 
6
6
  GEM
7
7
  remote: http://rubygems.org/
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2010 Daniel Harrington
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md CHANGED
@@ -3,6 +3,8 @@ HTTPI
3
3
 
4
4
  HTTPI provides a common interface for Ruby HTTP libraries.
5
5
 
6
+ [Feedback](http://httpi.uservoice.com) | [Bugs](http://github.com/rubiii/httpi/issues) | [Docs](http://rubydoc.info/gems/httpi)
7
+
6
8
  Installation
7
9
  ------------
8
10
 
@@ -13,12 +15,12 @@ The gem is available through [Rubygems](http://rubygems.org/gems/httpi) and can
13
15
  Some examples
14
16
  -------------
15
17
 
16
- Let's create the most basic request object and execute a GET request:
18
+ Executing a POST request with the most basic request object:
17
19
 
18
20
  request = HTTPI::Request.new :url => "http://example.com"
19
21
  HTTPI.get request
20
22
 
21
- A POST request with a request object:
23
+ Here's a POST request with a request object:
22
24
 
23
25
  request = HTTPI::Request.new
24
26
  request.url = "http://post.example.com"
@@ -34,19 +36,19 @@ And a GET request using HTTP basic auth and the Curb adapter:
34
36
 
35
37
  HTTPI.get request, :curb
36
38
 
37
- HTTPI also comes with some shortcuts. This executes a GET request:
39
+ HTTPI also comes with some shortcuts. This executes a PUT request:
38
40
 
39
- HTTPI.get "http://example.com"
41
+ HTTPI.put "http://example.com", "<some>xml</some>"
40
42
 
41
- And here's a POST:
43
+ And this executes a DELETE request:
42
44
 
43
- HTTPI.post "http://example.com", "<some>xml</some>"
45
+ HTTPI.delete "http://example.com"
44
46
 
45
47
  HTTPI
46
48
  -------------
47
49
 
48
- The `HTTPI` module uses one of the available adapters to execute HTTP requests.
49
- It currently supports GET and POST requests:
50
+ The `HTTPI` module uses one of the available adapters to execute HTTP requests.
51
+ It supports GET, POST, HEAD, PUT and DELETE requests:
50
52
 
51
53
  ### GET
52
54
 
@@ -58,6 +60,21 @@ It currently supports GET and POST requests:
58
60
  .post(request, adapter = nil)
59
61
  .post(url, body, adapter = nil)
60
62
 
63
+ ### HEAD
64
+
65
+ .head(request, adapter = nil)
66
+ .head(url, adapter = nil)
67
+
68
+ ### PUT
69
+
70
+ .put(request, adapter = nil)
71
+ .put(url, body, adapter = nil)
72
+
73
+ ### DELETE
74
+
75
+ .delete(request, adapter = nil)
76
+ .delete(url, adapter = nil)
77
+
61
78
  ### Notice
62
79
 
63
80
  * You can specify the adapter to use per request
@@ -72,10 +89,6 @@ by your adapter in a block:
72
89
  http.use_ssl = true # Curb example
73
90
  end
74
91
 
75
- ### TODO
76
-
77
- * Add support for HEAD, PUT and DELETE requests
78
-
79
92
  HTTPI::Request
80
93
  --------------
81
94
 
@@ -91,17 +104,18 @@ It represents an HTTP request and lets you customize various settings through th
91
104
 
92
105
  It also contains methods for setting up authentication:
93
106
 
94
- #basic_auth(username, password) # HTTP basic auth credentials
107
+ #basic_auth(username, password) # HTTP basic auth credentials
108
+ #digest_auth(username, password) # HTTP digest auth credentials
95
109
 
96
110
  ### TODO
97
111
 
98
- * Add support for HTTP digest authentication
99
112
  * Add support for SSL client authentication
113
+ * Add support for NTLM authentication
100
114
 
101
115
  HTTPI::Adapter
102
116
  --------------
103
117
 
104
- HTTPI uses adapters to support multiple HTTP libraries.
118
+ HTTPI uses adapters to support multiple HTTP libraries.
105
119
  It currently contains adapters for:
106
120
 
107
121
  * [httpclient](http://rubygems.org/gems/httpclient) ~> 2.1.5
@@ -109,16 +123,12 @@ It currently contains adapters for:
109
123
 
110
124
  By default, HTTPI uses the `HTTPClient`. But changing the default is fairly easy:
111
125
 
112
- HTTPI::Adapter.use = :curb
113
-
114
- You can find a list of supported adapters via:
115
-
116
- HTTPI::Adapter.adapters # returns a Hash of supported adapters
126
+ HTTPI::Adapter.use = :curb # or :httpclient
117
127
 
118
128
  HTTPI::Response
119
129
  ---------------
120
130
 
121
- As mentioned before, every request method return an `HTTPI::Response`.
131
+ As mentioned before, every request method return an `HTTPI::Response`.
122
132
  It contains the response code, headers and body.
123
133
 
124
134
  response = HTTPI.get request
data/Rakefile CHANGED
@@ -29,6 +29,13 @@ begin
29
29
  require "rspec/core/rake_task"
30
30
 
31
31
  RSpec::Core::RakeTask.new do |t|
32
+ t.pattern = "spec/httpi/*_spec.rb"
33
+ t.rspec_opts = %w(-fd -c)
34
+ end
35
+
36
+ desc "Run RSpec integration examples"
37
+ RSpec::Core::RakeTask.new "spec:integration" do |t|
38
+ t.pattern = "spec/integration/*_spec.rb"
32
39
  t.rspec_opts = %w(-fd -c)
33
40
  end
34
41
  rescue LoadError
data/lib/httpi.rb CHANGED
@@ -5,33 +5,73 @@ require "httpi/adapter"
5
5
  # = HTTPI
6
6
  #
7
7
  # Executes HTTP requests using a predefined adapter.
8
+ # All request methods accept an <tt>HTTPI::Request</tt> and an optional adapter.
9
+ # They may also offer shortcut methods for executing basic requests.
10
+ # Also they all return an <tt>HTTPI::Response</tt>.
11
+ #
12
+ # == GET
13
+ #
14
+ # request = HTTPI::Request.new :url => "http://example.com"
15
+ # HTTPI.get request, :httpclient
16
+ #
17
+ # === Shortcuts
18
+ #
19
+ # HTTPI.get "http://example.com", :curb
20
+ #
21
+ # == POST
22
+ #
23
+ # request = HTTPI::Request.new
24
+ # request.url = "http://example.com"
25
+ # request.body = "<some>xml</some>"
26
+ #
27
+ # HTTPI.post request, :httpclient
28
+ #
29
+ # === Shortcuts
30
+ #
31
+ # HTTPI.post "http://example.com", "<some>xml</some>", :curb
32
+ #
33
+ # == HEAD
34
+ #
35
+ # request = HTTPI::Request.new :url => "http://example.com"
36
+ # HTTPI.head request, :httpclient
37
+ #
38
+ # === Shortcuts
39
+ #
40
+ # HTTPI.head "http://example.com", :curb
41
+ #
42
+ # == PUT
43
+ #
44
+ # request = HTTPI::Request.new
45
+ # request.url = "http://example.com"
46
+ # request.body = "<some>xml</some>"
47
+ #
48
+ # HTTPI.put request, :httpclient
49
+ #
50
+ # === Shortcuts
51
+ #
52
+ # HTTPI.put "http://example.com", "<some>xml</some>", :curb
53
+ #
54
+ # == DELETE
55
+ #
56
+ # request = HTTPI::Request.new :url => "http://example.com"
57
+ # HTTPI.delete request, :httpclient
58
+ #
59
+ # === Shortcuts
60
+ #
61
+ # HTTPI.delete "http://example.com", :curb
62
+ #
63
+ # == More control
64
+ #
65
+ # If you need more control over your request, you can access the HTTP client
66
+ # instance represented by your adapter in a block.
67
+ #
68
+ # HTTPI.get request do |http|
69
+ # http.follow_redirect_count = 3 # HTTPClient example
70
+ # end
8
71
  module HTTPI
9
72
  class << self
10
73
 
11
- # Executes an HTTP GET request and returns an <tt>HTTPI::Response</tt>.
12
- #
13
- # ==== Example
14
- #
15
- # Accepts an <tt>HTTPI::Request</tt> and an optional adapter:
16
- #
17
- # request = HTTPI::Request.new :url => "http://example.com"
18
- # HTTPI.get request, :httpclient
19
- #
20
- # ==== Shortcut
21
- #
22
- # You can also just pass a URL and an optional adapter if you don't
23
- # need to configure the request:
24
- #
25
- # HTTPI.get "http://example.com", :curb
26
- #
27
- # ==== More control
28
- #
29
- # If you need more control over the request, you can access the HTTP
30
- # client instance represented by your adapter in a block.
31
- #
32
- # HTTPI.get request do |http|
33
- # http.follow_redirect_count = 3 # HTTPClient example
34
- # end
74
+ # Executes an HTTP GET request.
35
75
  def get(request, adapter = nil)
36
76
  request = Request.new :url => request if request.kind_of? String
37
77
 
@@ -41,35 +81,9 @@ module HTTPI
41
81
  end
42
82
  end
43
83
 
44
- # Executes an HTTP POST request and returns an <tt>HTTPI::Response</tt>.
45
- #
46
- # ==== Example
47
- #
48
- # Accepts an <tt>HTTPI::Request</tt> and an optional adapter:
49
- #
50
- # request = HTTPI::Request.new
51
- # request.url = "http://example.com"
52
- # request.body = "<some>xml</some>"
53
- #
54
- # HTTPI.post request, :httpclient
55
- #
56
- # ==== Shortcut
57
- #
58
- # You can also just pass a URL, a request body and an optional adapter
59
- # if you don't need to configure the request:
60
- #
61
- # HTTPI.post "http://example.com", "<some>xml</some>", :curb
62
- #
63
- # ==== More control
64
- #
65
- # If you need more control over the request, you can access the HTTP
66
- # client instance represented by your adapter in a block.
67
- #
68
- # HTTPI.post request do |http|
69
- # http.use_ssl = true # Curb example
70
- # end
84
+ # Executes an HTTP POST request.
71
85
  def post(*args)
72
- request, adapter = extract_post_args(args)
86
+ request, adapter = request_and_adapter_from(args)
73
87
 
74
88
  with adapter do |adapter|
75
89
  yield adapter.client if block_given?
@@ -77,12 +91,42 @@ module HTTPI
77
91
  end
78
92
  end
79
93
 
80
- private
94
+ # Executes an HTTP HEAD request.
95
+ def head(request, adapter = nil)
96
+ request = Request.new :url => request if request.kind_of? String
97
+
98
+ with adapter do |adapter|
99
+ yield adapter.client if block_given?
100
+ adapter.head request
101
+ end
102
+ end
103
+
104
+ # Executes an HTTP PUT request.
105
+ def put(*args)
106
+ request, adapter = request_and_adapter_from(args)
107
+
108
+ with adapter do |adapter|
109
+ yield adapter.client if block_given?
110
+ adapter.put request
111
+ end
112
+ end
113
+
114
+ # Executes an HTTP DELETE request.
115
+ def delete(request, adapter = nil)
116
+ request = Request.new :url => request if request.kind_of? String
117
+
118
+ with adapter do |adapter|
119
+ yield adapter.client if block_given?
120
+ adapter.delete request
121
+ end
122
+ end
123
+
124
+ private
81
125
 
82
126
  # Checks whether +args+ contains of an <tt>HTTPI::Request</tt> or a URL
83
127
  # and a request body plus an optional adapter and returns an Array with
84
128
  # an <tt>HTTPI::Request</tt> and (if given) an adapter.
85
- def extract_post_args(args)
129
+ def request_and_adapter_from(args)
86
130
  return args if args[0].kind_of? Request
87
131
  [Request.new(:url => args[0], :body => args[1]), args[2]]
88
132
  end
@@ -9,39 +9,60 @@ module HTTPI
9
9
  # http://rubygems.org/gems/curb
10
10
  class Curb
11
11
 
12
+ # Requires the "curb" gem.
12
13
  def initialize
13
14
  require "curb"
14
15
  end
15
16
 
17
+ # Returns a memoized <tt>Curl::Easy</tt> instance.
16
18
  def client
17
19
  @client ||= Curl::Easy.new
18
20
  end
19
21
 
22
+ # Executes an HTTP GET request.
23
+ # @see HTTPI.get
20
24
  def get(request)
21
- get_request(request) { |client| client.http_get }
25
+ do_request(request) { |client| client.http_get }
22
26
  end
23
27
 
28
+ # Executes an HTTP POST request.
29
+ # @see HTTPI.post
24
30
  def post(request)
25
- post_request(request) { |client, body| client.http_post body }
31
+ do_request(request) { |client, body| client.http_post body }
32
+ end
33
+
34
+ # Executes an HTTP HEAD request.
35
+ # @see HTTPI.head
36
+ def head(request)
37
+ do_request(request) { |client| client.http_head }
38
+ end
39
+
40
+ # Executes an HTTP PUT request.
41
+ # @see HTTPI.put
42
+ def put(request)
43
+ do_request(request) { |client, body| client.http_put body }
44
+ end
45
+
46
+ # Executes an HTTP DELETE request.
47
+ # @see HTTPI.delete
48
+ def delete(request)
49
+ do_request(request) { |client| client.http_delete }
26
50
  end
27
51
 
28
52
  private
29
53
 
30
- def get_request(request)
54
+ def do_request(request)
31
55
  setup_client request
32
56
  yield client
33
57
  respond_with client
34
58
  end
35
59
 
36
- def post_request(request)
37
- request.url.query = nil if request.url.query == "wsdl"
38
-
39
- setup_client request
40
- yield client, request.body
41
- respond_with client
60
+ def setup_client(request)
61
+ basic_setup request
62
+ setup_auth request if request.auth?
42
63
  end
43
64
 
44
- def setup_client(request)
65
+ def basic_setup(request)
45
66
  client.url = request.url.to_s
46
67
  client.timeout = request.read_timeout
47
68
  client.connect_timeout = request.open_timeout
@@ -49,6 +70,11 @@ module HTTPI
49
70
  client.verbose = false
50
71
  end
51
72
 
73
+ def setup_auth(request)
74
+ client.http_auth_types = request.auth_type
75
+ client.username, client.password = *request.credentials
76
+ end
77
+
52
78
  def respond_with(client)
53
79
  Response.new client.response_code, client.headers, client.body_str
54
80
  end
@@ -9,44 +9,77 @@ module HTTPI
9
9
  # http://rubygems.org/gems/httpclient
10
10
  class HTTPClient
11
11
 
12
+ # Requires the "httpclient" gem.
12
13
  def initialize
13
14
  require "httpclient"
14
15
  end
15
16
 
17
+ # Returns a memoized <tt>HTTPClient</tt> instance.
16
18
  def client
17
19
  @client ||= ::HTTPClient.new
18
20
  end
19
21
 
22
+ # Executes an HTTP GET request.
23
+ # @see HTTPI.get
20
24
  def get(request)
21
- get_request request do |client, url, headers|
25
+ do_request request do |client, url, headers|
22
26
  client.get url, nil, headers
23
27
  end
24
28
  end
25
29
 
30
+ # Executes an HTTP POST request.
31
+ # @see HTTPI.post
26
32
  def post(request)
27
- post_request request do |client, url, headers, body|
33
+ do_request request do |client, url, headers, body|
28
34
  client.post url, body, headers
29
35
  end
30
36
  end
31
37
 
32
- private
38
+ # Executes an HTTP HEAD request.
39
+ # @see HTTPI.head
40
+ def head(request)
41
+ do_request request do |client, url, headers|
42
+ client.head url, nil, headers
43
+ end
44
+ end
33
45
 
34
- def get_request(request)
35
- setup_client request
36
- respond_with yield(client, request.url, request.headers)
46
+ # Executes an HTTP PUT request.
47
+ # @see HTTPI.put
48
+ def put(request)
49
+ do_request request do |client, url, headers, body|
50
+ client.put url, body, headers
51
+ end
37
52
  end
38
53
 
39
- def post_request(request)
54
+ # Executes an HTTP DELETE request.
55
+ # @see HTTPI.delete
56
+ def delete(request)
57
+ do_request request do |client, url, headers|
58
+ client.delete url, headers
59
+ end
60
+ end
61
+ private
62
+
63
+ def do_request(request)
40
64
  setup_client request
41
65
  respond_with yield(client, request.url, request.headers, request.body)
42
66
  end
43
67
 
44
68
  def setup_client(request)
69
+ basic_setup request
70
+ auth_setup request if request.auth?
71
+ end
72
+
73
+ def basic_setup(request)
45
74
  client.proxy = request.proxy if request.proxy
46
75
  client.connect_timeout = request.open_timeout
47
76
  client.receive_timeout = request.read_timeout
48
77
  end
49
78
 
79
+ def auth_setup(request)
80
+ client.set_auth request.url.to_s, *request.credentials
81
+ end
82
+
50
83
  def respond_with(response)
51
84
  Response.new response.code, Hash[response.header.all], response.content
52
85
  end
data/lib/httpi/request.rb CHANGED
@@ -11,7 +11,7 @@ module HTTPI
11
11
  ACCESSORS = [:url, :proxy, :headers, :body, :open_timeout, :read_timeout]
12
12
 
13
13
  # Request authentication methods.
14
- AUTHENTICATION = [:basic_auth]
14
+ AUTHENTICATION = [:basic_auth, :digest_auth]
15
15
 
16
16
  # Accepts a Hash of +options+ which may contain any number of ACCESSORS and/or
17
17
  # AUTHENTICATION credentials to set.
@@ -44,15 +44,36 @@ module HTTPI
44
44
  # Sets the Hash of HTTP headers.
45
45
  attr_writer :headers
46
46
 
47
- attr_accessor :body, :open_timeout, :read_timeout
47
+ attr_accessor :body, :open_timeout, :read_timeout, :auth_type
48
+
49
+ # Returns whether any authentication credentials were specified.
50
+ def auth?
51
+ !!auth_type
52
+ end
53
+
54
+ # Shortcut method for returning the credentials for the authentication specified.
55
+ # Return +nil+ unless any authentication credentials were specified.
56
+ def credentials
57
+ return unless auth?
58
+ send "#{auth_type}_auth"
59
+ end
48
60
 
49
61
  # Sets the HTTP basic auth credentials. Accepts an Array or two arguments for the
50
62
  # +username+ and +password+. Resets the credentials when +nil+ is passed and returns
51
63
  # an Array of credentials when no +args+ where given.
52
64
  def basic_auth(*args)
65
+ self.auth_type = :basic
53
66
  @basic_auth = extract_credentials @basic_auth, args.flatten
54
67
  end
55
68
 
69
+ # Sets the HTTP digest auth credentials. Accepts an Array or two arguments for the
70
+ # +username+ and +password+. Resets the credentials when +nil+ is passed and returns
71
+ # an Array of credentials when no +args+ where given.
72
+ def digest_auth(*args)
73
+ self.auth_type = :digest
74
+ @digest_auth = extract_credentials @digest_auth, args.flatten
75
+ end
76
+
56
77
  private
57
78
 
58
79
  def assign_accessors(options)
data/lib/httpi/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  module HTTPI
2
2
 
3
- VERSION = "0.3.0"
3
+ VERSION = "0.4.0"
4
4
 
5
5
  end
@@ -6,6 +6,7 @@ require "curb"
6
6
 
7
7
  describe HTTPI::Adapter::Curb do
8
8
  let(:adapter) { HTTPI::Adapter::Curb.new }
9
+ let(:curb) { Curl::Easy.any_instance }
9
10
 
10
11
  describe ".new" do
11
12
  it "should require the Curb gem" do
@@ -42,8 +43,46 @@ describe HTTPI::Adapter::Curb do
42
43
  end
43
44
  end
44
45
 
45
- def curb
46
- Curl::Easy.any_instance
46
+ describe "#head" do
47
+ before do
48
+ curb.expects(:http_head)
49
+ curb.expects(:response_code).returns(200)
50
+ curb.expects(:headers).returns(Hash.new)
51
+ curb.expects(:body_str).returns(Fixture.xml)
52
+ end
53
+
54
+ it "should return a valid HTTPI::Response" do
55
+ request = HTTPI::Request.new :url => "http://example.com"
56
+ adapter.head(request).should be_a_valid_httpi_response
57
+ end
58
+ end
59
+
60
+ describe "#put" do
61
+ before do
62
+ curb.expects(:http_put)
63
+ curb.expects(:response_code).returns(200)
64
+ curb.expects(:headers).returns(Hash.new)
65
+ curb.expects(:body_str).returns(Fixture.xml)
66
+ end
67
+
68
+ it "should return a valid HTTPI::Response" do
69
+ request = HTTPI::Request.new :url => "http://example.com"
70
+ adapter.put(request).should be_a_valid_httpi_response
71
+ end
72
+ end
73
+
74
+ describe "#delete" do
75
+ before do
76
+ curb.expects(:http_delete)
77
+ curb.expects(:response_code).returns(200)
78
+ curb.expects(:headers).returns(Hash.new)
79
+ curb.expects(:body_str).returns("")
80
+ end
81
+
82
+ it "should return a valid HTTPI::Response" do
83
+ request = HTTPI::Request.new :url => "http://example.com"
84
+ adapter.delete(request).should be_a_valid_httpi_response
85
+ end
47
86
  end
48
87
 
49
88
  end
@@ -6,6 +6,7 @@ require "httpclient"
6
6
 
7
7
  describe HTTPI::Adapter::HTTPClient do
8
8
  let(:adapter) { HTTPI::Adapter::HTTPClient.new }
9
+ let(:httpclient) { HTTPClient.any_instance }
9
10
 
10
11
  describe ".new" do
11
12
  it "should require the HTTPClient gem" do
@@ -38,8 +39,40 @@ describe HTTPI::Adapter::HTTPClient do
38
39
  end
39
40
  end
40
41
 
41
- def httpclient
42
- HTTPClient.any_instance
42
+ describe "#head" do
43
+ before do
44
+ @request = HTTPI::Request.new :url => "http://example.com"
45
+ response = HTTP::Message.new_response Fixture.xml
46
+ httpclient.expects(:head).with(@request.url, nil, @request.headers).returns(response)
47
+ end
48
+
49
+ it "should return a valid HTTPI::Response" do
50
+ adapter.head(@request).should be_a_valid_httpi_response
51
+ end
52
+ end
53
+
54
+ describe "#put" do
55
+ before do
56
+ @request = HTTPI::Request.new :url => "http://example.com", :body => Fixture.xml
57
+ response = HTTP::Message.new_response Fixture.xml
58
+ httpclient.expects(:put).with(@request.url, @request.body, @request.headers).returns(response)
59
+ end
60
+
61
+ it "should return a valid HTTPI::Response" do
62
+ adapter.put(@request).should be_a_valid_httpi_response
63
+ end
64
+ end
65
+
66
+ describe "#delete" do
67
+ before do
68
+ @request = HTTPI::Request.new :url => "http://example.com"
69
+ response = HTTP::Message.new_response ""
70
+ httpclient.expects(:delete).with(@request.url, nil, @request.headers).returns(response)
71
+ end
72
+
73
+ it "should return a valid HTTPI::Response" do
74
+ adapter.delete(@request).should be_a_valid_httpi_response
75
+ end
43
76
  end
44
77
 
45
78
  end
@@ -1,6 +1,9 @@
1
1
  require "spec_helper"
2
2
  require "httpi"
3
3
 
4
+ require "httpclient"
5
+ require "curb"
6
+
4
7
  describe HTTPI do
5
8
  let(:client) { HTTPI }
6
9
  let(:default_adapter) { HTTPI::Adapter.find HTTPI::Adapter.use }
@@ -41,25 +44,29 @@ describe HTTPI do
41
44
  client.get "http://example.com", :curb
42
45
  end
43
46
  end
44
-
45
- describe ".get" do
47
+
48
+ shared_examples_for "a request method" do
46
49
  context "(with a block)" do
47
50
  it "should yield the HTTP client instance used for the request" do
48
- client.get "http://example.com" do |http|
51
+ client.delete "http://example.com" do |http|
49
52
  http.should be_an(HTTPClient)
50
53
  end
51
54
  end
52
55
  end
53
56
 
54
- it "should raise an ArgumentError in case of an invalid adapter" do
55
- lambda { client.get HTTPI::Request.new, :invalid }.should raise_error(ArgumentError)
57
+ it "and raise an ArgumentError in case of an invalid adapter" do
58
+ lambda { client.delete HTTPI::Request.new, :invalid }.should raise_error(ArgumentError)
56
59
  end
57
60
 
58
- it "should raise an ArgumentError in case of an invalid URL" do
59
- lambda { client.get "invalid" }.should raise_error(ArgumentError)
61
+ it "and raise an ArgumentError in case of an invalid URL" do
62
+ lambda { client.delete "invalid" }.should raise_error(ArgumentError)
60
63
  end
61
64
  end
62
65
 
66
+ describe ".get" do
67
+ it_should_behave_like "a request method"
68
+ end
69
+
63
70
  describe ".post(request)" do
64
71
  it "should execute an HTTP POST request using the default adapter" do
65
72
  request = HTTPI::Request.new
@@ -99,21 +106,129 @@ describe HTTPI do
99
106
  end
100
107
 
101
108
  describe ".post" do
102
- context "(with a block)" do
103
- it "should yield the HTTP client instance used for the request" do
104
- client.get "http://example.com", :curb do |http|
105
- http.should be_a(Curl::Easy)
106
- end
107
- end
109
+ it_should_behave_like "a request method"
110
+ end
111
+
112
+ describe ".head(request)" do
113
+ it "should execute an HTTP HEAD request using the default adapter" do
114
+ request = HTTPI::Request.new
115
+ default_adapter.any_instance.expects(:head).with(request)
116
+
117
+ client.head request
118
+ end
119
+ end
120
+
121
+ describe ".head(request, adapter)" do
122
+ it "should execute an HTTP HEAD request using the given adapter" do
123
+ request = HTTPI::Request.new
124
+ curb.any_instance.expects(:head).with(request)
125
+
126
+ client.head request, :curb
127
+ end
128
+ end
129
+
130
+ describe ".head(url)" do
131
+ it "should execute an HTTP HEAD request using the default adapter" do
132
+ HTTPI::Request.any_instance.expects(:url=).with("http://example.com")
133
+ default_adapter.any_instance.expects(:head).with(instance_of(HTTPI::Request))
134
+
135
+ client.head "http://example.com"
136
+ end
137
+ end
138
+
139
+ describe ".head(url, adapter)" do
140
+ it "should execute an HTTP HEAD request using the given adapter" do
141
+ HTTPI::Request.any_instance.expects(:url=).with("http://example.com")
142
+ curb.any_instance.expects(:head).with(instance_of(HTTPI::Request))
143
+
144
+ client.head "http://example.com", :curb
145
+ end
146
+ end
147
+
148
+ describe ".head" do
149
+ it_should_behave_like "a request method"
150
+ end
151
+
152
+ describe ".put(request)" do
153
+ it "should execute an HTTP PUT request using the default adapter" do
154
+ request = HTTPI::Request.new
155
+ default_adapter.any_instance.expects(:put).with(request)
156
+
157
+ client.put request
108
158
  end
159
+ end
109
160
 
110
- it "should raise an ArgumentError in case of an invalid adapter" do
111
- lambda { client.post HTTPI::Request.new, :invalid }.should raise_error(ArgumentError)
161
+ describe ".put(request, adapter)" do
162
+ it "should execute an HTTP PUT request using the given adapter" do
163
+ request = HTTPI::Request.new
164
+ curb.any_instance.expects(:put).with(request)
165
+
166
+ client.put request, :curb
112
167
  end
168
+ end
113
169
 
114
- it "should raise an ArgumentError in case of an invalid URL" do
115
- lambda { client.post "invalid" }.should raise_error(ArgumentError)
170
+ describe ".put(url, body)" do
171
+ it "should execute an HTTP PUT request using the default adapter" do
172
+ HTTPI::Request.any_instance.expects(:url=).with("http://example.com")
173
+ HTTPI::Request.any_instance.expects(:body=).with("<some>xml</some>")
174
+ default_adapter.any_instance.expects(:put).with(instance_of(HTTPI::Request))
175
+
176
+ client.put "http://example.com", "<some>xml</some>"
116
177
  end
117
178
  end
118
179
 
180
+ describe ".put(url, body, adapter)" do
181
+ it "should execute an HTTP PUT request using the given adapter" do
182
+ HTTPI::Request.any_instance.expects(:url=).with("http://example.com")
183
+ HTTPI::Request.any_instance.expects(:body=).with("<some>xml</some>")
184
+ curb.any_instance.expects(:put).with(instance_of(HTTPI::Request))
185
+
186
+ client.put "http://example.com", "<some>xml</some>", :curb
187
+ end
188
+ end
189
+
190
+ describe ".put" do
191
+ it_should_behave_like "a request method"
192
+ end
193
+
194
+ describe ".delete(request)" do
195
+ it "should execute an HTTP DELETE request using the default adapter" do
196
+ request = HTTPI::Request.new
197
+ default_adapter.any_instance.expects(:delete).with(request)
198
+
199
+ client.delete request
200
+ end
201
+ end
202
+
203
+ describe ".delete(request, adapter)" do
204
+ it "should execute an HTTP DELETE request using the given adapter" do
205
+ request = HTTPI::Request.new
206
+ curb.any_instance.expects(:delete).with(request)
207
+
208
+ client.delete request, :curb
209
+ end
210
+ end
211
+
212
+ describe ".delete(url)" do
213
+ it "should execute an HTTP DELETE request using the default adapter" do
214
+ HTTPI::Request.any_instance.expects(:url=).with("http://example.com")
215
+ default_adapter.any_instance.expects(:delete).with(instance_of(HTTPI::Request))
216
+
217
+ client.delete "http://example.com"
218
+ end
219
+ end
220
+
221
+ describe ".delete(url, adapter)" do
222
+ it "should execute an HTTP DELETE request using the given adapter" do
223
+ HTTPI::Request.any_instance.expects(:url=).with("http://example.com")
224
+ curb.any_instance.expects(:delete).with(instance_of(HTTPI::Request))
225
+
226
+ client.delete "http://example.com", :curb
227
+ end
228
+ end
229
+
230
+ describe ".delete" do
231
+ it_should_behave_like "a request method"
232
+ end
233
+
119
234
  end
@@ -99,6 +99,65 @@ describe HTTPI::Request do
99
99
  request.basic_auth nil
100
100
  request.basic_auth.should be_nil
101
101
  end
102
- end
102
+ end
103
+
104
+ describe "#digest_auth" do
105
+ it "lets you specify the digest auth credentials" do
106
+ request.digest_auth "username", "password"
107
+ request.digest_auth.should == ["username", "password"]
108
+ end
109
+
110
+ it "also accepts an Array of credentials" do
111
+ request.digest_auth ["username", "password"]
112
+ request.digest_auth.should == ["username", "password"]
113
+ end
114
+
115
+ it "lets you reset the credentials" do
116
+ request.digest_auth "username", "password"
117
+ request.digest_auth.should == ["username", "password"]
103
118
 
119
+ request.digest_auth nil
120
+ request.digest_auth.should be_nil
121
+ end
122
+ end
123
+
124
+ describe "#auth?" do
125
+ it "should return false unless any authentication credentials were specified" do
126
+ request.auth?.should be_false
127
+ end
128
+
129
+ it "should return true if HTTP basic auth authentication credentials were specified" do
130
+ request.basic_auth "username", "password"
131
+ request.auth?.should be_true
132
+ end
133
+
134
+ it "should return true if HTTP digest auth authentication credentials were specified" do
135
+ request.digest_auth "username", "password"
136
+ request.auth?.should be_true
137
+ end
138
+ end
139
+
140
+ describe "#credentials" do
141
+ it "return the credentials for HTTP basic auth" do
142
+ request.basic_auth "username", "basic"
143
+ request.credentials.should == ["username", "basic"]
144
+ end
145
+
146
+ it "return the credentials for HTTP digest auth" do
147
+ request.digest_auth "username", "digest"
148
+ request.credentials.should == ["username", "digest"]
149
+ end
150
+ end
151
+
152
+ describe "#auth_type" do
153
+ it "should return :basic for HTTP basic auth" do
154
+ request.basic_auth "username", "password"
155
+ request.auth_type.should == :basic
156
+ end
157
+
158
+ it "should return :digest for HTTP basic auth" do
159
+ request.digest_auth "username", "password"
160
+ request.auth_type.should == :digest
161
+ end
162
+ end
104
163
  end
@@ -0,0 +1,68 @@
1
+ require "spec_helper"
2
+ require "httpi"
3
+
4
+ describe HTTPI do
5
+ let(:client) { HTTPI }
6
+
7
+ # Uses example.com for basic request methods and webdav.org
8
+ # for HTTP basic and digest authentication.
9
+ #
10
+ # http://example.com
11
+ # http://test.webdav.org
12
+
13
+ before :all do
14
+ @username = @password = "user1"
15
+ @error_message = "Authorization Required"
16
+ @example_web_page = "Example Web Page"
17
+ end
18
+
19
+ HTTPI::Adapter.adapters.keys.each do |adapter|
20
+ context "using :#{adapter}" do
21
+ it "should execute an HTTP GET request" do
22
+ response = HTTPI.get "http://example.com", adapter
23
+ response.body.should include(@example_web_page)
24
+ end
25
+
26
+ it "should execute an HTTP POST request" do
27
+ response = HTTPI.post "http://example.com", "<some>xml</some>", adapter
28
+ response.body.should include(@example_web_page)
29
+ end
30
+
31
+ it "should execute an HTTP HEAD request" do
32
+ response = HTTPI.head "http://example.com", adapter
33
+ response.code.should == 200
34
+ end
35
+
36
+ it "should execute an HTTP PUT request" do
37
+ response = HTTPI.put "http://example.com", "<some>xml</some>", adapter
38
+ response.body.should include("PUT is not allowed")
39
+ end
40
+
41
+ it "should execute an HTTP DELETE request" do
42
+ response = HTTPI.delete "http://example.com", adapter
43
+ response.body.should include("DELETE is not allowed")
44
+ end
45
+
46
+ context "with HTTP basic authentication" do
47
+ it "requires a username and password" do
48
+ request = HTTPI::Request.new :url => "http://test.webdav.org/auth-basic/"
49
+ request.basic_auth @username, @password
50
+
51
+ response = HTTPI.get request, adapter
52
+ response.body.should_not include(@error_message)
53
+ end
54
+ end
55
+
56
+ context "with HTTP digest authentication" do
57
+ it "requires a username and password" do
58
+ request = HTTPI::Request.new :url => "http://test.webdav.org/auth-digest/"
59
+ request.digest_auth @username, @password
60
+
61
+ response = HTTPI.get request, adapter
62
+ response.body.should_not include(@error_message)
63
+ end
64
+ end
65
+ end
66
+ end
67
+
68
+ end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: httpi
3
3
  version: !ruby/object:Gem::Version
4
- hash: 19
4
+ hash: 15
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
- - 3
8
+ - 4
9
9
  - 0
10
- version: 0.3.0
10
+ version: 0.4.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - Daniel Harrington
@@ -16,7 +16,7 @@ autorequire:
16
16
  bindir: bin
17
17
  cert_chain: []
18
18
 
19
- date: 2010-09-24 00:00:00 +02:00
19
+ date: 2010-09-25 00:00:00 +02:00
20
20
  default_executable:
21
21
  dependencies:
22
22
  - !ruby/object:Gem::Dependency
@@ -96,8 +96,10 @@ extra_rdoc_files: []
96
96
  files:
97
97
  - Gemfile
98
98
  - Gemfile.lock
99
+ - LICENSE
99
100
  - Rakefile
100
101
  - README.md
102
+ - .autotest
101
103
  - .rspec
102
104
  - autotest/discover.rb
103
105
  - lib/httpi/adapter/curb.rb
@@ -115,6 +117,7 @@ files:
115
117
  - spec/httpi/httpi_spec.rb
116
118
  - spec/httpi/request_spec.rb
117
119
  - spec/httpi/response_spec.rb
120
+ - spec/integration/request_spec.rb
118
121
  - spec/spec_helper.rb
119
122
  - spec/support/fixture.rb
120
123
  - spec/support/matchers.rb