jugend-httparty 0.5.2.3 → 0.5.3.4
Sign up to get free protection for your applications and to get access to all the features.
- data/History +25 -7
- data/Rakefile +4 -4
- data/VERSION +1 -1
- data/features/digest_authentication.feature +20 -0
- data/features/steps/env.rb +8 -1
- data/features/steps/httparty_steps.rb +8 -0
- data/features/steps/mongrel_helper.rb +22 -0
- data/features/steps/remote_service_steps.rb +11 -2
- data/features/supports_timeout_option.feature +1 -0
- data/jugend-httparty.gemspec +14 -12
- data/lib/httparty.rb +45 -6
- data/lib/httparty/net_digest_auth.rb +35 -0
- data/lib/httparty/request.rb +103 -91
- data/lib/httparty/response.rb +54 -10
- data/spec/httparty/request_spec.rb +38 -0
- data/spec/httparty/response_spec.rb +53 -32
- data/spec/httparty_spec.rb +31 -1
- data/spec/spec_helper.rb +6 -2
- data/spec/support/stub_response.rb +1 -1
- metadata +13 -12
data/History
CHANGED
@@ -1,12 +1,30 @@
|
|
1
|
-
== 0.5.
|
2
|
-
*
|
1
|
+
== 0.5.3.4
|
2
|
+
* Update gem name to jugend-httparty
|
3
|
+
|
4
|
+
== 0.5.3.3
|
5
|
+
* Remove RubyforgeTasks
|
6
|
+
|
7
|
+
== 0.5.3.2
|
8
|
+
* Remove deprecated rubyforge gem push
|
9
|
+
|
10
|
+
== 0.5.3.1
|
11
|
+
* Update Pathname initialization to support earlier version of ruby (<=1.8.4)
|
3
12
|
|
4
|
-
== 0.5.
|
5
|
-
|
13
|
+
== 0.5.3 (master)
|
14
|
+
* major enhancements
|
15
|
+
* Digest Auth (bartiaco, sbecker, gilles, and aaronrussell)
|
16
|
+
* Maintain HTTP method across redirects (bartiaco and sbecker)
|
17
|
+
* HTTParty::Response#response returns the Net::HTTPResponse object
|
18
|
+
* HTTParty::Response#headers returns a HTTParty::Response::Headers object
|
19
|
+
which quacks like a Hash + Net::HTTPHeader. The #headers method continues
|
20
|
+
to be backwards-compatible with the old Hash return value but may become
|
21
|
+
deprecated in the future.
|
6
22
|
|
7
|
-
|
8
|
-
* Update
|
9
|
-
|
23
|
+
* minor enhancements
|
24
|
+
* Update crack requirement to version 0.1.7
|
25
|
+
You may still get a warning because Crack's version constant is out of date
|
26
|
+
* Timeout option can be set for all requests using HTTParty.default_timeout (taazza)
|
27
|
+
* Closed #38 "headers hash should downcase keys so canonical header name can be used"
|
10
28
|
|
11
29
|
== 0.5.2 2010-01-31
|
12
30
|
* minor enhancements
|
data/Rakefile
CHANGED
@@ -7,14 +7,14 @@ begin
|
|
7
7
|
gem.summary = %Q{Makes http fun! Also, makes consuming restful web services dead easy.}
|
8
8
|
gem.description = %Q{Makes http fun! Also, makes consuming restful web services dead easy.}
|
9
9
|
gem.email = "nunemaker@gmail.com"
|
10
|
-
gem.homepage = "http://httparty
|
10
|
+
gem.homepage = "http://github.com/jugend/httparty"
|
11
11
|
gem.authors = ["John Nunemaker", "Sandro Turriate"]
|
12
|
-
gem.add_dependency 'crack', '0.1.
|
12
|
+
gem.add_dependency 'crack', '0.1.7'
|
13
13
|
gem.add_development_dependency "activesupport", "~>2.3"
|
14
|
-
gem.add_development_dependency "cucumber", "~>0.
|
14
|
+
gem.add_development_dependency "cucumber", "~>0.7"
|
15
15
|
gem.add_development_dependency "fakeweb", "~>1.2"
|
16
16
|
gem.add_development_dependency "mongrel", "~>1.1"
|
17
|
-
gem.add_development_dependency "rspec", "1.
|
17
|
+
gem.add_development_dependency "rspec", "~>1.3"
|
18
18
|
gem.post_install_message = "When you HTTParty, you must party hard!"
|
19
19
|
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
20
20
|
end
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.5.
|
1
|
+
0.5.3.4
|
@@ -0,0 +1,20 @@
|
|
1
|
+
Feature: Digest Authentication
|
2
|
+
|
3
|
+
As a developer
|
4
|
+
I want to be able to use a service that requires Digest Authentication
|
5
|
+
Because that is not an uncommon requirement
|
6
|
+
|
7
|
+
Scenario: Passing no credentials to a page requiring Digest Authentication
|
8
|
+
Given a restricted page at '/protected.html'
|
9
|
+
When I call HTTParty#get with '/protected.html'
|
10
|
+
Then it should return a response with a 401 response code
|
11
|
+
|
12
|
+
Scenario: Passing proper credentials to a page requiring Digest Authentication
|
13
|
+
Given a remote service that returns 'Digest Authenticated Page'
|
14
|
+
And that service is accessed at the path '/protected.html'
|
15
|
+
And that service is protected by Digest Authentication
|
16
|
+
And that service requires the username 'jcash' with the password 'maninblack'
|
17
|
+
When I call HTTParty#get with '/protected.html' and a digest_auth hash:
|
18
|
+
| username | password |
|
19
|
+
| jcash | maninblack |
|
20
|
+
Then the return value should match 'Digest Authenticated Page'
|
data/features/steps/env.rb
CHANGED
@@ -4,7 +4,14 @@ require 'lib/httparty'
|
|
4
4
|
require 'spec/expectations'
|
5
5
|
|
6
6
|
Before do
|
7
|
-
|
7
|
+
def new_port
|
8
|
+
server = TCPServer.new('0.0.0.0', nil)
|
9
|
+
port = server.addr[1]
|
10
|
+
ensure
|
11
|
+
server.close
|
12
|
+
end
|
13
|
+
|
14
|
+
port = ENV["HTTPARTY_PORT"] || new_port
|
8
15
|
@host_and_port = "0.0.0.0:#{port}"
|
9
16
|
@server = Mongrel::HttpServer.new("0.0.0.0", port)
|
10
17
|
@server.run
|
@@ -17,3 +17,11 @@ When /I call HTTParty#get with '(.*)' and a basic_auth hash:/ do |url, auth_tabl
|
|
17
17
|
:basic_auth => { :username => h["username"], :password => h["password"] }
|
18
18
|
)
|
19
19
|
end
|
20
|
+
|
21
|
+
When /I call HTTParty#get with '(.*)' and a digest_auth hash:/ do |url, auth_table|
|
22
|
+
h = auth_table.hashes.first
|
23
|
+
@response_from_httparty = HTTParty.get(
|
24
|
+
"http://#{@host_and_port}#{url}",
|
25
|
+
:digest_auth => { :username => h["username"], :password => h["password"] }
|
26
|
+
)
|
27
|
+
end
|
@@ -50,6 +50,28 @@ def add_basic_authentication_to(handler)
|
|
50
50
|
handler.extend(m)
|
51
51
|
end
|
52
52
|
|
53
|
+
def add_digest_authentication_to(handler)
|
54
|
+
m = Module.new do
|
55
|
+
attr_writer :username, :password
|
56
|
+
|
57
|
+
def self.extended(base)
|
58
|
+
base.instance_eval { @custom_headers["WWW-Authenticate"] = 'Digest realm="testrealm@host.com",qop="auth,auth-int",nonce="nonce",opaque="opaque"' }
|
59
|
+
base.class_eval { alias_method_chain :process, :digest_authentication }
|
60
|
+
end
|
61
|
+
|
62
|
+
def process_with_digest_authentication(request, response)
|
63
|
+
if authorized?(request) then process_without_digest_authentication(request, response)
|
64
|
+
else reply_with(response, 401, "Incorrect. You have 20 seconds to comply.")
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def authorized?(request)
|
69
|
+
request.params["HTTP_AUTHORIZATION"] =~ /Digest.*uri=/
|
70
|
+
end
|
71
|
+
end
|
72
|
+
handler.extend(m)
|
73
|
+
end
|
74
|
+
|
53
75
|
def new_mongrel_redirector(target_url, relative_path = false)
|
54
76
|
target_url = "http://#{@host_and_port}#{target_url}" unless relative_path
|
55
77
|
Mongrel::RedirectHandler.new(target_url)
|
@@ -13,8 +13,8 @@ Given /that service is accessed at the path '(.*)'/ do |path|
|
|
13
13
|
end
|
14
14
|
|
15
15
|
Given /^that service takes (\d+) seconds to generate a response$/ do |time|
|
16
|
-
|
17
|
-
@handler.preprocessor =
|
16
|
+
@server_response_time = time.to_i
|
17
|
+
@handler.preprocessor = lambda { sleep time.to_i }
|
18
18
|
end
|
19
19
|
|
20
20
|
Given /the response from the service has a Content-Type of '(.*)'/ do |content_type|
|
@@ -33,6 +33,10 @@ Given /that service is protected by Basic Authentication/ do
|
|
33
33
|
add_basic_authentication_to @handler
|
34
34
|
end
|
35
35
|
|
36
|
+
Given /that service is protected by Digest Authentication/ do
|
37
|
+
add_digest_authentication_to @handler
|
38
|
+
end
|
39
|
+
|
36
40
|
Given /that service requires the username '(.*)' with the password '(.*)'/ do |username, password|
|
37
41
|
@handler.username = username
|
38
42
|
@handler.password = password
|
@@ -50,3 +54,8 @@ end
|
|
50
54
|
Given /I want to hit this in a browser/ do
|
51
55
|
@server.acceptor.join
|
52
56
|
end
|
57
|
+
|
58
|
+
Then /I wait for the server to recover/ do
|
59
|
+
timeout = @request_options[:timeout] || 0
|
60
|
+
sleep @server_response_time - timeout
|
61
|
+
end
|
data/jugend-httparty.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{jugend-httparty}
|
8
|
-
s.version = "0.5.
|
8
|
+
s.version = "0.5.3.4"
|
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"]
|
12
|
-
s.date = %q{2010-
|
12
|
+
s.date = %q{2010-05-26}
|
13
13
|
s.default_executable = %q{httparty}
|
14
14
|
s.description = %q{Makes http fun! Also, makes consuming restful web services dead easy.}
|
15
15
|
s.email = %q{nunemaker@gmail.com}
|
@@ -38,6 +38,7 @@ Gem::Specification.new do |s|
|
|
38
38
|
"features/basic_authentication.feature",
|
39
39
|
"features/command_line.feature",
|
40
40
|
"features/deals_with_http_error_codes.feature",
|
41
|
+
"features/digest_authentication.feature",
|
41
42
|
"features/handles_multiple_formats.feature",
|
42
43
|
"features/steps/env.rb",
|
43
44
|
"features/steps/httparty_response_steps.rb",
|
@@ -52,6 +53,7 @@ Gem::Specification.new do |s|
|
|
52
53
|
"lib/httparty/core_extensions.rb",
|
53
54
|
"lib/httparty/exceptions.rb",
|
54
55
|
"lib/httparty/module_inheritable_attributes.rb",
|
56
|
+
"lib/httparty/net_digest_auth.rb",
|
55
57
|
"lib/httparty/parser.rb",
|
56
58
|
"lib/httparty/request.rb",
|
57
59
|
"lib/httparty/response.rb",
|
@@ -72,7 +74,7 @@ Gem::Specification.new do |s|
|
|
72
74
|
"website/css/common.css",
|
73
75
|
"website/index.html"
|
74
76
|
]
|
75
|
-
s.homepage = %q{http://httparty
|
77
|
+
s.homepage = %q{http://github.com/jugend/httparty}
|
76
78
|
s.post_install_message = %q{When you HTTParty, you must party hard!}
|
77
79
|
s.rdoc_options = ["--charset=UTF-8"]
|
78
80
|
s.require_paths = ["lib"]
|
@@ -101,27 +103,27 @@ Gem::Specification.new do |s|
|
|
101
103
|
s.specification_version = 3
|
102
104
|
|
103
105
|
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
104
|
-
s.add_runtime_dependency(%q<crack>, ["= 0.1.
|
106
|
+
s.add_runtime_dependency(%q<crack>, ["= 0.1.7"])
|
105
107
|
s.add_development_dependency(%q<activesupport>, ["~> 2.3"])
|
106
|
-
s.add_development_dependency(%q<cucumber>, ["~> 0.
|
108
|
+
s.add_development_dependency(%q<cucumber>, ["~> 0.7"])
|
107
109
|
s.add_development_dependency(%q<fakeweb>, ["~> 1.2"])
|
108
110
|
s.add_development_dependency(%q<mongrel>, ["~> 1.1"])
|
109
|
-
s.add_development_dependency(%q<rspec>, ["
|
111
|
+
s.add_development_dependency(%q<rspec>, ["~> 1.3"])
|
110
112
|
else
|
111
|
-
s.add_dependency(%q<crack>, ["= 0.1.
|
113
|
+
s.add_dependency(%q<crack>, ["= 0.1.7"])
|
112
114
|
s.add_dependency(%q<activesupport>, ["~> 2.3"])
|
113
|
-
s.add_dependency(%q<cucumber>, ["~> 0.
|
115
|
+
s.add_dependency(%q<cucumber>, ["~> 0.7"])
|
114
116
|
s.add_dependency(%q<fakeweb>, ["~> 1.2"])
|
115
117
|
s.add_dependency(%q<mongrel>, ["~> 1.1"])
|
116
|
-
s.add_dependency(%q<rspec>, ["
|
118
|
+
s.add_dependency(%q<rspec>, ["~> 1.3"])
|
117
119
|
end
|
118
120
|
else
|
119
|
-
s.add_dependency(%q<crack>, ["= 0.1.
|
121
|
+
s.add_dependency(%q<crack>, ["= 0.1.7"])
|
120
122
|
s.add_dependency(%q<activesupport>, ["~> 2.3"])
|
121
|
-
s.add_dependency(%q<cucumber>, ["~> 0.
|
123
|
+
s.add_dependency(%q<cucumber>, ["~> 0.7"])
|
122
124
|
s.add_dependency(%q<fakeweb>, ["~> 1.2"])
|
123
125
|
s.add_dependency(%q<mongrel>, ["~> 1.1"])
|
124
|
-
s.add_dependency(%q<rspec>, ["
|
126
|
+
s.add_dependency(%q<rspec>, ["~> 1.3"])
|
125
127
|
end
|
126
128
|
end
|
127
129
|
|
data/lib/httparty.rb
CHANGED
@@ -3,17 +3,15 @@ require 'net/http'
|
|
3
3
|
require 'net/https'
|
4
4
|
require 'crack'
|
5
5
|
|
6
|
-
|
7
|
-
warn "warning: HTTParty depends on version 0.1.6 of crack, not #{Crack::VERSION}."
|
8
|
-
end
|
9
|
-
|
10
|
-
dir = Pathname(__FILE__).dirname.expand_path
|
6
|
+
dir = Pathname.new(__FILE__).dirname.expand_path
|
11
7
|
|
12
8
|
require dir + 'httparty/module_inheritable_attributes'
|
13
9
|
require dir + 'httparty/cookie_hash'
|
10
|
+
require dir + 'httparty/net_digest_auth'
|
14
11
|
|
15
12
|
module HTTParty
|
16
13
|
VERSION = "0.5.2".freeze
|
14
|
+
CRACK_DEPENDENCY = "0.1.7".freeze
|
17
15
|
|
18
16
|
module AllowedFormatsDeprecation
|
19
17
|
def const_missing(const)
|
@@ -73,6 +71,16 @@ module HTTParty
|
|
73
71
|
default_options[:basic_auth] = {:username => u, :password => p}
|
74
72
|
end
|
75
73
|
|
74
|
+
# Allows setting digest authentication username and password.
|
75
|
+
#
|
76
|
+
# class Foo
|
77
|
+
# include HTTParty
|
78
|
+
# digest_auth 'username', 'password'
|
79
|
+
# end
|
80
|
+
def digest_auth(u, p)
|
81
|
+
default_options[:digest_auth] = {:username => u, :password => p}
|
82
|
+
end
|
83
|
+
|
76
84
|
# Allows setting default parameters to be appended to each request.
|
77
85
|
# Great for api keys and such.
|
78
86
|
#
|
@@ -86,6 +94,18 @@ module HTTParty
|
|
86
94
|
default_options[:default_params].merge!(h)
|
87
95
|
end
|
88
96
|
|
97
|
+
# Allows setting a default timeout for all HTTP calls
|
98
|
+
# Timeout is specified in seconds.
|
99
|
+
#
|
100
|
+
# class Foo
|
101
|
+
# include HTTParty
|
102
|
+
# default_timeout 10
|
103
|
+
# end
|
104
|
+
def default_timeout(t)
|
105
|
+
raise ArgumentError, 'Timeout must be an integer' unless t && t.is_a?(Integer)
|
106
|
+
default_options[:timeout] = t
|
107
|
+
end
|
108
|
+
|
89
109
|
# Set an output stream for debugging, defaults to $stderr.
|
90
110
|
# The output stream is passed on to Net::HTTP#set_debug_output.
|
91
111
|
#
|
@@ -97,7 +117,7 @@ module HTTParty
|
|
97
117
|
default_options[:debug_output] = stream
|
98
118
|
end
|
99
119
|
|
100
|
-
# Allows setting
|
120
|
+
# Allows setting HTTP headers to be used for each request.
|
101
121
|
#
|
102
122
|
# class Foo
|
103
123
|
# include HTTParty
|
@@ -154,6 +174,21 @@ module HTTParty
|
|
154
174
|
default_options[:no_follow] = value
|
155
175
|
end
|
156
176
|
|
177
|
+
# Declare that you wish to maintain the chosen HTTP method across redirects.
|
178
|
+
# The default behavior is to follow redirects via the GET method.
|
179
|
+
# If you wish to maintain the original method, you can set this option to true.
|
180
|
+
#
|
181
|
+
# @example
|
182
|
+
# class Foo
|
183
|
+
# include HTTParty
|
184
|
+
# base_uri 'http://google.com'
|
185
|
+
# maintain_method_across_redirects true
|
186
|
+
# end
|
187
|
+
|
188
|
+
def maintain_method_across_redirects(value = true)
|
189
|
+
default_options[:maintain_method_across_redirects] = value
|
190
|
+
end
|
191
|
+
|
157
192
|
# Allows setting a PEM file to be used
|
158
193
|
#
|
159
194
|
# class Foo
|
@@ -302,3 +337,7 @@ require dir + 'httparty/exceptions'
|
|
302
337
|
require dir + 'httparty/parser'
|
303
338
|
require dir + 'httparty/request'
|
304
339
|
require dir + 'httparty/response'
|
340
|
+
|
341
|
+
if Crack::VERSION != HTTParty::CRACK_DEPENDENCY
|
342
|
+
warn "warning: HTTParty depends on version #{HTTParty::CRACK_DEPENDENCY} of crack, not #{Crack::VERSION}."
|
343
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'digest/md5'
|
2
|
+
require 'net/http'
|
3
|
+
|
4
|
+
module Net
|
5
|
+
module HTTPHeader
|
6
|
+
def digest_auth(user, password, response)
|
7
|
+
response['www-authenticate'] =~ /^(\w+) (.*)/
|
8
|
+
|
9
|
+
params = {}
|
10
|
+
$2.gsub(/(\w+)="(.*?)"/) { params[$1] = $2 }
|
11
|
+
params.merge!("cnonce" => Digest::MD5.hexdigest("%x" % (Time.now.to_i + rand(65535))))
|
12
|
+
|
13
|
+
a_1 = Digest::MD5.hexdigest("#{user}:#{params['realm']}:#{password}")
|
14
|
+
a_2 = Digest::MD5.hexdigest("#{@method}:#{@path}")
|
15
|
+
|
16
|
+
request_digest = Digest::MD5.hexdigest(
|
17
|
+
[a_1, params['nonce'], "0", params['cnonce'], params['qop'], a_2].join(":")
|
18
|
+
)
|
19
|
+
|
20
|
+
header = [
|
21
|
+
%Q(Digest username="#{user}"),
|
22
|
+
%Q(realm="#{params['realm']}"),
|
23
|
+
%Q(qop="#{params['qop']}"),
|
24
|
+
%Q(uri="#{@path}"),
|
25
|
+
%Q(nonce="#{params['nonce']}"),
|
26
|
+
%Q(nc="0"),
|
27
|
+
%Q(cnonce="#{params['cnonce']}"),
|
28
|
+
%Q(opaque="#{params['opaque']}"),
|
29
|
+
%Q(response="#{request_digest}")
|
30
|
+
]
|
31
|
+
|
32
|
+
@header['Authorization'] = header
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
data/lib/httparty/request.rb
CHANGED
@@ -13,7 +13,7 @@ module HTTParty
|
|
13
13
|
|
14
14
|
SupportedURISchemes = [URI::HTTP, URI::HTTPS]
|
15
15
|
|
16
|
-
attr_accessor :http_method, :path, :options, :last_response
|
16
|
+
attr_accessor :http_method, :path, :options, :last_response, :redirect
|
17
17
|
|
18
18
|
def initialize(http_method, path, o={})
|
19
19
|
self.http_method = http_method
|
@@ -33,7 +33,7 @@ module HTTParty
|
|
33
33
|
new_uri = path.relative? ? URI.parse("#{options[:base_uri]}#{path}") : path
|
34
34
|
|
35
35
|
# avoid double query string on redirects [#12]
|
36
|
-
unless
|
36
|
+
unless redirect
|
37
37
|
new_uri.query = query_string(new_uri)
|
38
38
|
end
|
39
39
|
|
@@ -52,7 +52,6 @@ module HTTParty
|
|
52
52
|
options[:parser]
|
53
53
|
end
|
54
54
|
|
55
|
-
|
56
55
|
def perform
|
57
56
|
validate
|
58
57
|
setup_raw_request
|
@@ -62,133 +61,146 @@ module HTTParty
|
|
62
61
|
|
63
62
|
private
|
64
63
|
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
if options[:timeout] && options[:timeout].is_a?(Integer)
|
70
|
-
http.open_timeout = options[:timeout]
|
71
|
-
http.read_timeout = options[:timeout]
|
72
|
-
end
|
73
|
-
|
74
|
-
if options[:pem] && http.use_ssl?
|
75
|
-
http.cert = OpenSSL::X509::Certificate.new(options[:pem])
|
76
|
-
http.key = OpenSSL::PKey::RSA.new(options[:pem])
|
77
|
-
http.verify_mode = OpenSSL::SSL::VERIFY_PEER
|
78
|
-
else
|
79
|
-
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
80
|
-
end
|
81
|
-
|
82
|
-
if options[:debug_output]
|
83
|
-
http.set_debug_output(options[:debug_output])
|
84
|
-
end
|
64
|
+
def http
|
65
|
+
http = Net::HTTP.new(uri.host, uri.port, options[:http_proxyaddr], options[:http_proxyport])
|
66
|
+
http.use_ssl = ssl_implied?
|
85
67
|
|
86
|
-
|
68
|
+
if options[:timeout] && options[:timeout].is_a?(Integer)
|
69
|
+
http.open_timeout = options[:timeout]
|
70
|
+
http.read_timeout = options[:timeout]
|
87
71
|
end
|
88
72
|
|
89
|
-
|
90
|
-
|
73
|
+
if options[:pem] && http.use_ssl?
|
74
|
+
http.cert = OpenSSL::X509::Certificate.new(options[:pem])
|
75
|
+
http.key = OpenSSL::PKey::RSA.new(options[:pem])
|
76
|
+
http.verify_mode = OpenSSL::SSL::VERIFY_PEER
|
77
|
+
else
|
78
|
+
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
91
79
|
end
|
92
80
|
|
93
|
-
|
94
|
-
|
81
|
+
if options[:debug_output]
|
82
|
+
http.set_debug_output(options[:debug_output])
|
95
83
|
end
|
96
84
|
|
97
|
-
|
98
|
-
|
99
|
-
end
|
85
|
+
http
|
86
|
+
end
|
100
87
|
|
101
|
-
|
102
|
-
|
103
|
-
|
88
|
+
def ssl_implied?
|
89
|
+
uri.port == 443 || uri.instance_of?(URI::HTTPS)
|
90
|
+
end
|
104
91
|
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
@raw_request.initialize_http_header(options[:headers])
|
109
|
-
@raw_request.basic_auth(username, password) if options[:basic_auth]
|
110
|
-
end
|
92
|
+
def body
|
93
|
+
options[:body].is_a?(Hash) ? options[:body].to_params : options[:body]
|
94
|
+
end
|
111
95
|
|
112
|
-
|
113
|
-
|
114
|
-
|
96
|
+
def credentials
|
97
|
+
options[:basic_auth] || options[:digest_auth]
|
98
|
+
end
|
115
99
|
|
116
|
-
|
117
|
-
|
118
|
-
|
100
|
+
def username
|
101
|
+
credentials[:username]
|
102
|
+
end
|
103
|
+
|
104
|
+
def password
|
105
|
+
credentials[:password]
|
106
|
+
end
|
107
|
+
|
108
|
+
def setup_raw_request
|
109
|
+
@raw_request = http_method.new(uri.request_uri)
|
110
|
+
@raw_request.body = body if body
|
111
|
+
@raw_request.initialize_http_header(options[:headers])
|
112
|
+
@raw_request.basic_auth(username, password) if options[:basic_auth]
|
113
|
+
setup_digest_auth if options[:digest_auth]
|
114
|
+
end
|
115
|
+
|
116
|
+
def setup_digest_auth
|
117
|
+
res = http.head(uri.request_uri, options[:headers])
|
118
|
+
if res['www-authenticate'] != nil && res['www-authenticate'].length > 0
|
119
|
+
@raw_request.digest_auth(username, password, res)
|
119
120
|
end
|
121
|
+
end
|
120
122
|
|
121
|
-
|
122
|
-
|
123
|
-
|
123
|
+
def perform_actual_request
|
124
|
+
http.request(@raw_request)
|
125
|
+
end
|
124
126
|
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
query_string_parts << options[:query] unless options[:query].nil?
|
130
|
-
end
|
127
|
+
def get_response
|
128
|
+
self.last_response = perform_actual_request
|
129
|
+
options[:format] ||= format_from_mimetype(last_response['content-type'])
|
130
|
+
end
|
131
131
|
|
132
|
-
|
132
|
+
def query_string(uri)
|
133
|
+
query_string_parts = []
|
134
|
+
query_string_parts << uri.query unless uri.query.nil?
|
135
|
+
|
136
|
+
if options[:query].is_a?(Hash)
|
137
|
+
query_string_parts << options[:default_params].merge(options[:query]).to_params
|
138
|
+
else
|
139
|
+
query_string_parts << options[:default_params].to_params unless options[:default_params].empty?
|
140
|
+
query_string_parts << options[:query] unless options[:query].nil?
|
133
141
|
end
|
134
142
|
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
143
|
+
query_string_parts.size > 0 ? query_string_parts.join('&') : nil
|
144
|
+
end
|
145
|
+
|
146
|
+
# Raises exception Net::XXX (http error code) if an http error occured
|
147
|
+
def handle_response
|
148
|
+
case last_response
|
149
|
+
when Net::HTTPMultipleChoice, # 300
|
150
|
+
Net::HTTPMovedPermanently, # 301
|
151
|
+
Net::HTTPFound, # 302
|
152
|
+
Net::HTTPSeeOther, # 303
|
153
|
+
Net::HTTPUseProxy, # 305
|
154
|
+
Net::HTTPTemporaryRedirect
|
144
155
|
if last_response.key?('location')
|
145
156
|
options[:limit] -= 1
|
146
157
|
self.path = last_response['location']
|
147
|
-
|
148
|
-
self.http_method = Net::HTTP::Get
|
158
|
+
self.redirect = true
|
159
|
+
self.http_method = Net::HTTP::Get unless options[:maintain_method_across_redirects]
|
149
160
|
capture_cookies(last_response)
|
150
161
|
perform
|
151
162
|
else
|
152
163
|
last_response
|
153
164
|
end
|
154
165
|
else
|
155
|
-
Response.new(
|
156
|
-
end
|
166
|
+
Response.new(last_response, parse_response(last_response.body))
|
157
167
|
end
|
168
|
+
end
|
158
169
|
|
159
|
-
|
160
|
-
|
161
|
-
|
170
|
+
def parse_response(body)
|
171
|
+
parser.call(body, format)
|
172
|
+
end
|
162
173
|
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
174
|
+
def capture_cookies(response)
|
175
|
+
return unless response['Set-Cookie']
|
176
|
+
cookies_hash = HTTParty::CookieHash.new()
|
177
|
+
cookies_hash.add_cookies(options[:headers]['Cookie']) if options[:headers] && options[:headers]['Cookie']
|
178
|
+
cookies_hash.add_cookies(response['Set-Cookie'])
|
179
|
+
options[:headers] ||= {}
|
180
|
+
options[:headers]['Cookie'] = cookies_hash.to_cookie_string
|
181
|
+
end
|
171
182
|
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
end
|
183
|
+
# Uses the HTTP Content-Type header to determine the format of the
|
184
|
+
# response It compares the MIME type returned to the types stored in the
|
185
|
+
# SupportedFormats hash
|
186
|
+
def format_from_mimetype(mimetype)
|
187
|
+
if mimetype && parser.respond_to?(:format_from_mimetype)
|
188
|
+
parser.format_from_mimetype(mimetype)
|
179
189
|
end
|
190
|
+
end
|
180
191
|
|
181
192
|
def validate
|
182
193
|
raise HTTParty::RedirectionTooDeep.new(last_response), 'HTTP redirects too deep' if options[:limit].to_i <= 0
|
183
194
|
raise ArgumentError, 'only get, post, put, delete, head, and options methods are supported' unless SupportedHTTPMethods.include?(http_method)
|
184
195
|
raise ArgumentError, ':headers must be a hash' if options[:headers] && !options[:headers].is_a?(Hash)
|
196
|
+
raise ArgumentError, 'only one authentication method, :basic_auth or :digest_auth may be used at a time' if options[:basic_auth] && options[:digest_auth]
|
185
197
|
raise ArgumentError, ':basic_auth must be a hash' if options[:basic_auth] && !options[:basic_auth].is_a?(Hash)
|
198
|
+
raise ArgumentError, ':digest_auth must be a hash' if options[:digest_auth] && !options[:digest_auth].is_a?(Hash)
|
186
199
|
raise ArgumentError, ':query must be hash if using HTTP Post' if post? && !options[:query].nil? && !options[:query].is_a?(Hash)
|
187
200
|
end
|
188
201
|
|
189
|
-
|
190
|
-
|
191
|
-
|
202
|
+
def post?
|
203
|
+
Net::HTTP::Post == http_method
|
204
|
+
end
|
192
205
|
end
|
193
206
|
end
|
194
|
-
|
data/lib/httparty/response.rb
CHANGED
@@ -1,18 +1,62 @@
|
|
1
1
|
module HTTParty
|
2
2
|
class Response < HTTParty::BasicObject #:nodoc:
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
3
|
+
class Headers
|
4
|
+
include Net::HTTPHeader
|
5
|
+
|
6
|
+
def initialize(header)
|
7
|
+
@header = header
|
8
|
+
end
|
9
|
+
|
10
|
+
def ==(other)
|
11
|
+
@header == other
|
12
|
+
end
|
13
|
+
|
14
|
+
def inspect
|
15
|
+
@header.inspect
|
16
|
+
end
|
17
|
+
|
18
|
+
def method_missing(name, *args, &block)
|
19
|
+
if @header.respond_to?(name)
|
20
|
+
@header.send(name, *args, &block)
|
21
|
+
else
|
22
|
+
super
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def respond_to?(method)
|
27
|
+
super || @header.respond_to?(method)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
attr_reader :response, :parsed_response, :body, :headers
|
32
|
+
|
33
|
+
def initialize(response, parsed_response)
|
34
|
+
@response = response
|
35
|
+
@body = response.body
|
36
|
+
@parsed_response = parsed_response
|
37
|
+
@headers = Headers.new(response.to_hash)
|
38
|
+
end
|
39
|
+
|
40
|
+
def class
|
41
|
+
Object.instance_method(:class).bind(self).call
|
42
|
+
end
|
43
|
+
|
44
|
+
def code
|
45
|
+
response.code.to_i
|
46
|
+
end
|
47
|
+
|
48
|
+
def inspect
|
49
|
+
%(<#{self.class} @response=#{response.inspect}>)
|
12
50
|
end
|
13
51
|
|
14
52
|
def method_missing(name, *args, &block)
|
15
|
-
|
53
|
+
if parsed_response.respond_to?(name)
|
54
|
+
parsed_response.send(name, *args, &block)
|
55
|
+
elsif response.respond_to?(name)
|
56
|
+
response.send(name, *args, &block)
|
57
|
+
else
|
58
|
+
super
|
59
|
+
end
|
16
60
|
end
|
17
61
|
end
|
18
62
|
end
|
@@ -30,6 +30,17 @@ describe HTTParty::Request do
|
|
30
30
|
@request.send(:setup_raw_request)
|
31
31
|
@request.instance_variable_get(:@raw_request)['authorization'].should_not be_nil
|
32
32
|
end
|
33
|
+
|
34
|
+
it "should use digest auth when configured" do
|
35
|
+
FakeWeb.register_uri(:head, "http://api.foo.com/v1",
|
36
|
+
:www_authenticate => 'Digest realm="Log Viewer", qop="auth", nonce="2CA0EC6B0E126C4800E56BA0C0003D3C", opaque="5ccc069c403ebaf9f0171e9517f40e41", stale=false')
|
37
|
+
|
38
|
+
@request.options[:digest_auth] = {:username => 'foobar', :password => 'secret'}
|
39
|
+
@request.send(:setup_raw_request)
|
40
|
+
|
41
|
+
raw_request = @request.instance_variable_get(:@raw_request)
|
42
|
+
raw_request.instance_variable_get(:@header)['Authorization'].should_not be_nil
|
43
|
+
end
|
33
44
|
end
|
34
45
|
|
35
46
|
describe "#uri" do
|
@@ -353,6 +364,13 @@ describe HTTParty::Request do
|
|
353
364
|
@request.perform.should == {"hash" => {"foo" => "bar"}}
|
354
365
|
@request.http_method.should == Net::HTTP::Get
|
355
366
|
end
|
367
|
+
|
368
|
+
it 'should not make resulting request a get request if options[:maintain_method_across_redirects] is true' do
|
369
|
+
@request.options[:maintain_method_across_redirects] = true
|
370
|
+
@request.http_method = Net::HTTP::Delete
|
371
|
+
@request.perform.should == {"hash" => {"foo" => "bar"}}
|
372
|
+
@request.http_method.should == Net::HTTP::Delete
|
373
|
+
end
|
356
374
|
end
|
357
375
|
|
358
376
|
describe "infinitely" do
|
@@ -373,5 +391,25 @@ describe HTTParty::Request do
|
|
373
391
|
}.should raise_error(ArgumentError)
|
374
392
|
end
|
375
393
|
end
|
394
|
+
|
395
|
+
describe "argument validation" do
|
396
|
+
it "should raise argument error if basic_auth and digest_auth are both present" do
|
397
|
+
lambda {
|
398
|
+
HTTParty::Request.new(Net::HTTP::Post, 'http://api.foo.com/v1', :basic_auth => {}, :digest_auth => {}).perform
|
399
|
+
}.should raise_error(ArgumentError, "only one authentication method, :basic_auth or :digest_auth may be used at a time")
|
400
|
+
end
|
401
|
+
|
402
|
+
it "should raise argument error if basic_auth is not a hash" do
|
403
|
+
lambda {
|
404
|
+
HTTParty::Request.new(Net::HTTP::Post, 'http://api.foo.com/v1', :basic_auth => ["foo", "bar"]).perform
|
405
|
+
}.should raise_error(ArgumentError, ":basic_auth must be a hash")
|
406
|
+
end
|
407
|
+
|
408
|
+
it "should raise argument error if digest_auth is not a hash" do
|
409
|
+
lambda {
|
410
|
+
HTTParty::Request.new(Net::HTTP::Post, 'http://api.foo.com/v1', :digest_auth => ["foo", "bar"]).perform
|
411
|
+
}.should raise_error(ArgumentError, ":digest_auth must be a hash")
|
412
|
+
end
|
413
|
+
end
|
376
414
|
end
|
377
415
|
|
@@ -1,62 +1,83 @@
|
|
1
1
|
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'spec_helper'))
|
2
2
|
|
3
3
|
describe HTTParty::Response do
|
4
|
+
before do
|
5
|
+
@last_modified = Date.new(2010, 1, 15).to_s
|
6
|
+
@content_length = '1024'
|
7
|
+
@response_object = {'foo' => 'bar'}
|
8
|
+
@response_object = Net::HTTPOK.new('1.1', 200, 'OK')
|
9
|
+
@response_object.stub(:body => "{foo:'bar'}")
|
10
|
+
@response_object['last-modified'] = @last_modified
|
11
|
+
@response_object['content-length'] = @content_length
|
12
|
+
@parsed_response = {"foo" => "bar"}
|
13
|
+
@response = HTTParty::Response.new(@response_object, @parsed_response)
|
14
|
+
end
|
15
|
+
|
4
16
|
describe "initialization" do
|
5
|
-
|
6
|
-
@
|
7
|
-
@body = "{foo:'bar'}"
|
8
|
-
@code = '200'
|
9
|
-
@message = 'OK'
|
10
|
-
@response = HTTParty::Response.new(@response_object, @body, @code, @message)
|
11
|
-
end
|
12
|
-
|
13
|
-
it "should set delegate" do
|
14
|
-
@response.delegate.should == @response_object
|
17
|
+
it "should set the Net::HTTP Response" do
|
18
|
+
@response.response.should == @response_object
|
15
19
|
end
|
16
|
-
|
20
|
+
|
17
21
|
it "should set body" do
|
18
|
-
@response.body.should == @body
|
22
|
+
@response.body.should == @response_object.body
|
19
23
|
end
|
20
|
-
|
24
|
+
|
21
25
|
it "should set code" do
|
22
|
-
@response.code.should.to_s == @code
|
26
|
+
@response.code.should.to_s == @response_object.code
|
23
27
|
end
|
24
28
|
|
25
29
|
it "should set code as a Fixnum" do
|
26
30
|
@response.code.should be_an_instance_of(Fixnum)
|
27
31
|
end
|
28
|
-
|
29
|
-
it "should set body" do
|
30
|
-
@response.body.should == @body
|
31
|
-
end
|
32
32
|
end
|
33
|
-
|
34
|
-
it "
|
35
|
-
response = HTTParty::Response.new(
|
36
|
-
response.headers.should == {'
|
33
|
+
|
34
|
+
it "returns response headers" do
|
35
|
+
response = HTTParty::Response.new(@response_object, @parsed_response)
|
36
|
+
response.headers.should == {'last-modified' => [@last_modified], 'content-length' => [@content_length]}
|
37
37
|
end
|
38
|
-
|
38
|
+
|
39
39
|
it "should send missing methods to delegate" do
|
40
|
-
response = HTTParty::Response.new({'foo' => 'bar'}
|
40
|
+
response = HTTParty::Response.new(@response_object, {'foo' => 'bar'})
|
41
41
|
response['foo'].should == 'bar'
|
42
42
|
end
|
43
|
-
|
44
|
-
it "should be able to iterate
|
45
|
-
response = HTTParty::Response.new([{'foo' => 'bar'}, {'foo' => 'baz'}]
|
43
|
+
|
44
|
+
it "should be able to iterate if it is array" do
|
45
|
+
response = HTTParty::Response.new(@response_object, [{'foo' => 'bar'}, {'foo' => 'baz'}])
|
46
46
|
response.size.should == 2
|
47
|
-
|
47
|
+
expect {
|
48
48
|
response.each { |item| }
|
49
|
-
}.
|
49
|
+
}.to_not raise_error
|
50
|
+
end
|
51
|
+
|
52
|
+
it "allows headers to be accessed by mixed-case names in hash notation" do
|
53
|
+
response = HTTParty::Response.new(@response_object, @parsed_response)
|
54
|
+
response.headers['Content-LENGTH'].should == @content_length
|
55
|
+
end
|
56
|
+
|
57
|
+
it "returns a comma-delimited value when multiple values exist" do
|
58
|
+
@response_object.add_field 'set-cookie', 'csrf_id=12345; path=/'
|
59
|
+
@response_object.add_field 'set-cookie', '_github_ses=A123CdE; path=/'
|
60
|
+
response = HTTParty::Response.new(@response_object, @parsed_response)
|
61
|
+
response.headers['set-cookie'].should == "csrf_id=12345; path=/, _github_ses=A123CdE; path=/"
|
50
62
|
end
|
51
|
-
|
63
|
+
|
64
|
+
# Backwards-compatibility - previously, #headers returned a Hash
|
65
|
+
it "responds to hash methods" do
|
66
|
+
response = HTTParty::Response.new(@response_object, @parsed_response)
|
67
|
+
hash_methods = {}.methods - response.headers.methods
|
68
|
+
hash_methods.each do |method_name|
|
69
|
+
response.headers.respond_to?(method_name).should be_true
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
52
73
|
xit "should allow hashes to be accessed with dot notation" do
|
53
74
|
response = HTTParty::Response.new({'foo' => 'bar'}, "{foo:'bar'}", 200, 'OK')
|
54
75
|
response.foo.should == 'bar'
|
55
76
|
end
|
56
|
-
|
77
|
+
|
57
78
|
xit "should allow nested hashes to be accessed with dot notation" do
|
58
79
|
response = HTTParty::Response.new({'foo' => {'bar' => 'baz'}}, "{foo: {bar:'baz'}}", 200, 'OK')
|
59
80
|
response.foo.should == {'bar' => 'baz'}
|
60
81
|
response.foo.bar.should == 'baz'
|
61
82
|
end
|
62
|
-
end
|
83
|
+
end
|
data/spec/httparty_spec.rb
CHANGED
@@ -203,6 +203,17 @@ describe HTTParty do
|
|
203
203
|
end
|
204
204
|
end
|
205
205
|
|
206
|
+
describe "default timeout" do
|
207
|
+
it "should default to nil" do
|
208
|
+
@klass.default_options[:timeout].should == nil
|
209
|
+
end
|
210
|
+
|
211
|
+
it "should support updating" do
|
212
|
+
@klass.default_timeout 10
|
213
|
+
@klass.default_options[:timeout].should == 10
|
214
|
+
end
|
215
|
+
end
|
216
|
+
|
206
217
|
describe "debug_output" do
|
207
218
|
it "stores the given stream as a default_option" do
|
208
219
|
@klass.debug_output $stdout
|
@@ -222,6 +233,13 @@ describe HTTParty do
|
|
222
233
|
end
|
223
234
|
end
|
224
235
|
|
236
|
+
describe "digest http authentication" do
|
237
|
+
it "should work" do
|
238
|
+
@klass.digest_auth 'foobar', 'secret'
|
239
|
+
@klass.default_options[:digest_auth].should == {:username => 'foobar', :password => 'secret'}
|
240
|
+
end
|
241
|
+
end
|
242
|
+
|
225
243
|
describe "parser" do
|
226
244
|
let(:parser) do
|
227
245
|
Proc.new{ |data, format| CustomParser.parse(data) }
|
@@ -243,7 +261,7 @@ describe HTTParty do
|
|
243
261
|
@klass.format :json
|
244
262
|
class MyParser < HTTParty::Parser
|
245
263
|
SupportedFormats = {}
|
246
|
-
end
|
264
|
+
end unless defined?(MyParser)
|
247
265
|
expect do
|
248
266
|
@klass.parser MyParser
|
249
267
|
end.to raise_error(HTTParty::UnsupportedFormat)
|
@@ -316,6 +334,18 @@ describe HTTParty do
|
|
316
334
|
end
|
317
335
|
end
|
318
336
|
|
337
|
+
describe "#maintain_method_across_redirects" do
|
338
|
+
it "sets maintain_method_across_redirects to true by default" do
|
339
|
+
@klass.maintain_method_across_redirects
|
340
|
+
@klass.default_options[:maintain_method_across_redirects].should be_true
|
341
|
+
end
|
342
|
+
|
343
|
+
it "sets the maintain_method_across_redirects option to false" do
|
344
|
+
@klass.maintain_method_across_redirects false
|
345
|
+
@klass.default_options[:maintain_method_across_redirects].should be_false
|
346
|
+
end
|
347
|
+
end
|
348
|
+
|
319
349
|
describe "with explicit override of automatic redirect handling" do
|
320
350
|
before do
|
321
351
|
@request = HTTParty::Request.new(Net::HTTP::Get, 'http://api.foo.com/v1', :format => :xml, :no_follow => true)
|
data/spec/spec_helper.rb
CHANGED
@@ -2,8 +2,6 @@ require File.join(File.dirname(__FILE__), '..', 'lib', 'httparty')
|
|
2
2
|
require 'spec/autorun'
|
3
3
|
require 'fakeweb'
|
4
4
|
|
5
|
-
FakeWeb.allow_net_connect = false
|
6
|
-
|
7
5
|
def file_fixture(filename)
|
8
6
|
open(File.join(File.dirname(__FILE__), 'fixtures', "#{filename.to_s}")).read
|
9
7
|
end
|
@@ -12,4 +10,10 @@ Dir[File.expand_path(File.join(File.dirname(__FILE__),'support','**','*.rb'))].e
|
|
12
10
|
|
13
11
|
Spec::Runner.configure do |config|
|
14
12
|
config.include HTTParty::StubResponse
|
13
|
+
config.before(:suite) do
|
14
|
+
FakeWeb.allow_net_connect = false
|
15
|
+
end
|
16
|
+
config.after(:suite) do
|
17
|
+
FakeWeb.allow_net_connect = true
|
18
|
+
end
|
15
19
|
end
|
@@ -14,7 +14,7 @@ module HTTParty
|
|
14
14
|
end
|
15
15
|
|
16
16
|
def stub_response(body, code = 200)
|
17
|
-
unless @http
|
17
|
+
unless defined?(@http) && @http
|
18
18
|
@http = Net::HTTP.new('localhost', 80)
|
19
19
|
@request.stub!(:http).and_return(@http)
|
20
20
|
@request.stub!(:uri).and_return(URI.parse("http://foo.com/foobar"))
|
metadata
CHANGED
@@ -5,9 +5,9 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
segments:
|
6
6
|
- 0
|
7
7
|
- 5
|
8
|
-
- 2
|
9
8
|
- 3
|
10
|
-
|
9
|
+
- 4
|
10
|
+
version: 0.5.3.4
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- John Nunemaker
|
@@ -16,7 +16,7 @@ autorequire:
|
|
16
16
|
bindir: bin
|
17
17
|
cert_chain: []
|
18
18
|
|
19
|
-
date: 2010-
|
19
|
+
date: 2010-05-26 00:00:00 +08:00
|
20
20
|
default_executable: httparty
|
21
21
|
dependencies:
|
22
22
|
- !ruby/object:Gem::Dependency
|
@@ -29,8 +29,8 @@ dependencies:
|
|
29
29
|
segments:
|
30
30
|
- 0
|
31
31
|
- 1
|
32
|
-
-
|
33
|
-
version: 0.1.
|
32
|
+
- 7
|
33
|
+
version: 0.1.7
|
34
34
|
type: :runtime
|
35
35
|
version_requirements: *id001
|
36
36
|
- !ruby/object:Gem::Dependency
|
@@ -55,8 +55,8 @@ dependencies:
|
|
55
55
|
- !ruby/object:Gem::Version
|
56
56
|
segments:
|
57
57
|
- 0
|
58
|
-
-
|
59
|
-
version: "0.
|
58
|
+
- 7
|
59
|
+
version: "0.7"
|
60
60
|
type: :development
|
61
61
|
version_requirements: *id003
|
62
62
|
- !ruby/object:Gem::Dependency
|
@@ -90,13 +90,12 @@ dependencies:
|
|
90
90
|
prerelease: false
|
91
91
|
requirement: &id006 !ruby/object:Gem::Requirement
|
92
92
|
requirements:
|
93
|
-
- -
|
93
|
+
- - ~>
|
94
94
|
- !ruby/object:Gem::Version
|
95
95
|
segments:
|
96
96
|
- 1
|
97
|
-
-
|
98
|
-
|
99
|
-
version: 1.2.9
|
97
|
+
- 3
|
98
|
+
version: "1.3"
|
100
99
|
type: :development
|
101
100
|
version_requirements: *id006
|
102
101
|
description: Makes http fun! Also, makes consuming restful web services dead easy.
|
@@ -128,6 +127,7 @@ files:
|
|
128
127
|
- features/basic_authentication.feature
|
129
128
|
- features/command_line.feature
|
130
129
|
- features/deals_with_http_error_codes.feature
|
130
|
+
- features/digest_authentication.feature
|
131
131
|
- features/handles_multiple_formats.feature
|
132
132
|
- features/steps/env.rb
|
133
133
|
- features/steps/httparty_response_steps.rb
|
@@ -142,6 +142,7 @@ files:
|
|
142
142
|
- lib/httparty/core_extensions.rb
|
143
143
|
- lib/httparty/exceptions.rb
|
144
144
|
- lib/httparty/module_inheritable_attributes.rb
|
145
|
+
- lib/httparty/net_digest_auth.rb
|
145
146
|
- lib/httparty/parser.rb
|
146
147
|
- lib/httparty/request.rb
|
147
148
|
- lib/httparty/response.rb
|
@@ -162,7 +163,7 @@ files:
|
|
162
163
|
- website/css/common.css
|
163
164
|
- website/index.html
|
164
165
|
has_rdoc: true
|
165
|
-
homepage: http://httparty
|
166
|
+
homepage: http://github.com/jugend/httparty
|
166
167
|
licenses: []
|
167
168
|
|
168
169
|
post_install_message: When you HTTParty, you must party hard!
|