httparty 0.13.3 → 0.13.4
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.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.rubocop.yml +92 -0
- data/.rubocop_todo.yml +124 -0
- data/.simplecov +1 -0
- data/Gemfile +8 -3
- data/Guardfile +1 -1
- data/README.md +1 -0
- data/Rakefile +4 -5
- data/bin/httparty +9 -10
- data/examples/README.md +3 -0
- data/examples/aaws.rb +2 -2
- data/examples/crack.rb +1 -1
- data/examples/custom_parsers.rb +1 -4
- data/examples/delicious.rb +3 -3
- data/examples/google.rb +2 -2
- data/examples/logging.rb +5 -7
- data/examples/nokogiri_html_parser.rb +0 -3
- data/examples/rescue_json.rb +17 -0
- data/examples/rubyurl.rb +3 -3
- data/examples/twitter.rb +2 -2
- data/examples/whoismyrep.rb +1 -1
- data/features/command_line.feature +85 -2
- data/features/steps/env.rb +16 -11
- data/features/steps/httparty_response_steps.rb +13 -13
- data/features/steps/mongrel_helper.rb +2 -2
- data/features/steps/remote_service_steps.rb +18 -6
- data/httparty.gemspec +4 -4
- data/lib/httparty.rb +37 -56
- data/lib/httparty/connection_adapter.rb +3 -4
- data/lib/httparty/cookie_hash.rb +2 -3
- data/lib/httparty/hash_conversions.rb +3 -5
- data/lib/httparty/logger/apache_logger.rb +1 -1
- data/lib/httparty/logger/logger.rb +1 -1
- data/lib/httparty/module_inheritable_attributes.rb +1 -1
- data/lib/httparty/net_digest_auth.rb +46 -16
- data/lib/httparty/request.rb +16 -16
- data/lib/httparty/response.rb +9 -4
- data/lib/httparty/version.rb +1 -1
- data/spec/httparty/connection_adapter_spec.rb +184 -100
- data/spec/httparty/cookie_hash_spec.rb +21 -21
- data/spec/httparty/exception_spec.rb +22 -7
- data/spec/httparty/hash_conversions_spec.rb +41 -0
- data/spec/httparty/logger/apache_logger_spec.rb +3 -3
- data/spec/httparty/logger/curl_logger_spec.rb +2 -2
- data/spec/httparty/logger/logger_spec.rb +7 -7
- data/spec/httparty/net_digest_auth_spec.rb +60 -32
- data/spec/httparty/parser_spec.rb +37 -35
- data/spec/httparty/request_spec.rb +249 -193
- data/spec/httparty/response_spec.rb +37 -29
- data/spec/httparty/ssl_spec.rb +21 -21
- data/spec/httparty_spec.rb +153 -164
- data/spec/spec_helper.rb +34 -12
- data/spec/support/ssl_test_helper.rb +2 -2
- data/spec/support/ssl_test_server.rb +21 -21
- data/spec/support/stub_response.rb +10 -10
- metadata +9 -4
- data/lib/httparty/core_extensions.rb +0 -32
@@ -50,7 +50,6 @@ module HTTParty
|
|
50
50
|
# * :+ssl_ca_path+: see HTTParty::ClassMethods.ssl_ca_path.
|
51
51
|
# * :+connection_adapter_options+: contains the hash you passed to HTTParty.connection_adapter when you configured your connection adapter
|
52
52
|
class ConnectionAdapter
|
53
|
-
|
54
53
|
# Private: Regex used to strip brackets from IPv6 URIs.
|
55
54
|
StripIpv6BracketsRegex = /\A\[(.*)\]\z/
|
56
55
|
|
@@ -61,8 +60,8 @@ module HTTParty
|
|
61
60
|
|
62
61
|
attr_reader :uri, :options
|
63
62
|
|
64
|
-
def initialize(uri, options={})
|
65
|
-
raise ArgumentError, "uri must be a URI, not a #{uri.class}" unless uri.
|
63
|
+
def initialize(uri, options = {})
|
64
|
+
raise ArgumentError, "uri must be a URI, not a #{uri.class}" unless uri.is_a? URI
|
66
65
|
|
67
66
|
@uri = uri
|
68
67
|
@options = options
|
@@ -120,7 +119,7 @@ module HTTParty
|
|
120
119
|
end
|
121
120
|
end
|
122
121
|
|
123
|
-
|
122
|
+
http
|
124
123
|
end
|
125
124
|
|
126
125
|
private
|
data/lib/httparty/cookie_hash.rb
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
class HTTParty::CookieHash < Hash #:nodoc:
|
2
|
-
|
3
|
-
CLIENT_COOKIES = %w{path expires domain path secure httponly}
|
2
|
+
CLIENT_COOKIES = %w(path expires domain path secure httponly)
|
4
3
|
|
5
4
|
def add_cookies(value)
|
6
5
|
case value
|
@@ -8,7 +7,7 @@ class HTTParty::CookieHash < Hash #:nodoc:
|
|
8
7
|
merge!(value)
|
9
8
|
when String
|
10
9
|
value.split('; ').each do |cookie|
|
11
|
-
array = cookie.split('=',2)
|
10
|
+
array = cookie.split('=', 2)
|
12
11
|
self[array[0].to_sym] = array[1]
|
13
12
|
end
|
14
13
|
else
|
@@ -12,9 +12,7 @@ module HTTParty
|
|
12
12
|
# }.to_params
|
13
13
|
# #=> "name=Bob&address[city]=Ruby Central&address[phones][]=111-111-1111&address[phones][]=222-222-2222&address[street]=111 Ruby Ave."
|
14
14
|
def self.to_params(hash)
|
15
|
-
|
16
|
-
params.chop! # trailing &
|
17
|
-
params
|
15
|
+
hash.to_hash.map { |k, v| normalize_param(k, v) }.join.chop
|
18
16
|
end
|
19
17
|
|
20
18
|
# @param key<Object> The key for the param.
|
@@ -30,9 +28,9 @@ module HTTParty
|
|
30
28
|
if value.respond_to?(:to_ary)
|
31
29
|
param << value.to_ary.map { |element| normalize_param("#{key}[]", element) }.join
|
32
30
|
elsif value.respond_to?(:to_hash)
|
33
|
-
stack << [key,value.to_hash]
|
31
|
+
stack << [key, value.to_hash]
|
34
32
|
else
|
35
|
-
param << "#{key}=#{
|
33
|
+
param << "#{key}=#{ERB::Util.url_encode(value.to_s)}&"
|
36
34
|
end
|
37
35
|
|
38
36
|
stack.each do |parent, hash|
|
@@ -15,7 +15,7 @@ module HTTParty
|
|
15
15
|
http_method = request.http_method.name.split("::").last.upcase
|
16
16
|
path = request.path.to_s
|
17
17
|
content_length = response.respond_to?(:headers) ? response.headers['Content-Length'] : response['Content-Length']
|
18
|
-
@logger.send @level, "[#{TAG_NAME}] [#{current_time}] #{response.code} \"#{http_method} #{path}\" #{content_length ||
|
18
|
+
@logger.send @level, "[#{TAG_NAME}] [#{current_time}] #{response.code} \"#{http_method} #{path}\" #{content_length || '-'} "
|
19
19
|
end
|
20
20
|
end
|
21
21
|
end
|
@@ -4,10 +4,22 @@ require 'net/http'
|
|
4
4
|
module Net
|
5
5
|
module HTTPHeader
|
6
6
|
def digest_auth(username, password, response)
|
7
|
-
|
8
|
-
|
7
|
+
authenticator = DigestAuthenticator.new(
|
8
|
+
username,
|
9
|
+
password,
|
10
|
+
@method,
|
11
|
+
@path,
|
12
|
+
response
|
13
|
+
)
|
14
|
+
|
15
|
+
@header['Authorization'] = authenticator.authorization_header
|
16
|
+
@header['cookie'] = append_cookies(authenticator) if response['Set-Cookie']
|
9
17
|
end
|
10
18
|
|
19
|
+
def append_cookies(authenticator)
|
20
|
+
cookies = @header['cookie'] ? @header['cookie'] : []
|
21
|
+
cookies.concat(authenticator.cookie_header)
|
22
|
+
end
|
11
23
|
|
12
24
|
class DigestAuthenticator
|
13
25
|
def initialize(username, password, method, path, response_header)
|
@@ -16,36 +28,41 @@ module Net
|
|
16
28
|
@method = method
|
17
29
|
@path = path
|
18
30
|
@response = parse(response_header)
|
31
|
+
@cookies = parse_cookies(response_header)
|
19
32
|
end
|
20
33
|
|
21
34
|
def authorization_header
|
22
35
|
@cnonce = md5(random)
|
23
36
|
header = [
|
24
|
-
%
|
25
|
-
%
|
26
|
-
%
|
27
|
-
%
|
28
|
-
%
|
37
|
+
%(Digest username="#{@username}"),
|
38
|
+
%(realm="#{@response['realm']}"),
|
39
|
+
%(nonce="#{@response['nonce']}"),
|
40
|
+
%(uri="#{@path}"),
|
41
|
+
%(response="#{request_digest}")
|
29
42
|
]
|
30
43
|
|
31
44
|
if qop_present?
|
32
45
|
fields = [
|
33
|
-
%
|
34
|
-
%
|
35
|
-
|
46
|
+
%(cnonce="#{@cnonce}"),
|
47
|
+
%(qop="#{@response['qop']}"),
|
48
|
+
"nc=00000001"
|
36
49
|
]
|
37
50
|
fields.each { |field| header << field }
|
38
51
|
end
|
39
52
|
|
40
|
-
header << %
|
53
|
+
header << %(opaque="#{@response['opaque']}") if opaque_present?
|
41
54
|
header
|
42
55
|
end
|
43
56
|
|
44
|
-
|
57
|
+
def cookie_header
|
58
|
+
@cookies
|
59
|
+
end
|
60
|
+
|
61
|
+
private
|
45
62
|
|
46
63
|
def parse(response_header)
|
47
64
|
header = response_header['www-authenticate']
|
48
|
-
|
65
|
+
.gsub(/qop=(auth(?:-int)?)/, 'qop="\\1"')
|
49
66
|
|
50
67
|
header =~ /Digest (.*)/
|
51
68
|
params = {}
|
@@ -53,16 +70,29 @@ module Net
|
|
53
70
|
params
|
54
71
|
end
|
55
72
|
|
73
|
+
def parse_cookies(response_header)
|
74
|
+
return [] unless response_header['Set-Cookie']
|
75
|
+
|
76
|
+
cookies = response_header['Set-Cookie'].split('; ')
|
77
|
+
|
78
|
+
cookies.reduce([]) do |ret, cookie|
|
79
|
+
ret << cookie
|
80
|
+
ret
|
81
|
+
end
|
82
|
+
|
83
|
+
cookies
|
84
|
+
end
|
85
|
+
|
56
86
|
def opaque_present?
|
57
|
-
@response.
|
87
|
+
@response.key?('opaque') && !@response['opaque'].empty?
|
58
88
|
end
|
59
89
|
|
60
90
|
def qop_present?
|
61
|
-
@response.
|
91
|
+
@response.key?('qop') && !@response['qop'].empty?
|
62
92
|
end
|
63
93
|
|
64
94
|
def random
|
65
|
-
"%x"
|
95
|
+
format "%x", (Time.now.to_i + rand(65535))
|
66
96
|
end
|
67
97
|
|
68
98
|
def request_digest
|
data/lib/httparty/request.rb
CHANGED
@@ -14,12 +14,12 @@ module HTTParty
|
|
14
14
|
|
15
15
|
SupportedURISchemes = [URI::HTTP, URI::HTTPS, URI::Generic]
|
16
16
|
|
17
|
-
NON_RAILS_QUERY_STRING_NORMALIZER =
|
17
|
+
NON_RAILS_QUERY_STRING_NORMALIZER = proc do |query|
|
18
18
|
Array(query).sort_by { |a| a[0].to_s }.map do |key, value|
|
19
19
|
if value.nil?
|
20
20
|
key.to_s
|
21
21
|
elsif value.respond_to?(:to_ary)
|
22
|
-
value.to_ary.map {|v| "#{key}=#{
|
22
|
+
value.to_ary.map {|v| "#{key}=#{ERB::Util.url_encode(v.to_s)}"}
|
23
23
|
else
|
24
24
|
HashConversions.to_params(key => value)
|
25
25
|
end
|
@@ -29,7 +29,7 @@ module HTTParty
|
|
29
29
|
attr_accessor :http_method, :options, :last_response, :redirect, :last_uri
|
30
30
|
attr_reader :path
|
31
31
|
|
32
|
-
def initialize(http_method, path, o={})
|
32
|
+
def initialize(http_method, path, o = {})
|
33
33
|
self.http_method = http_method
|
34
34
|
self.path = path
|
35
35
|
self.options = {
|
@@ -57,7 +57,10 @@ module HTTParty
|
|
57
57
|
|
58
58
|
def uri
|
59
59
|
if redirect && path.relative? && path.path[0] != "/"
|
60
|
-
|
60
|
+
last_uri_host = @last_uri.path.gsub(/[^\/]+$/, "")
|
61
|
+
|
62
|
+
path.path = "/#{path.path}" if last_uri_host[-1] != "/"
|
63
|
+
path.path = last_uri_host + path.path
|
61
64
|
end
|
62
65
|
|
63
66
|
new_uri = path.relative? ? URI.parse("#{base_uri}#{path}") : path.clone
|
@@ -164,7 +167,7 @@ module HTTParty
|
|
164
167
|
auth_request.initialize_http_header(options[:headers].to_hash) if options[:headers].respond_to?(:to_hash)
|
165
168
|
res = http.request(auth_request)
|
166
169
|
|
167
|
-
if res['www-authenticate']
|
170
|
+
if !res['www-authenticate'].nil? && res['www-authenticate'].length > 0
|
168
171
|
@raw_request.digest_auth(username, password, res)
|
169
172
|
end
|
170
173
|
end
|
@@ -202,12 +205,10 @@ module HTTParty
|
|
202
205
|
end
|
203
206
|
|
204
207
|
def encode_with_ruby_encoding(body, charset)
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
body
|
210
|
-
end
|
208
|
+
encoding = Encoding.find(charset)
|
209
|
+
body.force_encoding(encoding)
|
210
|
+
rescue
|
211
|
+
body
|
211
212
|
end
|
212
213
|
|
213
214
|
def assume_utf16_is_big_endian
|
@@ -228,7 +229,6 @@ module HTTParty
|
|
228
229
|
else
|
229
230
|
body.force_encoding("UTF-16LE")
|
230
231
|
end
|
231
|
-
|
232
232
|
end
|
233
233
|
|
234
234
|
def _encode_body(body)
|
@@ -263,7 +263,7 @@ module HTTParty
|
|
263
263
|
self.path = last_response['location']
|
264
264
|
self.redirect = true
|
265
265
|
if last_response.class == Net::HTTPSeeOther
|
266
|
-
unless options[:maintain_method_across_redirects]
|
266
|
+
unless options[:maintain_method_across_redirects] && options[:resend_on_redirect]
|
267
267
|
self.http_method = Net::HTTP::Get
|
268
268
|
end
|
269
269
|
else
|
@@ -274,7 +274,7 @@ module HTTParty
|
|
274
274
|
capture_cookies(last_response)
|
275
275
|
perform(&block)
|
276
276
|
else
|
277
|
-
body
|
277
|
+
body ||= last_response.body
|
278
278
|
body = encode_body(body)
|
279
279
|
Response.new(self, last_response, lambda { parse_response(body) }, body: body)
|
280
280
|
end
|
@@ -311,7 +311,7 @@ module HTTParty
|
|
311
311
|
|
312
312
|
def capture_cookies(response)
|
313
313
|
return unless response['Set-Cookie']
|
314
|
-
cookies_hash = HTTParty::CookieHash.new
|
314
|
+
cookies_hash = HTTParty::CookieHash.new
|
315
315
|
cookies_hash.add_cookies(options[:headers].to_hash['Cookie']) if options[:headers] && options[:headers].to_hash['Cookie']
|
316
316
|
response.get_fields('Set-Cookie').each { |cookie| cookies_hash.add_cookies(cookie) }
|
317
317
|
options[:headers] ||= {}
|
@@ -344,7 +344,7 @@ module HTTParty
|
|
344
344
|
def set_basic_auth_from_uri
|
345
345
|
if path.userinfo
|
346
346
|
username, password = path.userinfo.split(':')
|
347
|
-
options[:basic_auth] = {:
|
347
|
+
options[:basic_auth] = {username: username, password: password}
|
348
348
|
end
|
349
349
|
end
|
350
350
|
end
|
data/lib/httparty/response.rb
CHANGED
@@ -1,12 +1,12 @@
|
|
1
1
|
module HTTParty
|
2
|
-
class Response <
|
2
|
+
class Response < BasicObject
|
3
3
|
def self.underscore(string)
|
4
|
-
string.gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').gsub(/([a-z])([A-Z])/,'\1_\2').downcase
|
4
|
+
string.gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2').gsub(/([a-z])([A-Z])/, '\1_\2').downcase
|
5
5
|
end
|
6
6
|
|
7
7
|
attr_reader :request, :response, :body, :headers
|
8
8
|
|
9
|
-
def initialize(request, response, parsed_block, options={})
|
9
|
+
def initialize(request, response, parsed_block, options = {})
|
10
10
|
@request = request
|
11
11
|
@response = response
|
12
12
|
@body = options[:body] || response.body
|
@@ -31,8 +31,13 @@ module HTTParty
|
|
31
31
|
response.code.to_i
|
32
32
|
end
|
33
33
|
|
34
|
+
def tap
|
35
|
+
yield self
|
36
|
+
self
|
37
|
+
end
|
38
|
+
|
34
39
|
def inspect
|
35
|
-
inspect_id = "%x"
|
40
|
+
inspect_id = format "%x", (object_id * 2)
|
36
41
|
%(#<#{self.class}:0x#{inspect_id} parsed_response=#{parsed_response.inspect}, @response=#{response.inspect}, @headers=#{headers.inspect}>)
|
37
42
|
end
|
38
43
|
|
data/lib/httparty/version.rb
CHANGED
@@ -1,7 +1,6 @@
|
|
1
1
|
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'spec_helper'))
|
2
2
|
|
3
|
-
describe HTTParty::ConnectionAdapter do
|
4
|
-
|
3
|
+
RSpec.describe HTTParty::ConnectionAdapter do
|
5
4
|
describe "initialization" do
|
6
5
|
let(:uri) { URI 'http://www.google.com' }
|
7
6
|
it "takes a URI as input" do
|
@@ -18,7 +17,7 @@ describe HTTParty::ConnectionAdapter do
|
|
18
17
|
|
19
18
|
it "sets the uri" do
|
20
19
|
adapter = HTTParty::ConnectionAdapter.new(uri)
|
21
|
-
adapter.uri.
|
20
|
+
expect(adapter.uri).to be uri
|
22
21
|
end
|
23
22
|
|
24
23
|
it "also accepts an optional options hash" do
|
@@ -28,22 +27,22 @@ describe HTTParty::ConnectionAdapter do
|
|
28
27
|
it "sets the options" do
|
29
28
|
options = {foo: :bar}
|
30
29
|
adapter = HTTParty::ConnectionAdapter.new(uri, options)
|
31
|
-
adapter.options.
|
30
|
+
expect(adapter.options).to be options
|
32
31
|
end
|
33
32
|
end
|
34
33
|
|
35
34
|
describe ".call" do
|
36
35
|
it "generates an HTTParty::ConnectionAdapter instance with the given uri and options" do
|
37
|
-
HTTParty::ConnectionAdapter.
|
36
|
+
expect(HTTParty::ConnectionAdapter).to receive(:new).with(@uri, @options).and_return(double(connection: nil))
|
38
37
|
HTTParty::ConnectionAdapter.call(@uri, @options)
|
39
38
|
end
|
40
39
|
|
41
40
|
it "calls #connection on the connection adapter" do
|
42
|
-
adapter =
|
43
|
-
connection =
|
44
|
-
adapter.
|
45
|
-
HTTParty::ConnectionAdapter.
|
46
|
-
HTTParty::ConnectionAdapter.call(@uri, @options).
|
41
|
+
adapter = double('Adapter')
|
42
|
+
connection = double('Connection')
|
43
|
+
expect(adapter).to receive(:connection).and_return(connection)
|
44
|
+
allow(HTTParty::ConnectionAdapter).to receive_messages(new: adapter)
|
45
|
+
expect(HTTParty::ConnectionAdapter.call(@uri, @options)).to be connection
|
47
46
|
end
|
48
47
|
end
|
49
48
|
|
@@ -54,52 +53,51 @@ describe HTTParty::ConnectionAdapter do
|
|
54
53
|
|
55
54
|
describe "the resulting connection" do
|
56
55
|
subject { adapter.connection }
|
57
|
-
it {
|
56
|
+
it { is_expected.to be_an_instance_of Net::HTTP }
|
58
57
|
|
59
58
|
context "using port 80" do
|
60
59
|
let(:uri) { URI 'http://foobar.com' }
|
61
|
-
it {
|
60
|
+
it { is_expected.not_to use_ssl }
|
62
61
|
end
|
63
62
|
|
64
63
|
context "when dealing with ssl" do
|
65
64
|
let(:uri) { URI 'https://foobar.com' }
|
66
65
|
|
67
66
|
context "uses the system cert_store, by default" do
|
68
|
-
let(:system_cert_store) do
|
69
|
-
system_cert_store =
|
70
|
-
system_cert_store.
|
71
|
-
OpenSSL::X509::Store.
|
67
|
+
let!(:system_cert_store) do
|
68
|
+
system_cert_store = double('default_cert_store')
|
69
|
+
expect(system_cert_store).to receive(:set_default_paths)
|
70
|
+
expect(OpenSSL::X509::Store).to receive(:new).and_return(system_cert_store)
|
72
71
|
system_cert_store
|
73
72
|
end
|
74
|
-
it {
|
73
|
+
it { is_expected.to use_cert_store(system_cert_store) }
|
75
74
|
end
|
76
75
|
|
77
76
|
context "should use the specified cert store, when one is given" do
|
78
|
-
let(:custom_cert_store) {
|
77
|
+
let(:custom_cert_store) { double('custom_cert_store') }
|
79
78
|
let(:options) { {cert_store: custom_cert_store} }
|
80
|
-
it {
|
79
|
+
it { is_expected.to use_cert_store(custom_cert_store) }
|
81
80
|
end
|
82
81
|
|
83
82
|
context "using port 443 for ssl" do
|
84
83
|
let(:uri) { URI 'https://api.foo.com/v1:443' }
|
85
|
-
it {
|
84
|
+
it { is_expected.to use_ssl }
|
86
85
|
end
|
87
86
|
|
88
87
|
context "https scheme with default port" do
|
89
|
-
it {
|
88
|
+
it { is_expected.to use_ssl }
|
90
89
|
end
|
91
90
|
|
92
91
|
context "https scheme with non-standard port" do
|
93
92
|
let(:uri) { URI 'https://foobar.com:123456' }
|
94
|
-
it {
|
93
|
+
it { is_expected.to use_ssl }
|
95
94
|
end
|
96
95
|
|
97
|
-
|
98
96
|
context "when ssl version is set" do
|
99
97
|
let(:options) { {ssl_version: :TLSv1} }
|
100
98
|
|
101
99
|
it "sets ssl version" do
|
102
|
-
subject.ssl_version.
|
100
|
+
expect(subject.ssl_version).to eq(:TLSv1)
|
103
101
|
end
|
104
102
|
end if RUBY_VERSION > '1.9'
|
105
103
|
end
|
@@ -108,7 +106,7 @@ describe HTTParty::ConnectionAdapter do
|
|
108
106
|
let(:uri) { URI 'http://[fd00::1]' }
|
109
107
|
|
110
108
|
it "strips brackets from the address" do
|
111
|
-
subject.address.
|
109
|
+
expect(subject.address).to eq('fd00::1')
|
112
110
|
end
|
113
111
|
end
|
114
112
|
|
@@ -116,16 +114,21 @@ describe HTTParty::ConnectionAdapter do
|
|
116
114
|
let(:options) { {ciphers: 'RC4-SHA' } }
|
117
115
|
|
118
116
|
it "should set the ciphers on the connection" do
|
119
|
-
subject.ciphers.
|
117
|
+
expect(subject.ciphers).to eq('RC4-SHA')
|
120
118
|
end
|
121
119
|
end if RUBY_VERSION > '1.9'
|
122
120
|
|
123
121
|
context "when timeout is not set" do
|
124
122
|
it "doesn't set the timeout" do
|
125
|
-
http =
|
126
|
-
|
127
|
-
|
128
|
-
|
123
|
+
http = double(
|
124
|
+
"http",
|
125
|
+
:null_object => true,
|
126
|
+
:use_ssl= => false,
|
127
|
+
:use_ssl? => false
|
128
|
+
)
|
129
|
+
expect(http).not_to receive(:open_timeout=)
|
130
|
+
expect(http).not_to receive(:read_timeout=)
|
131
|
+
allow(Net::HTTP).to receive_messages(new: http)
|
129
132
|
|
130
133
|
adapter.connection
|
131
134
|
end
|
@@ -135,18 +138,30 @@ describe HTTParty::ConnectionAdapter do
|
|
135
138
|
context "to 5 seconds" do
|
136
139
|
let(:options) { {timeout: 5} }
|
137
140
|
|
138
|
-
|
139
|
-
|
141
|
+
describe '#open_timeout' do
|
142
|
+
subject { super().open_timeout }
|
143
|
+
it { is_expected.to eq(5) }
|
144
|
+
end
|
145
|
+
|
146
|
+
describe '#read_timeout' do
|
147
|
+
subject { super().read_timeout }
|
148
|
+
it { is_expected.to eq(5) }
|
149
|
+
end
|
140
150
|
end
|
141
151
|
|
142
152
|
context "and timeout is a string" do
|
143
153
|
let(:options) { {timeout: "five seconds"} }
|
144
154
|
|
145
155
|
it "doesn't set the timeout" do
|
146
|
-
http =
|
147
|
-
|
148
|
-
|
149
|
-
|
156
|
+
http = double(
|
157
|
+
"http",
|
158
|
+
:null_object => true,
|
159
|
+
:use_ssl= => false,
|
160
|
+
:use_ssl? => false
|
161
|
+
)
|
162
|
+
expect(http).not_to receive(:open_timeout=)
|
163
|
+
expect(http).not_to receive(:read_timeout=)
|
164
|
+
allow(Net::HTTP).to receive_messages(new: http)
|
150
165
|
|
151
166
|
adapter.connection
|
152
167
|
end
|
@@ -156,12 +171,21 @@ describe HTTParty::ConnectionAdapter do
|
|
156
171
|
context "when timeout is not set and read_timeout is set to 6 seconds" do
|
157
172
|
let(:options) { {read_timeout: 6} }
|
158
173
|
|
159
|
-
|
174
|
+
describe '#read_timeout' do
|
175
|
+
subject { super().read_timeout }
|
176
|
+
it { is_expected.to eq(6) }
|
177
|
+
end
|
160
178
|
|
161
179
|
it "should not set the open_timeout" do
|
162
|
-
http =
|
163
|
-
|
164
|
-
|
180
|
+
http = double(
|
181
|
+
"http",
|
182
|
+
:null_object => true,
|
183
|
+
:use_ssl= => false,
|
184
|
+
:use_ssl? => false,
|
185
|
+
:read_timeout= => 0
|
186
|
+
)
|
187
|
+
expect(http).not_to receive(:open_timeout=)
|
188
|
+
allow(Net::HTTP).to receive_messages(new: http)
|
165
189
|
adapter.connection
|
166
190
|
end
|
167
191
|
end
|
@@ -169,14 +193,28 @@ describe HTTParty::ConnectionAdapter do
|
|
169
193
|
context "when timeout is set and read_timeout is set to 6 seconds" do
|
170
194
|
let(:options) { {timeout: 5, read_timeout: 6} }
|
171
195
|
|
172
|
-
|
173
|
-
|
196
|
+
describe '#open_timeout' do
|
197
|
+
subject { super().open_timeout }
|
198
|
+
it { is_expected.to eq(5) }
|
199
|
+
end
|
200
|
+
|
201
|
+
describe '#read_timeout' do
|
202
|
+
subject { super().read_timeout }
|
203
|
+
it { is_expected.to eq(6) }
|
204
|
+
end
|
174
205
|
|
175
206
|
it "should override the timeout option" do
|
176
|
-
http =
|
177
|
-
|
178
|
-
|
179
|
-
|
207
|
+
http = double(
|
208
|
+
"http",
|
209
|
+
:null_object => true,
|
210
|
+
:use_ssl= => false,
|
211
|
+
:use_ssl? => false,
|
212
|
+
:read_timeout= => 0,
|
213
|
+
:open_timeout= => 0
|
214
|
+
)
|
215
|
+
expect(http).to receive(:open_timeout=)
|
216
|
+
expect(http).to receive(:read_timeout=).twice
|
217
|
+
allow(Net::HTTP).to receive_messages(new: http)
|
180
218
|
adapter.connection
|
181
219
|
end
|
182
220
|
end
|
@@ -184,12 +222,21 @@ describe HTTParty::ConnectionAdapter do
|
|
184
222
|
context "when timeout is not set and open_timeout is set to 7 seconds" do
|
185
223
|
let(:options) { {open_timeout: 7} }
|
186
224
|
|
187
|
-
|
225
|
+
describe '#open_timeout' do
|
226
|
+
subject { super().open_timeout }
|
227
|
+
it { is_expected.to eq(7) }
|
228
|
+
end
|
188
229
|
|
189
230
|
it "should not set the read_timeout" do
|
190
|
-
http =
|
191
|
-
|
192
|
-
|
231
|
+
http = double(
|
232
|
+
"http",
|
233
|
+
:null_object => true,
|
234
|
+
:use_ssl= => false,
|
235
|
+
:use_ssl? => false,
|
236
|
+
:open_timeout= => 0
|
237
|
+
)
|
238
|
+
expect(http).not_to receive(:read_timeout=)
|
239
|
+
allow(Net::HTTP).to receive_messages(new: http)
|
193
240
|
adapter.connection
|
194
241
|
end
|
195
242
|
end
|
@@ -197,14 +244,28 @@ describe HTTParty::ConnectionAdapter do
|
|
197
244
|
context "when timeout is set and open_timeout is set to 7 seconds" do
|
198
245
|
let(:options) { {timeout: 5, open_timeout: 7} }
|
199
246
|
|
200
|
-
|
201
|
-
|
247
|
+
describe '#open_timeout' do
|
248
|
+
subject { super().open_timeout }
|
249
|
+
it { is_expected.to eq(7) }
|
250
|
+
end
|
251
|
+
|
252
|
+
describe '#read_timeout' do
|
253
|
+
subject { super().read_timeout }
|
254
|
+
it { is_expected.to eq(5) }
|
255
|
+
end
|
202
256
|
|
203
257
|
it "should override the timeout option" do
|
204
|
-
http =
|
205
|
-
|
206
|
-
|
207
|
-
|
258
|
+
http = double(
|
259
|
+
"http",
|
260
|
+
:null_object => true,
|
261
|
+
:use_ssl= => false,
|
262
|
+
:use_ssl? => false,
|
263
|
+
:read_timeout= => 0,
|
264
|
+
:open_timeout= => 0
|
265
|
+
)
|
266
|
+
expect(http).to receive(:open_timeout=).twice
|
267
|
+
expect(http).to receive(:read_timeout=)
|
268
|
+
allow(Net::HTTP).to receive_messages(new: http)
|
208
269
|
adapter.connection
|
209
270
|
end
|
210
271
|
end
|
@@ -212,20 +273,20 @@ describe HTTParty::ConnectionAdapter do
|
|
212
273
|
context "when debug_output" do
|
213
274
|
let(:http) { Net::HTTP.new(uri) }
|
214
275
|
before do
|
215
|
-
Net::HTTP.
|
276
|
+
allow(Net::HTTP).to receive_messages(new: http)
|
216
277
|
end
|
217
278
|
|
218
279
|
context "is set to $stderr" do
|
219
280
|
let(:options) { {debug_output: $stderr} }
|
220
281
|
it "has debug output set" do
|
221
|
-
http.
|
282
|
+
expect(http).to receive(:set_debug_output).with($stderr)
|
222
283
|
adapter.connection
|
223
284
|
end
|
224
285
|
end
|
225
286
|
|
226
287
|
context "is not provided" do
|
227
288
|
it "does not set_debug_output" do
|
228
|
-
http.
|
289
|
+
expect(http).not_to receive(:set_debug_output)
|
229
290
|
adapter.connection
|
230
291
|
end
|
231
292
|
end
|
@@ -234,17 +295,33 @@ describe HTTParty::ConnectionAdapter do
|
|
234
295
|
context 'when providing proxy address and port' do
|
235
296
|
let(:options) { {http_proxyaddr: '1.2.3.4', http_proxyport: 8080} }
|
236
297
|
|
237
|
-
it {
|
238
|
-
|
239
|
-
|
298
|
+
it { is_expected.to be_a_proxy }
|
299
|
+
|
300
|
+
describe '#proxy_address' do
|
301
|
+
subject { super().proxy_address }
|
302
|
+
it { is_expected.to eq('1.2.3.4') }
|
303
|
+
end
|
304
|
+
|
305
|
+
describe '#proxy_port' do
|
306
|
+
subject { super().proxy_port }
|
307
|
+
it { is_expected.to eq(8080) }
|
308
|
+
end
|
240
309
|
|
241
310
|
context 'as well as proxy user and password' do
|
242
311
|
let(:options) do
|
243
312
|
{http_proxyaddr: '1.2.3.4', http_proxyport: 8080,
|
244
313
|
http_proxyuser: 'user', http_proxypass: 'pass'}
|
245
314
|
end
|
246
|
-
|
247
|
-
|
315
|
+
|
316
|
+
describe '#proxy_user' do
|
317
|
+
subject { super().proxy_user }
|
318
|
+
it { is_expected.to eq('user') }
|
319
|
+
end
|
320
|
+
|
321
|
+
describe '#proxy_pass' do
|
322
|
+
subject { super().proxy_pass }
|
323
|
+
it { is_expected.to eq('pass') }
|
324
|
+
end
|
248
325
|
end
|
249
326
|
end
|
250
327
|
|
@@ -253,7 +330,7 @@ describe HTTParty::ConnectionAdapter do
|
|
253
330
|
|
254
331
|
it "does not pass any proxy parameters to the connection" do
|
255
332
|
http = Net::HTTP.new("proxytest.com")
|
256
|
-
Net::HTTP.
|
333
|
+
expect(Net::HTTP).to receive(:new).once.with("proxytest.com", 80).and_return(http)
|
257
334
|
adapter.connection
|
258
335
|
end
|
259
336
|
end
|
@@ -261,8 +338,15 @@ describe HTTParty::ConnectionAdapter do
|
|
261
338
|
context 'when providing a local bind address and port' do
|
262
339
|
let(:options) { {local_host: "127.0.0.1", local_port: 12345 } }
|
263
340
|
|
264
|
-
|
265
|
-
|
341
|
+
describe '#local_host' do
|
342
|
+
subject { super().local_host }
|
343
|
+
it { is_expected.to eq('127.0.0.1') }
|
344
|
+
end
|
345
|
+
|
346
|
+
describe '#local_port' do
|
347
|
+
subject { super().local_port }
|
348
|
+
it { is_expected.to eq(12345) }
|
349
|
+
end
|
266
350
|
end if RUBY_VERSION >= '2.0'
|
267
351
|
|
268
352
|
context "when providing PEM certificates" do
|
@@ -271,28 +355,28 @@ describe HTTParty::ConnectionAdapter do
|
|
271
355
|
|
272
356
|
context "when scheme is https" do
|
273
357
|
let(:uri) { URI 'https://google.com' }
|
274
|
-
let(:cert) {
|
275
|
-
let(:key) {
|
358
|
+
let(:cert) { double("OpenSSL::X509::Certificate") }
|
359
|
+
let(:key) { double("OpenSSL::PKey::RSA") }
|
276
360
|
|
277
361
|
before do
|
278
|
-
OpenSSL::X509::Certificate.
|
279
|
-
OpenSSL::PKey::RSA.
|
362
|
+
expect(OpenSSL::X509::Certificate).to receive(:new).with(pem).and_return(cert)
|
363
|
+
expect(OpenSSL::PKey::RSA).to receive(:new).with(pem, "password").and_return(key)
|
280
364
|
end
|
281
365
|
|
282
366
|
it "uses the provided PEM certificate" do
|
283
|
-
subject.cert.
|
284
|
-
subject.key.
|
367
|
+
expect(subject.cert).to eq(cert)
|
368
|
+
expect(subject.key).to eq(key)
|
285
369
|
end
|
286
370
|
|
287
371
|
it "will verify the certificate" do
|
288
|
-
subject.verify_mode.
|
372
|
+
expect(subject.verify_mode).to eq(OpenSSL::SSL::VERIFY_PEER)
|
289
373
|
end
|
290
|
-
|
374
|
+
|
291
375
|
context "when options include verify_peer=false" do
|
292
376
|
let(:options) { {pem: pem, pem_password: "password", verify_peer: false} }
|
293
|
-
|
377
|
+
|
294
378
|
it "should not verify the certificate" do
|
295
|
-
subject.verify_mode.
|
379
|
+
expect(subject.verify_mode).to eq(OpenSSL::SSL::VERIFY_NONE)
|
296
380
|
end
|
297
381
|
end
|
298
382
|
end
|
@@ -302,16 +386,16 @@ describe HTTParty::ConnectionAdapter do
|
|
302
386
|
let(:http) { Net::HTTP.new(uri) }
|
303
387
|
|
304
388
|
before do
|
305
|
-
Net::HTTP.
|
306
|
-
OpenSSL::X509::Certificate.
|
307
|
-
OpenSSL::PKey::RSA.
|
308
|
-
http.
|
309
|
-
http.
|
389
|
+
allow(Net::HTTP).to receive_messages(new: http)
|
390
|
+
expect(OpenSSL::X509::Certificate).not_to receive(:new).with(pem)
|
391
|
+
expect(OpenSSL::PKey::RSA).not_to receive(:new).with(pem, "password")
|
392
|
+
expect(http).not_to receive(:cert=)
|
393
|
+
expect(http).not_to receive(:key=)
|
310
394
|
end
|
311
395
|
|
312
396
|
it "has no PEM certificate " do
|
313
|
-
subject.cert.
|
314
|
-
subject.key.
|
397
|
+
expect(subject.cert).to be_nil
|
398
|
+
expect(subject.key).to be_nil
|
315
399
|
end
|
316
400
|
end
|
317
401
|
end
|
@@ -322,28 +406,28 @@ describe HTTParty::ConnectionAdapter do
|
|
322
406
|
|
323
407
|
context "when scheme is https" do
|
324
408
|
let(:uri) { URI 'https://google.com' }
|
325
|
-
let(:pkcs12) {
|
326
|
-
let(:cert) {
|
327
|
-
let(:key) {
|
409
|
+
let(:pkcs12) { double("OpenSSL::PKCS12", certificate: cert, key: key) }
|
410
|
+
let(:cert) { double("OpenSSL::X509::Certificate") }
|
411
|
+
let(:key) { double("OpenSSL::PKey::RSA") }
|
328
412
|
|
329
413
|
before do
|
330
|
-
OpenSSL::PKCS12.
|
414
|
+
expect(OpenSSL::PKCS12).to receive(:new).with(p12, "password").and_return(pkcs12)
|
331
415
|
end
|
332
416
|
|
333
417
|
it "uses the provided P12 certificate " do
|
334
|
-
subject.cert.
|
335
|
-
subject.key.
|
418
|
+
expect(subject.cert).to eq(cert)
|
419
|
+
expect(subject.key).to eq(key)
|
336
420
|
end
|
337
421
|
|
338
422
|
it "will verify the certificate" do
|
339
|
-
subject.verify_mode.
|
423
|
+
expect(subject.verify_mode).to eq(OpenSSL::SSL::VERIFY_PEER)
|
340
424
|
end
|
341
|
-
|
425
|
+
|
342
426
|
context "when options include verify_peer=false" do
|
343
427
|
let(:options) { {p12: p12, p12_password: "password", verify_peer: false} }
|
344
|
-
|
428
|
+
|
345
429
|
it "should not verify the certificate" do
|
346
|
-
subject.verify_mode.
|
430
|
+
expect(subject.verify_mode).to eq(OpenSSL::SSL::VERIFY_NONE)
|
347
431
|
end
|
348
432
|
end
|
349
433
|
end
|
@@ -353,15 +437,15 @@ describe HTTParty::ConnectionAdapter do
|
|
353
437
|
let(:http) { Net::HTTP.new(uri) }
|
354
438
|
|
355
439
|
before do
|
356
|
-
Net::HTTP.
|
357
|
-
OpenSSL::PKCS12.
|
358
|
-
http.
|
359
|
-
http.
|
440
|
+
allow(Net::HTTP).to receive_messages(new: http)
|
441
|
+
expect(OpenSSL::PKCS12).not_to receive(:new).with(p12, "password")
|
442
|
+
expect(http).not_to receive(:cert=)
|
443
|
+
expect(http).not_to receive(:key=)
|
360
444
|
end
|
361
445
|
|
362
446
|
it "has no PKCS12 certificate " do
|
363
|
-
subject.cert.
|
364
|
-
subject.key.
|
447
|
+
expect(subject.cert).to be_nil
|
448
|
+
expect(subject.key).to be_nil
|
365
449
|
end
|
366
450
|
end
|
367
451
|
end
|