hugs 1.1.0 → 1.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/README.md +5 -4
- data/VERSION +1 -1
- data/hugs.gemspec +1 -2
- data/lib/hugs.rb +31 -17
- data/test/support.rb +0 -2
- data/test/test_hugs.rb +35 -26
- metadata +2 -3
- data/.bundle/config +0 -2
data/README.md
CHANGED
@@ -2,19 +2,21 @@
|
|
2
2
|
|
3
3
|
Hugs net-http-persistent with convenient get, delete, post, and put methods.
|
4
4
|
|
5
|
-
Opted to write this gem for
|
5
|
+
Opted to write this gem for four reasons:
|
6
6
|
|
7
7
|
* [Ganeti's API](http://docs.ganeti.org/ganeti/2.2/html/rapi.html), required
|
8
8
|
the sending of a message body with the HTTP Get request, which
|
9
9
|
[rest-client](https://github.com/archiloque/rest-client) does not do.
|
10
10
|
* Wanted a [fast](http://blog.segment7.net/articles/2010/05/07/net-http-is-not-slow),
|
11
11
|
thread-safe, and persistent client.
|
12
|
+
* [Excon](https://github.com/geemus/excon) does most everything right, but is not
|
13
|
+
compatible with [VCR](https://github.com/myronmarston/vcr).
|
14
|
+
* Wanted to learn how to handle this pattern.
|
12
15
|
|
13
16
|
## Assumptions
|
14
17
|
|
15
|
-
* The webservice returns JSON.
|
18
|
+
* The webservice returns JSON or XML.
|
16
19
|
* You want to objectify the returned JSON.
|
17
|
-
* The message body is JSON.
|
18
20
|
|
19
21
|
## Usage
|
20
22
|
|
@@ -28,6 +30,5 @@ See the 'Examples' section in the [wiki](http://github.com/retr0h/rubineti/wiki/
|
|
28
30
|
|
29
31
|
### TODO
|
30
32
|
|
31
|
-
* Remove HTTP Auth requirement, as mentioned in the 'Assumptions' section.
|
32
33
|
* Move @request instance method in #response_for to local. It was set to an instance
|
33
34
|
for ease of testing but it bothers me.
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.
|
1
|
+
1.2.0
|
data/hugs.gemspec
CHANGED
@@ -5,7 +5,7 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{hugs}
|
8
|
-
s.version = "1.
|
8
|
+
s.version = "1.2.0"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["retr0h"]
|
@@ -16,7 +16,6 @@ Gem::Specification.new do |s|
|
|
16
16
|
"README.md"
|
17
17
|
]
|
18
18
|
s.files = [
|
19
|
-
".bundle/config",
|
20
19
|
".rvmrc",
|
21
20
|
"Gemfile",
|
22
21
|
"Gemfile.lock",
|
data/lib/hugs.rb
CHANGED
@@ -3,7 +3,8 @@ require "yajl"
|
|
3
3
|
|
4
4
|
class Hugs
|
5
5
|
Headers = {
|
6
|
-
:json => "application/json"
|
6
|
+
:json => "application/json",
|
7
|
+
:xml => "application/xml",
|
7
8
|
}.freeze
|
8
9
|
|
9
10
|
##
|
@@ -16,11 +17,12 @@ class Hugs
|
|
16
17
|
# +scheme+: A String containing the HTTP scheme.
|
17
18
|
|
18
19
|
def initialize options
|
19
|
-
@user
|
20
|
-
@password
|
21
|
-
@host
|
22
|
-
@port
|
23
|
-
@scheme
|
20
|
+
@user = options[:user]
|
21
|
+
@password = options[:password]
|
22
|
+
@host = options[:host]
|
23
|
+
@port = options[:port] || 80
|
24
|
+
@scheme = options[:scheme] || "https"
|
25
|
+
@type = options[:type] || :json
|
24
26
|
end
|
25
27
|
|
26
28
|
##
|
@@ -35,7 +37,7 @@ class Hugs
|
|
35
37
|
define_method verb do |*args|
|
36
38
|
path = args[0]
|
37
39
|
params = args[1] || {}
|
38
|
-
clazz = eval "Net::HTTP::#{verb.capitalize}"
|
40
|
+
clazz = eval "::Net::HTTP::#{verb.capitalize}"
|
39
41
|
|
40
42
|
parse response_for(clazz, path, params)
|
41
43
|
end
|
@@ -62,8 +64,8 @@ private
|
|
62
64
|
query = params[:query] && params.delete(:query)
|
63
65
|
body = params[:body] && params.delete(:body)
|
64
66
|
|
65
|
-
@http ||= Net::HTTP::Persistent.new
|
66
|
-
@url ||= URI.parse "#{@scheme}://#{@host}:#{@port}"
|
67
|
+
@http ||= ::Net::HTTP::Persistent.new
|
68
|
+
@url ||= ::URI.parse "#{@scheme}://#{@host}:#{@port}"
|
67
69
|
|
68
70
|
@request = request.new [path, query].compact.join "?"
|
69
71
|
@request.body = encode(body) if body
|
@@ -73,21 +75,33 @@ private
|
|
73
75
|
end
|
74
76
|
|
75
77
|
def common_headers request
|
76
|
-
request.basic_auth(@user, @password) if
|
78
|
+
request.basic_auth(@user, @password) if requires_authentication?
|
77
79
|
case request.class.to_s
|
78
|
-
when Net::HTTP::Get.to_s, Net::HTTP::Delete.to_s
|
79
|
-
request.add_field "accept", Headers[
|
80
|
-
when Net::HTTP::Post.to_s, Net::HTTP::Put.to_s
|
81
|
-
request.add_field "accept", Headers[
|
82
|
-
request.add_field "content-type", Headers[
|
80
|
+
when ::Net::HTTP::Get.to_s, ::Net::HTTP::Delete.to_s
|
81
|
+
request.add_field "accept", Headers[@type]
|
82
|
+
when ::Net::HTTP::Post.to_s, ::Net::HTTP::Put.to_s
|
83
|
+
request.add_field "accept", Headers[@type]
|
84
|
+
request.add_field "content-type", Headers[@type]
|
83
85
|
end
|
84
86
|
end
|
85
87
|
|
86
88
|
def parse data
|
87
|
-
::Yajl::Parser.parse data
|
89
|
+
::Yajl::Parser.parse data if is_json?
|
88
90
|
end
|
89
91
|
|
90
92
|
def encode hash
|
91
|
-
::Yajl::Encoder.encode hash
|
93
|
+
::Yajl::Encoder.encode hash if is_json?
|
94
|
+
end
|
95
|
+
|
96
|
+
def requires_authentication?
|
97
|
+
@user && @password
|
98
|
+
end
|
99
|
+
|
100
|
+
def is_xml?
|
101
|
+
@type == :xml
|
102
|
+
end
|
103
|
+
|
104
|
+
def is_json?
|
105
|
+
@type == :json
|
92
106
|
end
|
93
107
|
end
|
data/test/support.rb
CHANGED
data/test/test_hugs.rb
CHANGED
@@ -14,15 +14,15 @@ describe Hugs do
|
|
14
14
|
:scheme => "https",
|
15
15
|
}
|
16
16
|
|
17
|
-
@instance = Hugs.new @valid_options
|
17
|
+
@instance = ::Hugs.new @valid_options
|
18
18
|
end
|
19
19
|
|
20
20
|
describe "#response_for" do
|
21
21
|
before do
|
22
22
|
@http = mock(:request => mock(:body => :body))
|
23
|
-
@request = Net::HTTP::Get
|
23
|
+
@request = ::Net::HTTP::Get
|
24
24
|
|
25
|
-
Net::HTTP::Persistent.stubs :new => @http
|
25
|
+
::Net::HTTP::Persistent.stubs :new => @http
|
26
26
|
end
|
27
27
|
|
28
28
|
it "generates a path" do
|
@@ -56,19 +56,17 @@ describe Hugs do
|
|
56
56
|
end
|
57
57
|
|
58
58
|
describe "headers" do
|
59
|
-
Json_Headers_Matcher = %r{#{"application/json"}}
|
60
|
-
|
61
59
|
it "has authentication" do
|
62
60
|
@instance.send :response_for, @request, "/", {}
|
63
61
|
|
64
62
|
@instance.instance_variable_get(:@request).get_fields("authorization").join.
|
65
|
-
must_match %r{Basic #{Base64.encode64("#{@user}:#{@password}").delete("\r\n")}}
|
63
|
+
must_match %r{Basic #{::Base64.encode64("#{@user}:#{@password}").delete("\r\n")}}
|
66
64
|
end
|
67
65
|
|
68
66
|
[:user, :password].each do |option|
|
69
67
|
it "doesn't authenticate when '#{option}' missing" do
|
70
68
|
invalid_options = @valid_options.reject { |k,v| k == option }
|
71
|
-
@instance = Hugs.new invalid_options
|
69
|
+
@instance = ::Hugs.new invalid_options
|
72
70
|
|
73
71
|
@instance.send :response_for, @request, "/", {}
|
74
72
|
|
@@ -76,25 +74,36 @@ describe Hugs do
|
|
76
74
|
end
|
77
75
|
end
|
78
76
|
|
79
|
-
[
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
77
|
+
[
|
78
|
+
{ :json => "application/json" },
|
79
|
+
{ :xml => "application/xml" },
|
80
|
+
].each do |pair|
|
81
|
+
pair.each_pair do |type, subtype|
|
82
|
+
[::Net::HTTP::Post, ::Net::HTTP::Put].each do |clazz|
|
83
|
+
it "has '#{subtype}' content-type and accept for '#{clazz}'" do
|
84
|
+
@instance = ::Hugs.new @valid_options.merge(:type => type)
|
85
|
+
|
86
|
+
@instance.send :response_for, clazz, "/", {}
|
87
|
+
|
88
|
+
@instance.instance_variable_get(:@request).get_fields("content-type").join.
|
89
|
+
must_match %r{#{subtype}}
|
90
|
+
@instance.instance_variable_get(:@request).get_fields("accept").join.
|
91
|
+
must_match %r{#{subtype}}
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
[::Net::HTTP::Get, ::Net::HTTP::Delete].each do |clazz|
|
96
|
+
it "has '#{subtype}' accept for '#{clazz}'" do
|
97
|
+
@instance = ::Hugs.new @valid_options.merge(:type => type)
|
98
|
+
|
99
|
+
@instance.send :response_for, clazz, "/", {}
|
100
|
+
|
101
|
+
@instance.instance_variable_get(:@request).get_fields("accept").join.
|
102
|
+
must_match %r{#{subtype}}
|
103
|
+
@instance.instance_variable_get(:@request).get_fields("content-type").
|
104
|
+
must_be_nil
|
105
|
+
end
|
106
|
+
end
|
98
107
|
end
|
99
108
|
end
|
100
109
|
end
|
metadata
CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
|
|
4
4
|
prerelease: false
|
5
5
|
segments:
|
6
6
|
- 1
|
7
|
-
-
|
7
|
+
- 2
|
8
8
|
- 0
|
9
|
-
version: 1.
|
9
|
+
version: 1.2.0
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- retr0h
|
@@ -115,7 +115,6 @@ extra_rdoc_files:
|
|
115
115
|
- LICENSE
|
116
116
|
- README.md
|
117
117
|
files:
|
118
|
-
- .bundle/config
|
119
118
|
- .rvmrc
|
120
119
|
- Gemfile
|
121
120
|
- Gemfile.lock
|
data/.bundle/config
DELETED