httpclient 2.8.0 → 2.8.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 7d31f6d6614892afef55ee460384719e2a3fd308
4
- data.tar.gz: deb8c8f5172a0d956daebda1853b585d7d2f5845
3
+ metadata.gz: c4ffce5e3ce378196b7441498f0a93969da6086f
4
+ data.tar.gz: 91ba9e1062f6515828ae1983ca28eb0a2d40a75d
5
5
  SHA512:
6
- metadata.gz: 5df03c1b552368850d643690166ef8dadedab621395ffae31c279cf863b4d4c8b7a1ac1504b9bf5feb6dde6452ce47ec725187dc15535c3c6576f4f606961664
7
- data.tar.gz: ef50511dd9b8d46ff3c6b5bad0e55a66b99501c62246b308c3f54eec3273253e006dce6ef13ab78b8533b2fb5eeda121c00f1943d562815f40c9c33e472b0f91
6
+ metadata.gz: 743acf9501f271b66d4b7dcc25812ea766f81d4e3eae6f5a4784ce157a3db7f81a386c6d8a7cced0b87cb464040752997047dad0d627cc94fb9451371f34a44b
7
+ data.tar.gz: 1e14c7fdd6ec23d895310ca70f3a96a6bd44910371f6221c33095fa4302344da15574a109e800493481e8477dbbb33ce4c4d2cb0661e271c0846d3b8674cf8ba
@@ -20,6 +20,7 @@ end
20
20
  url = ARGV.shift
21
21
  if method && url
22
22
  client = HTTPClient.new
23
+ client.strict_response_size_check = true
23
24
  if method == 'download'
24
25
  print client.get_content(url)
25
26
  else
@@ -37,6 +38,7 @@ require 'irb/completion'
37
38
  class Runner
38
39
  def initialize
39
40
  @httpclient = HTTPClient.new
41
+ @httpclient.strict_response_size_check = true
40
42
  end
41
43
 
42
44
  def method_missing(msg, *a, &b)
@@ -309,7 +309,6 @@ class HTTPClient
309
309
  if assignable
310
310
  aname = name + '='
311
311
  define_method(aname) { |rhs|
312
- reset_all
313
312
  @session_manager.__send__(aname, rhs)
314
313
  }
315
314
  end
@@ -365,6 +364,9 @@ class HTTPClient
365
364
  attr_proxy(:test_loopback_http_response)
366
365
  # Decompress a compressed (with gzip or deflate) content body transparently. false by default.
367
366
  attr_proxy(:transparent_gzip_decompression, true)
367
+ # Raise BadResponseError if response size does not match with Content-Length header in response. false by default.
368
+ # TODO: enable by default
369
+ attr_proxy(:strict_response_size_check, true)
368
370
  # Local socket address. Set HTTPClient#socket_local.host and HTTPClient#socket_local.port to specify local binding hostname and port of TCP socket.
369
371
  attr_proxy(:socket_local, true)
370
372
 
@@ -844,13 +846,7 @@ class HTTPClient
844
846
  end
845
847
  uri = to_resource_url(uri)
846
848
  if block
847
- if block.arity == 1
848
- filtered_block = proc { |res, str|
849
- block.call(str)
850
- }
851
- else
852
- filtered_block = block
853
- end
849
+ filtered_block = adapt_block(&block)
854
850
  end
855
851
  if follow_redirect
856
852
  follow_redirect(method, uri, query, body, header, &block)
@@ -1082,11 +1078,17 @@ private
1082
1078
  ENV[name.downcase] || ENV[name.upcase]
1083
1079
  end
1084
1080
 
1081
+ def adapt_block(&block)
1082
+ return block if block.arity == 2
1083
+ proc { |r, str| block.call(str) }
1084
+ end
1085
+
1085
1086
  def follow_redirect(method, uri, query, body, header, &block)
1086
1087
  uri = to_resource_url(uri)
1087
1088
  if block
1089
+ b = adapt_block(&block)
1088
1090
  filtered_block = proc { |r, str|
1089
- block.call(str) if r.ok?
1091
+ b.call(r, str) if r.ok?
1090
1092
  }
1091
1093
  end
1092
1094
  if HTTP::Message.file?(body)
@@ -1270,6 +1272,7 @@ private
1270
1272
  return
1271
1273
  end
1272
1274
  piper, pipew = IO.pipe
1275
+ pipew.binmode
1273
1276
  res = HTTP::Message.new_response(piper, req.header)
1274
1277
  @debug_dev << "= Request\n\n" if @debug_dev
1275
1278
  sess = @session_manager.query(req, proxy)
@@ -700,8 +700,9 @@ module HTTP
700
700
 
701
701
  def params_from_file(value)
702
702
  params = {}
703
+ original_filename = value.respond_to?(:original_filename) ? value.original_filename : nil
703
704
  path = value.respond_to?(:path) ? value.path : nil
704
- params['filename'] = File.basename(path || '')
705
+ params['filename'] = original_filename || File.basename(path || '')
705
706
  # Creation time is not available from File::Stat
706
707
  if value.respond_to?(:mtime)
707
708
  params['modification-date'] = value.mtime.rfc822
@@ -808,6 +809,8 @@ module HTTP
808
809
  case path
809
810
  when /\.txt$/i
810
811
  'text/plain'
812
+ when /\.xml$/i
813
+ 'text/xml'
811
814
  when /\.(htm|html)$/i
812
815
  'text/html'
813
816
  when /\.doc$/i
@@ -289,11 +289,11 @@ unless defined?(SSLSocket)
289
289
  @keystore.load(nil)
290
290
  end
291
291
 
292
- def add(cert_file, key_file, password)
293
- cert_str = cert_file.respond_to?(:to_pem) ? cert_file.to_pem : File.read(cert_file.to_s)
292
+ def add(cert_source, key_source, password)
293
+ cert_str = cert_source.respond_to?(:to_pem) ? cert_source.to_pem : File.read(cert_source.to_s)
294
294
  cert = PEMUtils.read_certificate(cert_str)
295
295
  @keystore.setCertificateEntry('client_cert', cert)
296
- key_str = key_file.respond_to?(:to_pem) ? key_file.to_pem : File.read(key_file.to_s)
296
+ key_str = key_source.respond_to?(:to_pem) ? key_source.to_pem : File.read(key_source.to_s)
297
297
  key_pair = PEMUtils.read_private_key(key_str, password)
298
298
  @keystore.setKeyEntry('client_key', key_pair.getPrivate, PASSWORD, [cert].to_java(Certificate))
299
299
  end
@@ -312,20 +312,21 @@ unless defined?(SSLSocket)
312
312
  @size = 0
313
313
  end
314
314
 
315
- def add(file_or_dir)
316
- return if file_or_dir == :default
317
- if File.directory?(file_or_dir)
318
- warn("#{file_or_dir}: directory not yet supported")
315
+ def add(cert_source)
316
+ return if cert_source == :default
317
+ if cert_source.respond_to?(:to_pem)
318
+ pem = cert_source.to_pem
319
+ elsif File.directory?(cert_source)
320
+ warn("#{cert_source}: directory not yet supported")
321
+ return
319
322
  else
320
323
  pem = nil
321
- File.read(file_or_dir).each_line do |line|
324
+ File.read(cert_source).each_line do |line|
322
325
  case line
323
326
  when /-----BEGIN CERTIFICATE-----/
324
327
  pem = ''
325
328
  when /-----END CERTIFICATE-----/
326
- cert = PEMUtils.read_certificate(pem)
327
- @size += 1
328
- @trust_store.setCertificateEntry("cert_#{@size}", cert)
329
+ break
329
330
  else
330
331
  if pem
331
332
  pem << line
@@ -333,6 +334,9 @@ unless defined?(SSLSocket)
333
334
  end
334
335
  end
335
336
  end
337
+ cert = PEMUtils.read_certificate(pem)
338
+ @size += 1
339
+ @trust_store.setCertificateEntry("cert_#{@size}", cert)
336
340
  end
337
341
 
338
342
  def trust_store
@@ -442,12 +446,12 @@ unless defined?(SSLSocket)
442
446
  new(socket, session.dest, session.ssl_config, session.debug_dev)
443
447
  end
444
448
 
445
- DEFAULT_SSL_PROTOCOL = 'TLS'
449
+ DEFAULT_SSL_PROTOCOL = (java.lang.System.getProperty('java.specification.version') == '1.7') ? 'TLSv1.2' : 'TLS'
446
450
  def initialize(socket, dest, config, debug_dev = nil)
447
451
  if config.ssl_version == :auto
448
452
  ssl_version = DEFAULT_SSL_PROTOCOL
449
453
  else
450
- ssl_version = config.ssl_version.to_s.gsub(/_/, '.')
454
+ ssl_version = config.ssl_version.to_s.tr('_', '.')
451
455
  end
452
456
  unless config.cert_store_crl_items.empty?
453
457
  raise NotImplementedError.new('Manual CRL configuration is not yet supported')
@@ -464,7 +468,7 @@ unless defined?(SSLSocket)
464
468
 
465
469
  trust_store = nil
466
470
  verify_callback = config.verify_callback || config.method(:default_verify_callback)
467
- if config.verify_mode == nil
471
+ if !config.verify?
468
472
  tmf = VerifyNoneTrustManagerFactory.new(verify_callback)
469
473
  else
470
474
  tmf = SystemTrustManagerFactory.new(verify_callback)
@@ -115,6 +115,9 @@ class HTTPClient
115
115
  attr_accessor :read_block_size
116
116
  attr_accessor :protocol_retry_count
117
117
 
118
+ # Raise BadResponseError if response size does not match with Content-Length header in response.
119
+ attr_accessor :strict_response_size_check
120
+
118
121
  # Local address to bind local side of the socket to
119
122
  attr_accessor :socket_local
120
123
 
@@ -148,6 +151,7 @@ class HTTPClient
148
151
  @test_loopback_http_response = []
149
152
 
150
153
  @transparent_gzip_decompression = false
154
+ @strict_response_size_check = false
151
155
  @socket_local = Site.new
152
156
 
153
157
  @sess_pool = {}
@@ -221,6 +225,7 @@ class HTTPClient
221
225
  sess.protocol_retry_count = @protocol_retry_count
222
226
  sess.ssl_config = @ssl_config
223
227
  sess.debug_dev = @debug_dev
228
+ sess.strict_response_size_check = @strict_response_size_check
224
229
  sess.socket_local = @socket_local
225
230
  sess.test_loopback_http_response = @test_loopback_http_response
226
231
  sess.transparent_gzip_decompression = @transparent_gzip_decompression
@@ -444,6 +449,7 @@ class HTTPClient
444
449
  attr_accessor :read_block_size
445
450
  attr_accessor :protocol_retry_count
446
451
 
452
+ attr_accessor :strict_response_size_check
447
453
  attr_accessor :socket_local
448
454
 
449
455
  attr_accessor :ssl_config
@@ -473,6 +479,7 @@ class HTTPClient
473
479
  @ssl_peer_cert = nil
474
480
 
475
481
  @test_loopback_http_response = nil
482
+ @strict_response_size_check = false
476
483
  @socket_local = Site::EMPTY
477
484
 
478
485
  @agent_name = agent_name
@@ -871,6 +878,9 @@ class HTTPClient
871
878
  rescue EOFError
872
879
  close
873
880
  buf = nil
881
+ if @strict_response_size_check
882
+ raise BadResponseError.new("EOF while reading rest #{@content_length} bytes")
883
+ end
874
884
  end
875
885
  end
876
886
  if buf && buf.bytesize > 0
@@ -887,18 +897,18 @@ class HTTPClient
887
897
  def read_body_chunked(&block)
888
898
  buf = empty_bin_str
889
899
  while true
890
- len = @socket.gets(RS)
891
- if len.nil? # EOF
892
- close
893
- return
894
- end
895
- @chunk_length = len.hex
896
- if @chunk_length == 0
897
- @content_length = 0
898
- @socket.gets(RS)
899
- return
900
- end
901
900
  ::Timeout.timeout(@receive_timeout, ReceiveTimeoutError) do
901
+ len = @socket.gets(RS)
902
+ if len.nil? # EOF
903
+ close
904
+ return
905
+ end
906
+ @chunk_length = len.hex
907
+ if @chunk_length == 0
908
+ @content_length = 0
909
+ @socket.gets(RS)
910
+ return
911
+ end
902
912
  @socket.read(@chunk_length, buf)
903
913
  @socket.read(2)
904
914
  end
@@ -920,6 +930,9 @@ class HTTPClient
920
930
  @socket.readpartial(@read_block_size, buf)
921
931
  rescue EOFError
922
932
  buf = nil
933
+ if @strict_response_size_check
934
+ raise BadResponseError.new("EOF while reading chunked response")
935
+ end
923
936
  end
924
937
  end
925
938
  if buf && buf.bytesize > 0
@@ -36,7 +36,30 @@ class HTTPClient
36
36
  # then add_trust_ca for that purpose.
37
37
  class SSLConfig
38
38
  include HTTPClient::Util
39
- include OpenSSL if SSLEnabled
39
+ if SSLEnabled
40
+ include OpenSSL
41
+
42
+ module ::OpenSSL
43
+ module X509
44
+ class Store
45
+ attr_reader :_httpclient_cert_store_items
46
+
47
+ def initialize(*a, &b)
48
+ super(*a, &b)
49
+ @_httpclient_cert_store_items = [ENV['SSL_CERT_FILE'] || :default]
50
+ end
51
+
52
+ [:add_cert, :add_file, :add_path].each do |m|
53
+ wrapped = instance_method(m)
54
+ define_method(m) do |cert|
55
+ wrapped.bind(self).call(cert)
56
+ @_httpclient_cert_store_items << cert
57
+ end
58
+ end
59
+ end
60
+ end
61
+ end
62
+ end
40
63
 
41
64
  CIPHERS_DEFAULT = "ALL:!aNULL:!eNULL:!SSLv2" # OpenSSL >1.0.0 default
42
65
 
@@ -89,7 +112,7 @@ class HTTPClient
89
112
  attr_reader :client_ca # :nodoc:
90
113
 
91
114
  # These array keeps original files/dirs that was added to @cert_store
92
- attr_reader :cert_store_items
115
+ def cert_store_items; @cert_store._httpclient_cert_store_items; end
93
116
  attr_reader :cert_store_crl_items
94
117
 
95
118
  # Creates a SSLConfig.
@@ -97,7 +120,6 @@ class HTTPClient
97
120
  return unless SSLEnabled
98
121
  @client = client
99
122
  @cert_store = X509::Store.new
100
- @cert_store_items = [:default]
101
123
  @cert_store_crl_items = []
102
124
  @client_cert = @client_key = @client_ca = nil
103
125
  @verify_mode = SSL::VERIFY_PEER | SSL::VERIFY_FAIL_IF_NO_PEER_CERT
@@ -170,7 +192,6 @@ class HTTPClient
170
192
  @cacerts_loaded = true # avoid lazy override
171
193
  @cert_store = X509::Store.new
172
194
  @cert_store.set_default_paths
173
- @cert_store_items = [ENV['SSL_CERT_FILE'] || :default]
174
195
  change_notify
175
196
  end
176
197
 
@@ -181,7 +202,7 @@ class HTTPClient
181
202
  def clear_cert_store
182
203
  @cacerts_loaded = true # avoid lazy override
183
204
  @cert_store = X509::Store.new
184
- @cert_store_items.clear
205
+ @cert_store._httpclient_cert_store_items.clear
185
206
  change_notify
186
207
  end
187
208
 
@@ -192,7 +213,6 @@ class HTTPClient
192
213
  def cert_store=(cert_store)
193
214
  @cacerts_loaded = true # avoid lazy override
194
215
  @cert_store = cert_store
195
- @cert_store_items.clear
196
216
  change_notify
197
217
  end
198
218
 
@@ -209,7 +229,6 @@ class HTTPClient
209
229
  end
210
230
  @cacerts_loaded = true # avoid lazy override
211
231
  add_trust_ca_to_store(@cert_store, trust_ca_file_or_hashed_dir)
212
- @cert_store_items << trust_ca_file_or_hashed_dir
213
232
  change_notify
214
233
  end
215
234
  alias set_trust_ca add_trust_ca
@@ -308,6 +327,10 @@ class HTTPClient
308
327
  change_notify
309
328
  end
310
329
 
330
+ def verify?
331
+ @verify_mode && (@verify_mode & OpenSSL::SSL::VERIFY_PEER != 0)
332
+ end
333
+
311
334
  # interfaces for SSLSocket.
312
335
  def set_context(ctx) # :nodoc:
313
336
  load_trust_ca unless @cacerts_loaded
@@ -445,11 +468,7 @@ class HTTPClient
445
468
  def load_cacerts(cert_store)
446
469
  ver = OpenSSL::OPENSSL_VERSION
447
470
  file = File.join(File.dirname(__FILE__), 'cacert.pem')
448
- unless defined?(JRuby)
449
- # JRuby uses @cert_store_items
450
- add_trust_ca_to_store(cert_store, file)
451
- end
452
- @cert_store_items << file
471
+ add_trust_ca_to_store(cert_store, file)
453
472
  end
454
473
  end
455
474
 
@@ -1,3 +1,3 @@
1
1
  class HTTPClient
2
- VERSION = '2.8.0'
2
+ VERSION = '2.8.1'
3
3
  end
@@ -342,7 +342,7 @@ class WebAgent
342
342
  cookie.domain_orig = given.domain
343
343
  cookie.path_orig = given.path
344
344
 
345
- if cookie.discard? || cookie.expires == nil
345
+ if cookie.discard? || cookie.expires.nil?
346
346
  cookie.discard = true
347
347
  else
348
348
  cookie.discard = false
@@ -33,6 +33,7 @@ class OAuthClient < HTTPClient
33
33
  @oauth_config = HTTPClient::OAuth::Config.new
34
34
  self.www_auth.oauth.set_config(nil, @oauth_config)
35
35
  self.www_auth.oauth.challenge(nil)
36
+ self.strict_response_size_check = true
36
37
  end
37
38
 
38
39
  # Get request token.
@@ -2,7 +2,6 @@ require File.expand_path('helper', File.dirname(__FILE__))
2
2
  require 'digest/md5'
3
3
  require 'rack'
4
4
  require 'rack/lint'
5
- require 'rack/showexceptions'
6
5
  require 'rack-ntlm'
7
6
 
8
7
  class TestAuth < Test::Unit::TestCase
@@ -347,11 +347,13 @@ class TestClient < Test::Unit::TestCase
347
347
  def test_receive_timeout
348
348
  # this test takes 2 sec
349
349
  assert_equal('hello', @client.get_content(serverurl + 'sleep?sec=2'))
350
+ @client.reset_all
350
351
  @client.receive_timeout = 1
351
352
  assert_equal('hello', @client.get_content(serverurl + 'sleep?sec=0'))
352
353
  assert_raise(HTTPClient::ReceiveTimeoutError) do
353
354
  @client.get_content(serverurl + 'sleep?sec=2')
354
355
  end
356
+ @client.reset_all
355
357
  @client.receive_timeout = 3
356
358
  assert_equal('hello', @client.get_content(serverurl + 'sleep?sec=2'))
357
359
  end
@@ -609,10 +609,12 @@ EOS
609
609
  assert_not_equal('hello', content)
610
610
  assert_equal(GZIP_CONTENT, content)
611
611
  @client.transparent_gzip_decompression = true
612
+ @client.reset_all
612
613
  assert_equal('hello', @client.get_content(serverurl + 'compressed?enc=gzip'))
613
614
  assert_equal('hello', @client.get_content(serverurl + 'compressed?enc=deflate'))
614
615
  assert_equal('hello', @client.get_content(serverurl + 'compressed?enc=deflate_noheader'))
615
616
  @client.transparent_gzip_decompression = false
617
+ @client.reset_all
616
618
  end
617
619
 
618
620
  def test_get_content_with_block
@@ -765,6 +767,22 @@ EOS
765
767
  assert_equal(1000*1000, res.content.read.length)
766
768
  end
767
769
 
770
+ if RUBY_VERSION > "1.9"
771
+ def test_post_async_with_default_internal
772
+ original_encoding = Encoding.default_internal
773
+ Encoding.default_internal = Encoding::UTF_8
774
+ begin
775
+ post_body = StringIO.new("こんにちは")
776
+ conn = @client.post_async(serverurl + 'servlet', post_body)
777
+ Thread.pass while !conn.finished?
778
+ res = conn.pop
779
+ assert_equal 'post,こんにちは', res.content.read
780
+ ensure
781
+ Encoding.default_internal = original_encoding
782
+ end
783
+ end
784
+ end
785
+
768
786
  def test_get_with_block
769
787
  called = false
770
788
  res = @client.get(serverurl + 'servlet') { |str|
@@ -788,6 +806,29 @@ EOS
788
806
  assert_nil(res.content)
789
807
  end
790
808
 
809
+ def test_get_with_block_and_redirects
810
+ called = false
811
+ res = @client.get(serverurl + 'servlet', :follow_redirect => true) { |str|
812
+ assert_equal('get', str)
813
+ called = true
814
+ }
815
+ assert(called)
816
+ # res does not have a content
817
+ assert_nil(res.content)
818
+ end
819
+
820
+ def test_get_with_block_arity_2_and_redirects
821
+ called = false
822
+ res = @client.get(serverurl + 'servlet', :follow_redirect => true) { |blk_res, str|
823
+ assert_equal(200, blk_res.status)
824
+ assert_equal('get', str)
825
+ called = true
826
+ }
827
+ assert(called)
828
+ # res does not have a content
829
+ assert_nil(res.content)
830
+ end
831
+
791
832
  def test_get_with_block_string_recycle
792
833
  @client.read_block_size = 2
793
834
  body = []
@@ -1032,6 +1073,10 @@ EOS
1032
1073
  def test_post_with_custom_multipart_and_file
1033
1074
  STDOUT.sync = true
1034
1075
  File.open(__FILE__) do |file|
1076
+ def file.original_filename
1077
+ 'file.txt'
1078
+ end
1079
+
1035
1080
  ext = { 'Content-Type' => 'multipart/alternative' }
1036
1081
  body = [{ 'Content-Type' => 'text/plain', :content => "this is only a test" },
1037
1082
  { 'Content-Type' => 'application/x-ruby', :content => file }]
@@ -1039,6 +1084,7 @@ EOS
1039
1084
  assert_match(/^Content-Type: text\/plain\r\n/m, res.content)
1040
1085
  assert_match(/^this is only a test\r\n/m, res.content)
1041
1086
  assert_match(/^Content-Type: application\/x-ruby\r\n/m, res.content)
1087
+ assert_match(/Content-Disposition: form-data; name="3"; filename="file.txt"/, res.content)
1042
1088
  assert_match(/FIND_TAG_IN_THIS_FILE/, res.content)
1043
1089
  end
1044
1090
  end
@@ -1311,11 +1357,13 @@ EOS
1311
1357
  # this test takes 2 sec
1312
1358
  assert_equal('hello?sec=2', @client.get_content(serverurl + 'sleep?sec=2'))
1313
1359
  @client.receive_timeout = 1
1360
+ @client.reset_all
1314
1361
  assert_equal('hello?sec=0', @client.get_content(serverurl + 'sleep?sec=0'))
1315
1362
  assert_raise(HTTPClient::ReceiveTimeoutError) do
1316
1363
  @client.get_content(serverurl + 'sleep?sec=2')
1317
1364
  end
1318
1365
  @client.receive_timeout = 3
1366
+ @client.reset_all
1319
1367
  assert_equal('hello?sec=2', @client.get_content(serverurl + 'sleep?sec=2'))
1320
1368
  end
1321
1369
 
@@ -1323,11 +1371,13 @@ EOS
1323
1371
  # this test takes 2 sec
1324
1372
  assert_equal('hello', @client.post(serverurl + 'sleep', :sec => 2).content)
1325
1373
  @client.receive_timeout = 1
1374
+ @client.reset_all
1326
1375
  assert_equal('hello', @client.post(serverurl + 'sleep', :sec => 0).content)
1327
1376
  assert_raise(HTTPClient::ReceiveTimeoutError) do
1328
1377
  @client.post(serverurl + 'sleep', :sec => 2)
1329
1378
  end
1330
1379
  @client.receive_timeout = 3
1380
+ @client.reset_all
1331
1381
  assert_equal('hello', @client.post(serverurl + 'sleep', :sec => 2).content)
1332
1382
  end
1333
1383
 
@@ -1486,6 +1536,7 @@ EOS
1486
1536
  assert_equal('text/plain', HTTP::Message.mime_type('foo.txt'))
1487
1537
  assert_equal('text/html', HTTP::Message.mime_type('foo.html'))
1488
1538
  assert_equal('text/html', HTTP::Message.mime_type('foo.htm'))
1539
+ assert_equal('text/xml', HTTP::Message.mime_type('foo.xml'))
1489
1540
  assert_equal('application/msword', HTTP::Message.mime_type('foo.doc'))
1490
1541
  assert_equal('image/png', HTTP::Message.mime_type('foo.png'))
1491
1542
  assert_equal('image/gif', HTTP::Message.mime_type('foo.gif'))
@@ -1779,6 +1830,19 @@ EOS
1779
1830
  end
1780
1831
  end
1781
1832
 
1833
+ def test_strict_response_size_check
1834
+ @client.strict_response_size_check = false
1835
+ @client.test_loopback_http_response << "HTTP/1.0 200 OK\r\nContent-Length: 12345\r\n\r\nhello world"
1836
+ assert_equal('hello world', @client.get_content('http://dummy'))
1837
+
1838
+ @client.reset_all
1839
+ @client.strict_response_size_check = true
1840
+ @client.test_loopback_http_response << "HTTP/1.0 200 OK\r\nContent-Length: 12345\r\n\r\nhello world"
1841
+ assert_raise(HTTPClient::BadResponseError) do
1842
+ @client.get_content('http://dummy')
1843
+ end
1844
+ end
1845
+
1782
1846
  def test_socket_local
1783
1847
  @client.socket_local.host = '127.0.0.1'
1784
1848
  assert_equal('hello', @client.get_content(serverurl + 'hello'))
@@ -149,6 +149,22 @@ end
149
149
  #
150
150
  cfg.verify_mode = nil
151
151
  assert_equal("hello", @client.get_content(@url))
152
+ cfg.verify_mode = OpenSSL::SSL::VERIFY_NONE
153
+ assert_equal("hello", @client.get_content(@url))
154
+ end
155
+
156
+ def test_cert_store
157
+ cfg = @client.ssl_config
158
+ cfg.cert_store.add_cert(cert('ca.cert'))
159
+ begin
160
+ @client.get(@url)
161
+ assert(false)
162
+ rescue OpenSSL::SSL::SSLError => ssle
163
+ assert_match(/(certificate verify failed|unable to find valid certification path to requested target)/, ssle.message)
164
+ end
165
+ #
166
+ cfg.cert_store.add_cert(cert('subca.cert'))
167
+ assert_equal("hello", @client.get_content(@url))
152
168
  end
153
169
 
154
170
  if defined?(HTTPClient::JRubySSLSocket)
@@ -237,7 +253,7 @@ end
237
253
  def test_use_higher_TLS
238
254
  omit('TODO: it does not pass with Java 7 or old openssl ')
239
255
  teardown_server
240
- setup_server_with_ssl_version(:TLSv1_2)
256
+ setup_server_with_ssl_version('TLSv1_2')
241
257
  assert_nothing_raised do
242
258
  @client.ssl_config.verify_mode = nil
243
259
  @client.get("https://localhost:#{serverport}/hello")
@@ -288,6 +304,10 @@ private
288
304
  end
289
305
 
290
306
  def setup_server_with_ssl_version(ssl_version)
307
+ # JRubyOpenSSL does not support "TLSv1_2" as an known version, and some JCE provides TLS v1.2 as "TLSv1.2" not "TLSv1_2"
308
+ if RUBY_ENGINE == 'jruby' && ['TLSv1_1', 'TLSv1_2'].include?(ssl_version)
309
+ ssl_version = ssl_version.tr('_', '.')
310
+ end
291
311
  logger = Logger.new(STDERR)
292
312
  logger.level = Logger::Severity::FATAL # avoid logging SSLError (ERROR level)
293
313
  @server = WEBrick::HTTPServer.new(
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: httpclient
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.8.0
4
+ version: 2.8.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Hiroshi Nakamura
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-04-24 00:00:00.000000000 Z
11
+ date: 2016-08-07 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description:
14
14
  email: nahi@ruby-lang.org
@@ -103,7 +103,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
103
103
  version: '0'
104
104
  requirements: []
105
105
  rubyforge_project:
106
- rubygems_version: 2.5.1
106
+ rubygems_version: 2.4.5.1
107
107
  signing_key:
108
108
  specification_version: 4
109
109
  summary: gives something like the functionality of libwww-perl (LWP) in Ruby