httparty 0.7.2 → 0.7.3
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of httparty might be problematic. Click here for more details.
- data/History +8 -0
- data/httparty.gemspec +4 -3
- data/lib/httparty.rb +1 -1
- data/lib/httparty/net_digest_auth.rb +63 -27
- data/spec/httparty/net_digest_auth_spec.rb +93 -0
- metadata +10 -7
data/History
CHANGED
@@ -1,3 +1,11 @@
|
|
1
|
+
== 0.7.3 2011-01-20
|
2
|
+
* bug fixes
|
3
|
+
* Fix digest auth for unspecified quality of protection (bjoernalbers, mtrudel, dwo)
|
4
|
+
|
5
|
+
== 0.7.2 2011-01-20
|
6
|
+
* bug fixes
|
7
|
+
* Fix gem dependencies
|
8
|
+
|
1
9
|
== 0.7.1 2011-01-19
|
2
10
|
* bug fixes
|
3
11
|
* Fix uninitialized constant HTTParty::Response::Net in 1.9.2 (cap10morgan)
|
data/httparty.gemspec
CHANGED
@@ -5,7 +5,7 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{httparty}
|
8
|
-
s.version = "0.7.
|
8
|
+
s.version = "0.7.3"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["John Nunemaker", "Sandro Turriate"]
|
@@ -76,6 +76,7 @@ Gem::Specification.new do |s|
|
|
76
76
|
"spec/fixtures/twitter.xml",
|
77
77
|
"spec/fixtures/undefined_method_add_node_for_nil.xml",
|
78
78
|
"spec/httparty/cookie_hash_spec.rb",
|
79
|
+
"spec/httparty/net_digest_auth_spec.rb",
|
79
80
|
"spec/httparty/parser_spec.rb",
|
80
81
|
"spec/httparty/request_spec.rb",
|
81
82
|
"spec/httparty/response_spec.rb",
|
@@ -92,7 +93,7 @@ Gem::Specification.new do |s|
|
|
92
93
|
s.homepage = %q{http://httparty.rubyforge.org}
|
93
94
|
s.post_install_message = %q{When you HTTParty, you must party hard!}
|
94
95
|
s.require_paths = ["lib"]
|
95
|
-
s.rubygems_version = %q{1.
|
96
|
+
s.rubygems_version = %q{1.4.2}
|
96
97
|
s.summary = %q{Makes http fun! Also, makes consuming restful web services dead easy.}
|
97
98
|
s.test_files = [
|
98
99
|
"examples/aaws.rb",
|
@@ -105,6 +106,7 @@ Gem::Specification.new do |s|
|
|
105
106
|
"examples/twitter.rb",
|
106
107
|
"examples/whoismyrep.rb",
|
107
108
|
"spec/httparty/cookie_hash_spec.rb",
|
109
|
+
"spec/httparty/net_digest_auth_spec.rb",
|
108
110
|
"spec/httparty/parser_spec.rb",
|
109
111
|
"spec/httparty/request_spec.rb",
|
110
112
|
"spec/httparty/response_spec.rb",
|
@@ -117,7 +119,6 @@ Gem::Specification.new do |s|
|
|
117
119
|
]
|
118
120
|
|
119
121
|
if s.respond_to? :specification_version then
|
120
|
-
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
121
122
|
s.specification_version = 3
|
122
123
|
|
123
124
|
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
data/lib/httparty.rb
CHANGED
@@ -3,33 +3,69 @@ require 'net/http'
|
|
3
3
|
|
4
4
|
module Net
|
5
5
|
module HTTPHeader
|
6
|
-
def digest_auth(
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
%Q(
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
%Q(
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
6
|
+
def digest_auth(username, password, response)
|
7
|
+
@header['Authorization'] = DigestAuthenticator.new(username, password,
|
8
|
+
@method, @path, response).authorization_header
|
9
|
+
end
|
10
|
+
|
11
|
+
|
12
|
+
class DigestAuthenticator
|
13
|
+
def initialize(username, password, method, path, response_header)
|
14
|
+
@username = username
|
15
|
+
@password = password
|
16
|
+
@method = method
|
17
|
+
@path = path
|
18
|
+
@response = parse(response_header)
|
19
|
+
end
|
20
|
+
|
21
|
+
def authorization_header
|
22
|
+
@cnonce = md5(random)
|
23
|
+
header = [%Q(Digest username="#{@username}"),
|
24
|
+
%Q(realm="#{@response['realm']}"),
|
25
|
+
%Q(nonce="#{@response['nonce']}"),
|
26
|
+
%Q(uri="#{@path}"),
|
27
|
+
%Q(response="#{request_digest}")]
|
28
|
+
[%Q(cnonce="#{@cnonce}"),
|
29
|
+
%Q(opaque="#{@response['opaque']}"),
|
30
|
+
%Q(qop="#{@response['qop']}"),
|
31
|
+
%Q(nc="0")].each { |field| header << field } if qop_present?
|
32
|
+
header
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
def parse(response_header)
|
38
|
+
response_header['www-authenticate'] =~ /^(\w+) (.*)/
|
39
|
+
params = {}
|
40
|
+
$2.gsub(/(\w+)="(.*?)"/) { params[$1] = $2 }
|
41
|
+
params
|
42
|
+
end
|
43
|
+
|
44
|
+
def qop_present?
|
45
|
+
@response.has_key?('qop') and not @response['qop'].empty?
|
46
|
+
end
|
47
|
+
|
48
|
+
def random
|
49
|
+
"%x" % (Time.now.to_i + rand(65535))
|
50
|
+
end
|
51
|
+
|
52
|
+
def request_digest
|
53
|
+
a = [md5(a1), @response['nonce'], md5(a2)]
|
54
|
+
a.insert(2, "0", @cnonce, @response['qop']) if qop_present?
|
55
|
+
md5(a.join(":"))
|
56
|
+
end
|
57
|
+
|
58
|
+
def md5(str)
|
59
|
+
Digest::MD5.hexdigest(str)
|
60
|
+
end
|
61
|
+
|
62
|
+
def a1
|
63
|
+
[@username, @response['realm'], @password].join(":")
|
64
|
+
end
|
65
|
+
|
66
|
+
def a2
|
67
|
+
[@method, @path].join(":")
|
68
|
+
end
|
33
69
|
end
|
34
70
|
end
|
35
71
|
end
|
@@ -0,0 +1,93 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'spec_helper'))
|
2
|
+
|
3
|
+
describe Net::HTTPHeader::DigestAuthenticator do
|
4
|
+
def setup_digest(response)
|
5
|
+
digest = Net::HTTPHeader::DigestAuthenticator.new("Mufasa",
|
6
|
+
"Circle Of Life", "GET", "/dir/index.html", response)
|
7
|
+
digest.stub(:random).and_return("deadbeef")
|
8
|
+
Digest::MD5.stub(:hexdigest) { |str| "md5(#{str})" }
|
9
|
+
digest
|
10
|
+
end
|
11
|
+
|
12
|
+
def authorization_header
|
13
|
+
@digest.authorization_header.join(", ")
|
14
|
+
end
|
15
|
+
|
16
|
+
|
17
|
+
context "with specified quality of protection (qop)" do
|
18
|
+
before do
|
19
|
+
@digest = setup_digest({'www-authenticate' =>
|
20
|
+
'Digest realm="myhost@testrealm.com", nonce="NONCE", qop="auth"'})
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should set prefix" do
|
24
|
+
authorization_header.should =~ /^Digest /
|
25
|
+
end
|
26
|
+
|
27
|
+
it "should set username" do
|
28
|
+
authorization_header.should include(%Q(username="Mufasa"))
|
29
|
+
end
|
30
|
+
|
31
|
+
it "should set digest-uri" do
|
32
|
+
authorization_header.should include(%Q(uri="/dir/index.html"))
|
33
|
+
end
|
34
|
+
|
35
|
+
it "should set qop" do
|
36
|
+
authorization_header.should include(%Q(qop="auth"))
|
37
|
+
end
|
38
|
+
|
39
|
+
it "should set cnonce" do
|
40
|
+
authorization_header.should include(%Q(cnonce="md5(deadbeef)"))
|
41
|
+
end
|
42
|
+
|
43
|
+
it "should set nonce-count" do
|
44
|
+
authorization_header.should include(%Q(nc="0"))
|
45
|
+
end
|
46
|
+
|
47
|
+
it "should set response" do
|
48
|
+
request_digest =
|
49
|
+
"md5(md5(Mufasa:myhost@testrealm.com:Circle Of Life)" +
|
50
|
+
":NONCE:0:md5(deadbeef):auth:md5(GET:/dir/index.html))"
|
51
|
+
authorization_header.should include(%Q(response="#{request_digest}"))
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
|
56
|
+
context "with unspecified quality of protection (qop)" do
|
57
|
+
before do
|
58
|
+
@digest = setup_digest({'www-authenticate' =>
|
59
|
+
'Digest realm="myhost@testrealm.com", nonce="NONCE"'})
|
60
|
+
end
|
61
|
+
|
62
|
+
it "should set prefix" do
|
63
|
+
authorization_header.should =~ /^Digest /
|
64
|
+
end
|
65
|
+
|
66
|
+
it "should set username" do
|
67
|
+
authorization_header.should include(%Q(username="Mufasa"))
|
68
|
+
end
|
69
|
+
|
70
|
+
it "should set digest-uri" do
|
71
|
+
authorization_header.should include(%Q(uri="/dir/index.html"))
|
72
|
+
end
|
73
|
+
|
74
|
+
it "should not set qop" do
|
75
|
+
authorization_header.should_not include(%Q(qop=))
|
76
|
+
end
|
77
|
+
|
78
|
+
it "should not set cnonce" do
|
79
|
+
authorization_header.should_not include(%Q(cnonce=))
|
80
|
+
end
|
81
|
+
|
82
|
+
it "should not set nonce-count" do
|
83
|
+
authorization_header.should_not include(%Q(nc=))
|
84
|
+
end
|
85
|
+
|
86
|
+
it "should set response" do
|
87
|
+
request_digest =
|
88
|
+
"md5(md5(Mufasa:myhost@testrealm.com:Circle Of Life)" +
|
89
|
+
":NONCE:md5(GET:/dir/index.html))"
|
90
|
+
authorization_header.should include(%Q(response="#{request_digest}"))
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: httparty
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
5
|
-
prerelease:
|
4
|
+
hash: 5
|
5
|
+
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 7
|
9
|
-
-
|
10
|
-
version: 0.7.
|
9
|
+
- 3
|
10
|
+
version: 0.7.3
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- John Nunemaker
|
@@ -118,12 +118,13 @@ dependencies:
|
|
118
118
|
requirements:
|
119
119
|
- - "="
|
120
120
|
- !ruby/object:Gem::Version
|
121
|
-
hash:
|
121
|
+
hash: 1923831981
|
122
122
|
segments:
|
123
123
|
- 1
|
124
124
|
- 2
|
125
125
|
- 0
|
126
|
-
-
|
126
|
+
- pre
|
127
|
+
- 2
|
127
128
|
version: 1.2.0.pre2
|
128
129
|
type: :development
|
129
130
|
version_requirements: *id007
|
@@ -194,6 +195,7 @@ files:
|
|
194
195
|
- spec/fixtures/twitter.xml
|
195
196
|
- spec/fixtures/undefined_method_add_node_for_nil.xml
|
196
197
|
- spec/httparty/cookie_hash_spec.rb
|
198
|
+
- spec/httparty/net_digest_auth_spec.rb
|
197
199
|
- spec/httparty/parser_spec.rb
|
198
200
|
- spec/httparty/request_spec.rb
|
199
201
|
- spec/httparty/response_spec.rb
|
@@ -236,7 +238,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
236
238
|
requirements: []
|
237
239
|
|
238
240
|
rubyforge_project:
|
239
|
-
rubygems_version: 1.
|
241
|
+
rubygems_version: 1.4.2
|
240
242
|
signing_key:
|
241
243
|
specification_version: 3
|
242
244
|
summary: Makes http fun! Also, makes consuming restful web services dead easy.
|
@@ -251,6 +253,7 @@ test_files:
|
|
251
253
|
- examples/twitter.rb
|
252
254
|
- examples/whoismyrep.rb
|
253
255
|
- spec/httparty/cookie_hash_spec.rb
|
256
|
+
- spec/httparty/net_digest_auth_spec.rb
|
254
257
|
- spec/httparty/parser_spec.rb
|
255
258
|
- spec/httparty/request_spec.rb
|
256
259
|
- spec/httparty/response_spec.rb
|