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 +4 -4
- data/bin/httpclient +2 -0
- data/lib/httpclient.rb +12 -9
- data/lib/httpclient/http.rb +4 -1
- data/lib/httpclient/jruby_ssl_socket.rb +18 -14
- data/lib/httpclient/session.rb +24 -11
- data/lib/httpclient/ssl_config.rb +31 -12
- data/lib/httpclient/version.rb +1 -1
- data/lib/httpclient/webagent-cookie.rb +1 -1
- data/lib/oauthclient.rb +1 -0
- data/test/test_auth.rb +0 -1
- data/test/test_http-access2.rb +2 -0
- data/test/test_httpclient.rb +64 -0
- data/test/test_ssl.rb +21 -1
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c4ffce5e3ce378196b7441498f0a93969da6086f
|
4
|
+
data.tar.gz: 91ba9e1062f6515828ae1983ca28eb0a2d40a75d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 743acf9501f271b66d4b7dcc25812ea766f81d4e3eae6f5a4784ce157a3db7f81a386c6d8a7cced0b87cb464040752997047dad0d627cc94fb9451371f34a44b
|
7
|
+
data.tar.gz: 1e14c7fdd6ec23d895310ca70f3a96a6bd44910371f6221c33095fa4302344da15574a109e800493481e8477dbbb33ce4c4d2cb0661e271c0846d3b8674cf8ba
|
data/bin/httpclient
CHANGED
@@ -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)
|
data/lib/httpclient.rb
CHANGED
@@ -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
|
-
|
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
|
-
|
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)
|
data/lib/httpclient/http.rb
CHANGED
@@ -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(
|
293
|
-
cert_str =
|
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 =
|
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(
|
316
|
-
return if
|
317
|
-
if
|
318
|
-
|
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(
|
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
|
-
|
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.
|
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.
|
471
|
+
if !config.verify?
|
468
472
|
tmf = VerifyNoneTrustManagerFactory.new(verify_callback)
|
469
473
|
else
|
470
474
|
tmf = SystemTrustManagerFactory.new(verify_callback)
|
data/lib/httpclient/session.rb
CHANGED
@@ -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
|
-
|
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
|
-
|
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
|
-
@
|
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
|
-
|
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
|
|
data/lib/httpclient/version.rb
CHANGED
data/lib/oauthclient.rb
CHANGED
data/test/test_auth.rb
CHANGED
data/test/test_http-access2.rb
CHANGED
@@ -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
|
data/test/test_httpclient.rb
CHANGED
@@ -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'))
|
data/test/test_ssl.rb
CHANGED
@@ -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(
|
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.
|
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-
|
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
|