httparty 0.13.7 → 0.14.0

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.

@@ -68,8 +68,10 @@ module Net
68
68
 
69
69
  header =~ /Digest (.*)/
70
70
  params = {}
71
- non_quoted = $1.gsub(/(\w+)="(.*?)"/) { params[$1] = $2 }
72
- non_quoted.gsub(/(\w+)=([^,]*)/) { params[$1] = $2 }
71
+ if $1
72
+ non_quoted = $1.gsub(/(\w+)="(.*?)"/) { params[$1] = $2 }
73
+ non_quoted.gsub(/(\w+)=([^,]*)/) { params[$1] = $2 }
74
+ end
73
75
  params
74
76
  end
75
77
 
@@ -9,7 +9,8 @@ module HTTParty
9
9
  Net::HTTP::Head,
10
10
  Net::HTTP::Options,
11
11
  Net::HTTP::Move,
12
- Net::HTTP::Copy
12
+ Net::HTTP::Copy,
13
+ Net::HTTP::Mkcol,
13
14
  ]
14
15
 
15
16
  SupportedURISchemes = ['http', 'https', 'webcal', nil]
@@ -93,7 +94,7 @@ module HTTParty
93
94
  base_uri += ":#{@last_uri.port}" if @last_uri.port != 80
94
95
  base_uri
95
96
  else
96
- options[:base_uri]
97
+ options[:base_uri] && HTTParty.normalize_base_uri(options[:base_uri])
97
98
  end
98
99
  end
99
100
 
@@ -128,6 +129,7 @@ module HTTParty
128
129
  end
129
130
 
130
131
  handle_deflation unless http_method == Net::HTTP::Head
132
+ handle_host_redirection if response_redirects?
131
133
  handle_response(chunked_body, &block)
132
134
  end
133
135
 
@@ -174,7 +176,7 @@ module HTTParty
174
176
  @raw_request.body = body if body
175
177
  @raw_request.body_stream = options[:body_stream] if options[:body_stream]
176
178
  @raw_request.initialize_http_header(options[:headers].to_hash) if options[:headers].respond_to?(:to_hash)
177
- @raw_request.basic_auth(username, password) if options[:basic_auth]
179
+ @raw_request.basic_auth(username, password) if options[:basic_auth] && send_authorization_header?
178
180
  setup_digest_auth if options[:digest_auth]
179
181
  end
180
182
 
@@ -298,6 +300,9 @@ module HTTParty
298
300
 
299
301
  # Inspired by Ruby 1.9
300
302
  def handle_deflation
303
+ return if response_redirects?
304
+ return if last_response.body.nil?
305
+
301
306
  case last_response["content-encoding"]
302
307
  when "gzip", "x-gzip"
303
308
  body_io = StringIO.new(last_response.body)
@@ -309,6 +314,24 @@ module HTTParty
309
314
  end
310
315
  end
311
316
 
317
+ def handle_host_redirection
318
+ check_duplicate_location_header
319
+ redirect_path = options[:uri_adapter].parse last_response['location']
320
+ return if redirect_path.relative? || path.host == redirect_path.host
321
+ @changed_hosts = true
322
+ end
323
+
324
+ def check_duplicate_location_header
325
+ location = last_response.get_fields('location')
326
+ if location.is_a?(Array) && location.count > 1
327
+ raise DuplicateLocationHeader.new(last_response)
328
+ end
329
+ end
330
+
331
+ def send_authorization_header?
332
+ !defined?(@changed_hosts)
333
+ end
334
+
312
335
  def response_redirects?
313
336
  case last_response
314
337
  when Net::HTTPNotModified # 304
@@ -17,6 +17,8 @@ module HTTParty
17
17
  logger = ::HTTParty::Logger.build(request.options[:logger], request.options[:log_level], request.options[:log_format])
18
18
  logger.format(request, self)
19
19
  end
20
+
21
+ throw_exception
20
22
  end
21
23
 
22
24
  def parsed_response
@@ -27,6 +29,12 @@ module HTTParty
27
29
  Response
28
30
  end
29
31
 
32
+ def is_a?(klass)
33
+ self.class == klass || self.class < klass
34
+ end
35
+
36
+ alias_method :kind_of?, :is_a?
37
+
30
38
  def code
31
39
  response.code.to_i
32
40
  end
@@ -41,11 +49,17 @@ module HTTParty
41
49
  %(#<#{self.class}:0x#{inspect_id} parsed_response=#{parsed_response.inspect}, @response=#{response.inspect}, @headers=#{headers.inspect}>)
42
50
  end
43
51
 
52
+ RESPOND_TO_METHODS = [:request, :response, :parsed_response, :body, :headers]
53
+
44
54
  CODES_TO_OBJ = ::Net::HTTPResponse::CODE_CLASS_TO_OBJ.merge ::Net::HTTPResponse::CODE_TO_OBJ
45
55
 
46
56
  CODES_TO_OBJ.each do |response_code, klass|
47
57
  name = klass.name.sub("Net::HTTP", '')
48
- define_method("#{underscore(name)}?") do
58
+ name = "#{underscore(name)}?".to_sym
59
+
60
+ RESPOND_TO_METHODS << name
61
+
62
+ define_method(name) do
49
63
  klass === response
50
64
  end
51
65
  end
@@ -56,7 +70,7 @@ module HTTParty
56
70
  end
57
71
 
58
72
  def respond_to?(name, include_all = false)
59
- return true if [:request, :response, :parsed_response, :body, :headers].include?(name)
73
+ return true if RESPOND_TO_METHODS.include?(name)
60
74
  parsed_response.respond_to?(name, include_all) || response.respond_to?(name, include_all)
61
75
  end
62
76
 
@@ -71,6 +85,12 @@ module HTTParty
71
85
  super
72
86
  end
73
87
  end
88
+
89
+ def throw_exception
90
+ if @request.options[:raise_on] && @request.options[:raise_on].include?(code)
91
+ ::Kernel.raise ::HTTParty::ResponseError.new(@response), "Code #{code} - #{body}"
92
+ end
93
+ end
74
94
  end
75
95
  end
76
96
 
@@ -1,3 +1,3 @@
1
1
  module HTTParty
2
- VERSION = "0.13.7"
2
+ VERSION = "0.14.0"
3
3
  end
@@ -27,7 +27,7 @@ RSpec.describe HTTParty::ConnectionAdapter do
27
27
  it "sets the options" do
28
28
  options = {foo: :bar}
29
29
  adapter = HTTParty::ConnectionAdapter.new(uri, options)
30
- expect(adapter.options).to be options
30
+ expect(adapter.options.keys).to include(:verify, :verify_peer, :foo)
31
31
  end
32
32
  end
33
33
 
@@ -325,6 +325,19 @@ RSpec.describe HTTParty::ConnectionAdapter do
325
325
  end
326
326
  end
327
327
 
328
+ context 'when providing nil as proxy address' do
329
+ let(:uri) { URI 'http://noproxytest.com' }
330
+ let(:options) { {http_proxyaddr: nil} }
331
+
332
+ it { is_expected.not_to be_a_proxy }
333
+
334
+ it "does pass nil proxy parameters to the connection, this forces to not use a proxy" do
335
+ http = Net::HTTP.new("noproxytest.com")
336
+ expect(Net::HTTP).to receive(:new).once.with("noproxytest.com", 80, nil, nil, nil, nil).and_return(http)
337
+ adapter.connection
338
+ end
339
+ end
340
+
328
341
  context 'when not providing a proxy address' do
329
342
  let(:uri) { URI 'http://proxytest.com' }
330
343
 
@@ -372,6 +385,13 @@ RSpec.describe HTTParty::ConnectionAdapter do
372
385
  expect(subject.verify_mode).to eq(OpenSSL::SSL::VERIFY_PEER)
373
386
  end
374
387
 
388
+ context "when options include verify=false" do
389
+ let(:options) { {pem: pem, pem_password: "password", verify: false} }
390
+
391
+ it "should not verify the certificate" do
392
+ expect(subject.verify_mode).to eq(OpenSSL::SSL::VERIFY_NONE)
393
+ end
394
+ end
375
395
  context "when options include verify_peer=false" do
376
396
  let(:options) { {pem: pem, pem_password: "password", verify_peer: false} }
377
397
 
@@ -423,6 +443,13 @@ RSpec.describe HTTParty::ConnectionAdapter do
423
443
  expect(subject.verify_mode).to eq(OpenSSL::SSL::VERIFY_PEER)
424
444
  end
425
445
 
446
+ context "when options include verify=false" do
447
+ let(:options) { {p12: p12, p12_password: "password", verify: false} }
448
+
449
+ it "should not verify the certificate" do
450
+ expect(subject.verify_mode).to eq(OpenSSL::SSL::VERIFY_NONE)
451
+ end
452
+ end
426
453
  context "when options include verify_peer=false" do
427
454
  let(:options) { {p12: p12, p12_password: "password", verify_peer: false} }
428
455
 
@@ -48,7 +48,7 @@ RSpec.describe HTTParty::CookieHash do
48
48
  it "should error" do
49
49
  expect {
50
50
  @cookie_hash.add_cookies([])
51
- }.to raise_error
51
+ }.to raise_error(RuntimeError)
52
52
  end
53
53
  end
54
54
  end
@@ -79,5 +79,22 @@ RSpec.describe HTTParty::CookieHash do
79
79
  @s = @cookie_hash.to_cookie_string
80
80
  expect(@s).not_to match(/Path=\//)
81
81
  end
82
+
83
+ it "should not mutate the hash" do
84
+ original_hash = {
85
+ "session" => "91e25e8b-6e32-418d-c72f-2d18adf041cd",
86
+ "Max-Age" => "15552000",
87
+ "cart" => "91e25e8b-6e32-418d-c72f-2d18adf041cd",
88
+ "httponly" => nil,
89
+ "Path" => "/",
90
+ "secure" => nil,
91
+ }
92
+
93
+ cookie_hash = HTTParty::CookieHash[original_hash]
94
+
95
+ cookie_hash.to_cookie_string
96
+
97
+ expect(cookie_hash).to eq(original_hash)
98
+ end
82
99
  end
83
100
  end
@@ -35,4 +35,11 @@ RSpec.describe HTTParty::Error do
35
35
  it { is_expected.to include(HTTParty::ResponseError) }
36
36
  end
37
37
  end
38
+
39
+ describe HTTParty::DuplicateLocationHeader do
40
+ describe '#ancestors' do
41
+ subject { super().ancestors }
42
+ it { is_expected.to include(HTTParty::ResponseError) }
43
+ end
44
+ end
38
45
  end
@@ -22,6 +22,14 @@ RSpec.describe HTTParty::HashConversions do
22
22
  end
23
23
  end
24
24
 
25
+ context "value is an empty array" do
26
+ it "creates a params string" do
27
+ expect(
28
+ HTTParty::HashConversions.normalize_param(:people, [])
29
+ ).to eq("people[]=&")
30
+ end
31
+ end
32
+
25
33
  context "value is hash" do
26
34
  it "creates a params string" do
27
35
  expect(
@@ -2,6 +2,107 @@ require File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'spec_hel
2
2
 
3
3
  RSpec.describe HTTParty::Logger::CurlFormatter do
4
4
  describe "#format" do
5
+ let(:logger) { double('Logger') }
6
+ let(:response_object) { Net::HTTPOK.new('1.1', 200, 'OK') }
7
+ let(:parsed_response) { lambda { {"foo" => "bar"} } }
8
+
9
+ let(:response) do
10
+ HTTParty::Response.new(request, response_object, parsed_response)
11
+ end
12
+
13
+ let(:request) do
14
+ HTTParty::Request.new(Net::HTTP::Get, 'http://foo.bar.com/')
15
+ end
16
+
17
+ subject { described_class.new(logger, :info) }
18
+
19
+ before do
20
+ allow(logger).to receive(:info)
21
+ allow(request).to receive(:raw_body).and_return('content')
22
+ allow(response_object).to receive_messages(body: "{foo:'bar'}")
23
+ response_object['header-key'] = 'header-value'
24
+
25
+ subject.format request, response
26
+ end
27
+
28
+ context 'when request is logged' do
29
+ context "and request's option 'base_uri' is not present" do
30
+ it 'logs url' do
31
+ expect(logger).to have_received(:info).with(/\[HTTParty\] \[\d{4}-\d\d-\d\d \d\d:\d\d:\d\d\ [+-]\d{4}\] > GET http:\/\/foo.bar.com/)
32
+ end
33
+ end
34
+
35
+ context "and request's option 'base_uri' is present" do
36
+ let(:request) do
37
+ HTTParty::Request.new(Net::HTTP::Get, '/path', base_uri: 'http://foo.bar.com')
38
+ end
39
+
40
+ it 'logs url' do
41
+ expect(logger).to have_received(:info).with(/\[HTTParty\] \[\d{4}-\d\d-\d\d \d\d:\d\d:\d\d\ [+-]\d{4}\] > GET http:\/\/foo.bar.com\/path/)
42
+ end
43
+ end
44
+
45
+ context 'and headers are not present' do
46
+ it 'not log Headers' do
47
+ expect(logger).not_to have_received(:info).with(/Headers/)
48
+ end
49
+ end
50
+
51
+ context 'and headers are present' do
52
+ let(:request) do
53
+ HTTParty::Request.new(Net::HTTP::Get, '/path', base_uri: 'http://foo.bar.com', headers: { key: 'value' })
54
+ end
55
+
56
+ it 'logs Headers' do
57
+ expect(logger).to have_received(:info).with(/Headers/)
58
+ end
59
+
60
+ it 'logs headers keys' do
61
+ expect(logger).to have_received(:info).with(/key: value/)
62
+ end
63
+ end
64
+
65
+ context 'and query is not present' do
66
+ it 'not logs Query' do
67
+ expect(logger).not_to have_received(:info).with(/Query/)
68
+ end
69
+ end
70
+
71
+ context 'and query is present' do
72
+ let(:request) do
73
+ HTTParty::Request.new(Net::HTTP::Get, '/path', query: { key: 'value' })
74
+ end
75
+
76
+ it 'logs Query' do
77
+ expect(logger).to have_received(:info).with(/Query/)
78
+ end
79
+
80
+ it 'logs query params' do
81
+ expect(logger).to have_received(:info).with(/key: value/)
82
+ end
83
+ end
84
+
85
+ context 'when request raw_body is present' do
86
+ it 'not logs request body' do
87
+ expect(logger).to have_received(:info).with(/content/)
88
+ end
89
+ end
90
+ end
91
+
92
+ context 'when response is logged' do
93
+ it 'logs http version and response code' do
94
+ expect(logger).to have_received(:info).with(/HTTP\/1.1 200/)
95
+ end
96
+
97
+ it 'logs headers' do
98
+ expect(logger).to have_received(:info).with(/Header-key: header-value/)
99
+ end
100
+
101
+ it 'logs body' do
102
+ expect(logger).to have_received(:info).with(/{foo:'bar'}/)
103
+ end
104
+ end
105
+
5
106
  it "formats a response in a style that resembles a -v curl" do
6
107
  logger_double = double
7
108
  expect(logger_double).to receive(:info).with(
@@ -152,6 +152,16 @@ RSpec.describe Net::HTTPHeader::DigestAuthenticator do
152
152
  end
153
153
  end
154
154
 
155
+ context "with http basic auth response when net digest auth expected" do
156
+ it "should not fail" do
157
+ @digest = setup_digest({
158
+ 'www-authenticate' => 'WWW-Authenticate: Basic realm="testrealm.com""'
159
+ })
160
+
161
+ expect(authorization_header).to include("Digest")
162
+ end
163
+ end
164
+
155
165
  context "with multiple authenticate headers" do
156
166
  before do
157
167
  @digest = setup_digest({
@@ -56,6 +56,24 @@ RSpec.describe HTTParty::Request do
56
56
  expect(request.connection_adapter).to eq(my_adapter)
57
57
  end
58
58
 
59
+ context "when using a query string" do
60
+ context "and it has an empty array" do
61
+ it "sets correct query string" do
62
+ request = HTTParty::Request.new(Net::HTTP::Get, 'http://google.com', query: { fake_array: [] })
63
+
64
+ expect(request.uri).to eq(URI.parse("http://google.com/?fake_array[]="))
65
+ end
66
+ end
67
+
68
+ context "when sending an array with only one element" do
69
+ it "sets correct query" do
70
+ request = HTTParty::Request.new(Net::HTTP::Get, 'http://google.com', query: { fake_array: [1] })
71
+
72
+ expect(request.uri).to eq(URI.parse("http://google.com/?fake_array[]=1"))
73
+ end
74
+ end
75
+ end
76
+
59
77
  context "when basic authentication credentials provided in uri" do
60
78
  context "when basic auth options wasn't set explicitly" do
61
79
  it "sets basic auth from uri" do
@@ -168,6 +186,14 @@ RSpec.describe HTTParty::Request do
168
186
  request.send(:setup_raw_request)
169
187
  expect(request.instance_variable_get(:@raw_request).body_stream).to eq(stream)
170
188
  end
189
+
190
+ it 'should normalize base uri when specified as request option' do
191
+ FakeWeb.register_uri(:get, 'http://foo.com/resource', :body => 'Bar')
192
+ response = HTTParty.get('/resource', {
193
+ base_uri: 'foo.com'
194
+ })
195
+ expect(response.code).to eq(200)
196
+ end
171
197
  end
172
198
 
173
199
  describe "#uri" do
@@ -213,10 +239,10 @@ RSpec.describe HTTParty::Request do
213
239
  end
214
240
 
215
241
  it "respects the query string normalization proc" do
216
- empty_proc = lambda {|qs| ""}
242
+ empty_proc = lambda {|qs| "I"}
217
243
  @request.options[:query_string_normalizer] = empty_proc
218
244
  @request.options[:query] = {foo: :bar}
219
- expect(CGI.unescape(@request.uri.query)).to eq("")
245
+ expect(CGI.unescape(@request.uri.query)).to eq("I")
220
246
  end
221
247
 
222
248
  it "does not append an ampersand when queries are embedded in paths" do
@@ -479,6 +505,12 @@ RSpec.describe HTTParty::Request do
479
505
  expect(response.parsed_response).to eq({"hash" => {"foo" => "bar"}})
480
506
  end
481
507
 
508
+ it "raises an error if redirect has duplicate location header" do
509
+ @request = HTTParty::Request.new(Net::HTTP::Get, 'http://test.com/redirect', format: :xml)
510
+ FakeWeb.register_uri(:get, "http://test.com/redirect", status: [300, "REDIRECT"], location: ["http://api.foo.com/v2","http://api.foo.com/v2"])
511
+ expect {@request.perform}.to raise_error(HTTParty::DuplicateLocationHeader)
512
+ end
513
+
482
514
  it "returns the HTTParty::Response when the 300 does not contain a location header" do
483
515
  stub_response '', 300
484
516
  expect(HTTParty::Response).to be === @request.perform
@@ -594,6 +626,11 @@ RSpec.describe HTTParty::Request do
594
626
  expect(@request.perform.parsed_response).to eq({"hash" => {"foo" => "bar"}})
595
627
  end
596
628
 
629
+ it "should be handled by MKCOL transparently" do
630
+ @request.http_method = Net::HTTP::Mkcol
631
+ expect(@request.perform.parsed_response).to eq({"hash" => {"foo" => "bar"}})
632
+ end
633
+
597
634
  it "should keep track of cookies between redirects" do
598
635
  @redirect['Set-Cookie'] = 'foo=bar; name=value; HTTPOnly'
599
636
  @request.perform
@@ -601,14 +638,14 @@ RSpec.describe HTTParty::Request do
601
638
  expect(@request.options[:headers]['Cookie']).to match(/name=value/)
602
639
  end
603
640
 
604
- it 'should update cookies with rediects' do
641
+ it 'should update cookies with redirects' do
605
642
  @request.options[:headers] = {'Cookie' => 'foo=bar;'}
606
643
  @redirect['Set-Cookie'] = 'foo=tar;'
607
644
  @request.perform
608
645
  expect(@request.options[:headers]['Cookie']).to match(/foo=tar/)
609
646
  end
610
647
 
611
- it 'should keep cookies between rediects' do
648
+ it 'should keep cookies between redirects' do
612
649
  @request.options[:headers] = {'Cookie' => 'keep=me'}
613
650
  @redirect['Set-Cookie'] = 'foo=tar;'
614
651
  @request.perform
@@ -715,6 +752,11 @@ RSpec.describe HTTParty::Request do
715
752
  expect(@request.perform.parsed_response).to eq({"hash" => {"foo" => "bar"}})
716
753
  end
717
754
 
755
+ it "should be handled by MKCOL transparently" do
756
+ @request.http_method = Net::HTTP::Mkcol
757
+ expect(@request.perform.parsed_response).to eq({"hash" => {"foo" => "bar"}})
758
+ end
759
+
718
760
  it "should keep track of cookies between redirects" do
719
761
  @redirect['Set-Cookie'] = 'foo=bar; name=value; HTTPOnly'
720
762
  @request.perform
@@ -722,14 +764,14 @@ RSpec.describe HTTParty::Request do
722
764
  expect(@request.options[:headers]['Cookie']).to match(/name=value/)
723
765
  end
724
766
 
725
- it 'should update cookies with rediects' do
767
+ it 'should update cookies with redirects' do
726
768
  @request.options[:headers] = {'Cookie' => 'foo=bar;'}
727
769
  @redirect['Set-Cookie'] = 'foo=tar;'
728
770
  @request.perform
729
771
  expect(@request.options[:headers]['Cookie']).to match(/foo=tar/)
730
772
  end
731
773
 
732
- it 'should keep cookies between rediects' do
774
+ it 'should keep cookies between redirects' do
733
775
  @request.options[:headers] = {'Cookie' => 'keep=me'}
734
776
  @redirect['Set-Cookie'] = 'foo=tar;'
735
777
  @request.perform
@@ -848,6 +890,11 @@ RSpec.describe HTTParty::Request do
848
890
  expect(@request.perform.code).to eq(304)
849
891
  end
850
892
 
893
+ it "should report 304 with a MKCOL request" do
894
+ @request.http_method = Net::HTTP::Mkcol
895
+ expect(@request.perform.code).to eq(304)
896
+ end
897
+
851
898
  it 'should not log the redirection' do
852
899
  logger_double = double
853
900
  expect(logger_double).to receive(:info).once
@@ -914,6 +961,11 @@ RSpec.describe HTTParty::Request do
914
961
  expect(@request.perform.parsed_response).to eq({"hash" => {"foo" => "bar"}})
915
962
  end
916
963
 
964
+ it "should be handled by MKCOL transparently" do
965
+ @request.http_method = Net::HTTP::Mkcol
966
+ expect(@request.perform.parsed_response).to eq({"hash" => {"foo" => "bar"}})
967
+ end
968
+
917
969
  it "should keep track of cookies between redirects" do
918
970
  @redirect['Set-Cookie'] = 'foo=bar; name=value; HTTPOnly'
919
971
  @request.perform
@@ -921,14 +973,14 @@ RSpec.describe HTTParty::Request do
921
973
  expect(@request.options[:headers]['Cookie']).to match(/name=value/)
922
974
  end
923
975
 
924
- it 'should update cookies with rediects' do
976
+ it 'should update cookies with redirects' do
925
977
  @request.options[:headers] = {'Cookie' => 'foo=bar;'}
926
978
  @redirect['Set-Cookie'] = 'foo=tar;'
927
979
  @request.perform
928
980
  expect(@request.options[:headers]['Cookie']).to match(/foo=tar/)
929
981
  end
930
982
 
931
- it 'should keep cookies between rediects' do
983
+ it 'should keep cookies between redirects' do
932
984
  @request.options[:headers] = {'Cookie' => 'keep=me'}
933
985
  @redirect['Set-Cookie'] = 'foo=tar;'
934
986
  @request.perform
@@ -1016,6 +1068,64 @@ RSpec.describe HTTParty::Request do
1016
1068
  expect(@request.last_response).to receive(:delete).with('content-encoding')
1017
1069
  @request.send(:handle_deflation)
1018
1070
  end
1071
+
1072
+ it "should not inflate a redirected response with content-encoding: gzip" do
1073
+ allow(@last_response).to receive(:[]).with("content-encoding").and_return("gzip")
1074
+ allow(@request).to receive(:last_response).and_return(@last_response)
1075
+ allow(@request).to receive(:response_redirects?).and_return(true)
1076
+ @request.send(:handle_deflation)
1077
+ end
1078
+
1079
+ it "should not inflate a redirected response with content-encoding: deflate" do
1080
+ allow(@last_response).to receive(:[]).with("content-encoding").and_return("deflate")
1081
+ allow(@request).to receive(:last_response).and_return(@last_response)
1082
+ allow(@request).to receive(:response_redirects?).and_return(true)
1083
+ @request.send(:handle_deflation)
1084
+ end
1085
+ end
1086
+ end
1087
+
1088
+ describe "#send_authorization_header?" do
1089
+ context "basic_auth" do
1090
+ before do
1091
+ @credentials = { username: "username", password: "password" }
1092
+ @authorization = "Basic dXNlcm5hbWU6cGFzc3dvcmQ="
1093
+ @request.options[:basic_auth] = @credentials
1094
+ @redirect = stub_response("", 302)
1095
+ @ok = stub_response('<hash><foo>bar</foo></hash>', 200)
1096
+ end
1097
+
1098
+ before(:each) do
1099
+ allow(@http).to receive(:request).and_return(@redirect, @ok)
1100
+ end
1101
+
1102
+ it "should not send Authorization header when redirecting to a different host" do
1103
+ @redirect['location'] = 'http://example.com/'
1104
+ @request.perform
1105
+ @request.send(:setup_raw_request)
1106
+ expect(@request.instance_variable_get(:@raw_request)['authorization']).to be_nil
1107
+ end
1108
+
1109
+ it "should send Authorization header when redirecting to a relative path" do
1110
+ @redirect['location'] = '/v3'
1111
+ @request.perform
1112
+ @request.send(:setup_raw_request)
1113
+ expect(@request.instance_variable_get(:@raw_request)['authorization']).to eq(@authorization)
1114
+ end
1115
+
1116
+ it "should send Authorization header when redirecting to the same host" do
1117
+ @redirect['location'] = 'http://api.foo.com/v2'
1118
+ @request.perform
1119
+ @request.send(:setup_raw_request)
1120
+ expect(@request.instance_variable_get(:@raw_request)['authorization']).to eq(@authorization)
1121
+ end
1122
+
1123
+ it "should send Authorization header when redirecting to a different port on the same host" do
1124
+ @redirect['location'] = 'http://api.foo.com:3000/v3'
1125
+ @request.perform
1126
+ @request.send(:setup_raw_request)
1127
+ expect(@request.instance_variable_get(:@raw_request)['authorization']).to eq(@authorization)
1128
+ end
1019
1129
  end
1020
1130
  end
1021
1131