httpclient 2.6.0.1 → 2.8.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +1 -1
- data/bin/httpclient +7 -1
- data/lib/http-access2.rb +1 -1
- data/lib/httpclient/auth.rb +3 -3
- data/lib/httpclient/cacert.pem +3952 -0
- data/lib/httpclient/connection.rb +1 -1
- data/lib/httpclient/cookie.rb +10 -10
- data/lib/httpclient/http.rb +9 -4
- data/lib/httpclient/jruby_ssl_socket.rb +588 -0
- data/lib/httpclient/session.rb +199 -262
- data/lib/httpclient/ssl_config.rb +123 -114
- data/lib/httpclient/ssl_socket.rb +150 -0
- data/lib/httpclient/timeout.rb +1 -1
- data/lib/httpclient/util.rb +33 -1
- data/lib/httpclient/version.rb +1 -1
- data/lib/httpclient/webagent-cookie.rb +2 -2
- data/lib/httpclient.rb +72 -20
- data/lib/oauthclient.rb +2 -1
- data/test/helper.rb +7 -5
- data/test/jruby_ssl_socket/test_pemutils.rb +32 -0
- data/test/test_auth.rb +28 -9
- data/test/test_cookie.rb +2 -2
- data/test/test_http-access2.rb +2 -0
- data/test/test_httpclient.rb +143 -23
- data/test/test_ssl.rb +295 -17
- data/test/test_webagent-cookie.rb +2 -2
- metadata +14 -10
- /data/lib/httpclient/{cacert.p7s → cacert1024.pem} +0 -0
- /data/test/{ca-chain.cert → ca-chain.pem} +0 -0
data/lib/httpclient.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
# HTTPClient - HTTP client library.
|
2
|
-
# Copyright (C) 2000-
|
2
|
+
# Copyright (C) 2000-2015 NAKAMURA, Hiroshi <nahi@ruby-lang.org>.
|
3
3
|
#
|
4
4
|
# This program is copyrighted free software by NAKAMURA, Hiroshi. You can
|
5
5
|
# redistribute it and/or modify it under the same terms of Ruby's license;
|
@@ -149,6 +149,16 @@ require 'httpclient/cookie'
|
|
149
149
|
# clnt.ssl_config.set_client_cert_file(user_cert_file, user_key_file)
|
150
150
|
# clnt.get(https_url)
|
151
151
|
#
|
152
|
+
# 4. Revocation check. On JRuby you can set following options to let
|
153
|
+
# HTTPClient to perform revocation check with CRL and OCSP:
|
154
|
+
#
|
155
|
+
# -J-Dcom.sun.security.enableCRLDP=true -J-Dcom.sun.net.ssl.checkRevocation=true
|
156
|
+
# ex. jruby -J-Dcom.sun.security.enableCRLDP=true -J-Dcom.sun.net.ssl.checkRevocation=true app.rb
|
157
|
+
# Revoked cert example: https://test-sspev.verisign.com:2443/test-SSPEV-revoked-verisign.html
|
158
|
+
#
|
159
|
+
# On other platform you can download CRL by yourself and set it via
|
160
|
+
# SSLConfig#add_crl.
|
161
|
+
#
|
152
162
|
# === Handling Cookies
|
153
163
|
#
|
154
164
|
# 1. Using volatile Cookies. Nothing to do. HTTPClient handles Cookies.
|
@@ -299,7 +309,6 @@ class HTTPClient
|
|
299
309
|
if assignable
|
300
310
|
aname = name + '='
|
301
311
|
define_method(aname) { |rhs|
|
302
|
-
reset_all
|
303
312
|
@session_manager.__send__(aname, rhs)
|
304
313
|
}
|
305
314
|
end
|
@@ -326,7 +335,7 @@ class HTTPClient
|
|
326
335
|
attr_accessor :follow_redirect_count
|
327
336
|
# Base url of resources.
|
328
337
|
attr_accessor :base_url
|
329
|
-
#
|
338
|
+
# Default request header.
|
330
339
|
attr_accessor :default_header
|
331
340
|
|
332
341
|
# Set HTTP version as a String:: 'HTTP/1.0' or 'HTTP/1.1'
|
@@ -346,6 +355,8 @@ class HTTPClient
|
|
346
355
|
# if your ruby is older than 2005-09-06, do not set socket_sync = false to
|
347
356
|
# avoid an SSL socket blocking bug in openssl/buffering.rb.
|
348
357
|
attr_proxy(:socket_sync, true)
|
358
|
+
# Enables TCP keepalive; no timing settings exist at present
|
359
|
+
attr_proxy(:tcp_keepalive, true)
|
349
360
|
# User-Agent header in HTTP request.
|
350
361
|
attr_proxy(:agent_name, true)
|
351
362
|
# From header in HTTP request.
|
@@ -355,6 +366,9 @@ class HTTPClient
|
|
355
366
|
attr_proxy(:test_loopback_http_response)
|
356
367
|
# Decompress a compressed (with gzip or deflate) content body transparently. false by default.
|
357
368
|
attr_proxy(:transparent_gzip_decompression, true)
|
369
|
+
# Raise BadResponseError if response size does not match with Content-Length header in response. false by default.
|
370
|
+
# TODO: enable by default
|
371
|
+
attr_proxy(:strict_response_size_check, true)
|
358
372
|
# Local socket address. Set HTTPClient#socket_local.host and HTTPClient#socket_local.port to specify local binding hostname and port of TCP socket.
|
359
373
|
attr_proxy(:socket_local, true)
|
360
374
|
|
@@ -383,10 +397,25 @@ class HTTPClient
|
|
383
397
|
#
|
384
398
|
# After you set :base_url, all resources you pass to get, post and other
|
385
399
|
# methods are recognized to be prefixed with base_url. Say base_url is
|
386
|
-
# 'https://api.example.com/v1
|
400
|
+
# 'https://api.example.com/v1/, get('users') is the same as
|
387
401
|
# get('https://api.example.com/v1/users') internally. You can also pass
|
388
402
|
# full URL from 'http://' even after setting base_url.
|
389
403
|
#
|
404
|
+
# The expected base_url and path behavior is the following. Please take
|
405
|
+
# care of '/' in base_url and path.
|
406
|
+
#
|
407
|
+
# The last '/' is important for base_url:
|
408
|
+
# 1. http://foo/bar/baz/ + path -> http://foo/bar/baz/path
|
409
|
+
# 2. http://foo/bar/baz + path -> http://foo/bar/path
|
410
|
+
# Relative path handling:
|
411
|
+
# 3. http://foo/bar/baz/ + ../path -> http://foo/bar/path
|
412
|
+
# 4. http://foo/bar/baz + ../path -> http://foo/path
|
413
|
+
# 5. http://foo/bar/baz/ + ./path -> http://foo/bar/baz/path
|
414
|
+
# 6. http://foo/bar/baz + ./path -> http://foo/bar/path
|
415
|
+
# The leading '/' of path means absolute path:
|
416
|
+
# 7. http://foo/bar/baz/ + /path -> http://foo/path
|
417
|
+
# 8. http://foo/bar/baz + /path -> http://foo/path
|
418
|
+
#
|
390
419
|
# :default_header is for providing default headers Hash that all HTTP
|
391
420
|
# requests should have, such as custom 'Authorization' header in API.
|
392
421
|
# You can override :default_header with :header Hash parameter in HTTP
|
@@ -396,7 +425,7 @@ class HTTPClient
|
|
396
425
|
# HTTP client must send Authorization header after it gets 401 error
|
397
426
|
# from server from security reason. But in some situation (e.g. API
|
398
427
|
# client) you might want to send Authorization from the beginning.
|
399
|
-
def initialize(*args)
|
428
|
+
def initialize(*args, &block)
|
400
429
|
proxy, agent_name, from, base_url, default_header, force_basic_auth =
|
401
430
|
keyword_argument(args, :proxy, :agent_name, :from, :base_url, :default_header, :force_basic_auth)
|
402
431
|
@proxy = nil # assigned later.
|
@@ -420,6 +449,7 @@ class HTTPClient
|
|
420
449
|
load_environment
|
421
450
|
self.proxy = proxy if proxy
|
422
451
|
keep_webmock_compat
|
452
|
+
instance_eval(&block) if block
|
423
453
|
end
|
424
454
|
|
425
455
|
# webmock 1.6.2 depends on HTTP::Message#body.content to work.
|
@@ -692,9 +722,9 @@ class HTTPClient
|
|
692
722
|
def default_redirect_uri_callback(uri, res)
|
693
723
|
newuri = urify(res.header['location'][0])
|
694
724
|
if !http?(newuri) && !https?(newuri)
|
695
|
-
newuri
|
696
|
-
warn("could be a relative URI in location header which is not recommended")
|
725
|
+
warn("#{newuri}: a relative URI in location header which is not recommended")
|
697
726
|
warn("'The field value consists of a single absolute URI' in HTTP spec")
|
727
|
+
newuri = uri + newuri
|
698
728
|
end
|
699
729
|
if https?(uri) && !https?(newuri)
|
700
730
|
raise BadResponseError.new("redirecting to non-https resource")
|
@@ -713,6 +743,16 @@ class HTTPClient
|
|
713
743
|
request(:get, uri, argument_to_hash(args, :query, :header, :follow_redirect), &block)
|
714
744
|
end
|
715
745
|
|
746
|
+
# Sends PATCH request to the specified URL. See request for arguments.
|
747
|
+
def patch(uri, *args, &block)
|
748
|
+
if hashy_argument_has_keys(args, :query, :body)
|
749
|
+
new_args = args[0]
|
750
|
+
else
|
751
|
+
new_args = argument_to_hash(args, :body, :header)
|
752
|
+
end
|
753
|
+
request(:patch, uri, new_args, &block)
|
754
|
+
end
|
755
|
+
|
716
756
|
# Sends POST request to the specified URL. See request for arguments.
|
717
757
|
# You should not depend on :follow_redirect => true for POST method. It
|
718
758
|
# sends the same POST method to the new location which is prohibited in HTTP spec.
|
@@ -808,13 +848,7 @@ class HTTPClient
|
|
808
848
|
end
|
809
849
|
uri = to_resource_url(uri)
|
810
850
|
if block
|
811
|
-
|
812
|
-
filtered_block = proc { |res, str|
|
813
|
-
block.call(str)
|
814
|
-
}
|
815
|
-
else
|
816
|
-
filtered_block = block
|
817
|
-
end
|
851
|
+
filtered_block = adapt_block(&block)
|
818
852
|
end
|
819
853
|
if follow_redirect
|
820
854
|
follow_redirect(method, uri, query, body, header, &block)
|
@@ -835,6 +869,17 @@ class HTTPClient
|
|
835
869
|
request_async2(:get, uri, argument_to_hash(args, :query, :header))
|
836
870
|
end
|
837
871
|
|
872
|
+
# Sends PATCH request in async style. See request_async2 for arguments.
|
873
|
+
# It immediately returns a HTTPClient::Connection instance as a result.
|
874
|
+
def patch_async(uri, *args)
|
875
|
+
if hashy_argument_has_keys(args, :query, :body)
|
876
|
+
new_args = args[0]
|
877
|
+
else
|
878
|
+
new_args = argument_to_hash(args, :body, :header)
|
879
|
+
end
|
880
|
+
request_async2(:patch, uri, new_args)
|
881
|
+
end
|
882
|
+
|
838
883
|
# Sends POST request in async style. See request_async for arguments.
|
839
884
|
# It immediately returns a HTTPClient::Connection instance as a result.
|
840
885
|
def post_async(uri, *args)
|
@@ -1035,11 +1080,17 @@ private
|
|
1035
1080
|
ENV[name.downcase] || ENV[name.upcase]
|
1036
1081
|
end
|
1037
1082
|
|
1083
|
+
def adapt_block(&block)
|
1084
|
+
return block if block.arity == 2
|
1085
|
+
proc { |r, str| block.call(str) }
|
1086
|
+
end
|
1087
|
+
|
1038
1088
|
def follow_redirect(method, uri, query, body, header, &block)
|
1039
1089
|
uri = to_resource_url(uri)
|
1040
1090
|
if block
|
1091
|
+
b = adapt_block(&block)
|
1041
1092
|
filtered_block = proc { |r, str|
|
1042
|
-
|
1093
|
+
b.call(r, str) if r.ok?
|
1043
1094
|
}
|
1044
1095
|
end
|
1045
1096
|
if HTTP::Message.file?(body)
|
@@ -1080,7 +1131,7 @@ private
|
|
1080
1131
|
def protect_keep_alive_disconnected
|
1081
1132
|
begin
|
1082
1133
|
yield
|
1083
|
-
rescue KeepAliveDisconnected
|
1134
|
+
rescue KeepAliveDisconnected
|
1084
1135
|
# Force to create new connection
|
1085
1136
|
Thread.current[:HTTPClient_AcquireNewConnection] = true
|
1086
1137
|
begin
|
@@ -1101,7 +1152,7 @@ private
|
|
1101
1152
|
boundary = nil
|
1102
1153
|
if body
|
1103
1154
|
_, content_type = header.find { |key, value|
|
1104
|
-
key.downcase == 'content-type'
|
1155
|
+
key.to_s.downcase == 'content-type'
|
1105
1156
|
}
|
1106
1157
|
if content_type
|
1107
1158
|
if /\Amultipart/ =~ content_type
|
@@ -1110,7 +1161,7 @@ private
|
|
1110
1161
|
else
|
1111
1162
|
boundary = create_boundary
|
1112
1163
|
content_type = "#{content_type}; boundary=#{boundary}"
|
1113
|
-
header = override_header(header, '
|
1164
|
+
header = override_header(header, 'content-type', content_type)
|
1114
1165
|
end
|
1115
1166
|
end
|
1116
1167
|
else
|
@@ -1148,7 +1199,7 @@ private
|
|
1148
1199
|
def override_header(header, key, value)
|
1149
1200
|
result = []
|
1150
1201
|
header.each do |k, v|
|
1151
|
-
if k.downcase == key
|
1202
|
+
if k.to_s.downcase == key
|
1152
1203
|
result << [key, value]
|
1153
1204
|
else
|
1154
1205
|
result << [k, v]
|
@@ -1223,6 +1274,7 @@ private
|
|
1223
1274
|
return
|
1224
1275
|
end
|
1225
1276
|
piper, pipew = IO.pipe
|
1277
|
+
pipew.binmode
|
1226
1278
|
res = HTTP::Message.new_response(piper, req.header)
|
1227
1279
|
@debug_dev << "= Request\n\n" if @debug_dev
|
1228
1280
|
sess = @session_manager.query(req, proxy)
|
@@ -1267,7 +1319,7 @@ private
|
|
1267
1319
|
def to_resource_url(uri)
|
1268
1320
|
u = urify(uri)
|
1269
1321
|
if @base_url && u.scheme.nil? && u.host.nil?
|
1270
|
-
urify(@base_url + uri
|
1322
|
+
urify(@base_url) + uri
|
1271
1323
|
else
|
1272
1324
|
u
|
1273
1325
|
end
|
data/lib/oauthclient.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
# HTTPClient - HTTP client library.
|
2
|
-
# Copyright (C) 2000-
|
2
|
+
# Copyright (C) 2000-2015 NAKAMURA, Hiroshi <nahi@ruby-lang.org>.
|
3
3
|
#
|
4
4
|
# This program is copyrighted free software by NAKAMURA, Hiroshi. You can
|
5
5
|
# redistribute it and/or modify it under the same terms of Ruby's license;
|
@@ -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.
|
data/test/helper.rb
CHANGED
@@ -59,11 +59,13 @@ module Helper
|
|
59
59
|
@client = HTTPClient.new
|
60
60
|
end
|
61
61
|
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
62
|
+
def escape_noproxy
|
63
|
+
backup = HTTPClient::NO_PROXY_HOSTS.dup
|
64
|
+
HTTPClient::NO_PROXY_HOSTS.clear
|
65
|
+
yield
|
66
|
+
ensure
|
67
|
+
HTTPClient::NO_PROXY_HOSTS.replace(backup)
|
68
|
+
end
|
67
69
|
|
68
70
|
def setup_proxyserver
|
69
71
|
@proxyserver = WEBrick::HTTPProxyServer.new(
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require File.expand_path('helper', File.join(File.dirname(__FILE__), ".."))
|
2
|
+
|
3
|
+
|
4
|
+
class PEMUtilsTest < Test::Unit::TestCase
|
5
|
+
include Helper
|
6
|
+
|
7
|
+
def setup
|
8
|
+
@raw_cert = "-----BEGIN CERTIFICATE-----\nMIIDOTCCAiGgAwIBAgIBAjANBgkqhkiG9w0BAQsFADBCMRMwEQYKCZImiZPyLGQB\nGRYDb3JnMRkwFwYKCZImiZPyLGQBGRYJcnVieS1sYW5nMRAwDgYDVQQDDAdSdWJ5\nIENBMB4XDTE2MDgxMDE3MjEzNFoXDTE3MDgxMDE3MjEzNFowSzETMBEGCgmSJomT\n8ixkARkWA29yZzEZMBcGCgmSJomT8ixkARkWCXJ1YnktbGFuZzEZMBcGA1UEAwwQ\nUnVieSBjZXJ0aWZpY2F0ZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB\nAJCfsSXpSMpmZCVa+ZCM+QDgomnhDlvnrGDq6pasTaIspGTXgws+7r8Dt/cNe6EH\nHJpRH2cGRiO4yPcfcT9eS4X7k8OC4f33wHfACOmLu6LeoNE8ujmSk6L6WzLUI+sE\nnLZbFrXxoAo4XHsm8vEG9C+jEoXZ1p+47wrAGaDwDQTnzlMy4dT9pRQEJP2G/Rry\nUkuZn8SUWmh3/YS78iaSzsNF1cgE1ealHOrPPFDjiCGDaH/LHyUPYlbFSLZ/B7Qx\nLxi5sePLcywWq/EJrmWpgeVTDjtNijsdKv/A3qkY+fm/oD0pzt7XsfJaP9YKNyJO\nQFdxWZeiPcDF+Hwf+IwSr+kCAwEAAaMxMC8wDgYDVR0PAQH/BAQDAgeAMB0GA1Ud\nDgQWBBQNvzYzJyXemGhxbA8NMXLolDnPyjANBgkqhkiG9w0BAQsFAAOCAQEARIJV\noKejGlOTn71QutnNnu07UtTu0IHs6YqjYzzND+m4JXLN+wvYm72AFUG0b1L7dRg0\niK8XjQrlNQNVqP1Mc6tffchy20neOPOHeiO6qTdRU8P2S8D3Uwe+1qhgxjfE+cWc\nwZmWxYK4HA8c58PxWMqrkr2QqXDplG9KWLvOgrtPGiLLZcQSKhvvB63QzItHBDU6\nRayiJY3oPkK/HrIvFlySqFqzWmuyknkciOFywEHQMz/tcSFJ2QFpPj/tBz9VXohH\nZ8KscmfhZrTPBjo+ky1lz/WraWoz4LMiLnkC2ABczWLRSawu+v3Irx1NFJngt05e\npqwtqIUeg7j+JLiTaA==\n-----END CERTIFICATE-----"
|
9
|
+
end
|
10
|
+
|
11
|
+
def test_read_certificate
|
12
|
+
assert_nothing_raised do
|
13
|
+
binary = HTTPClient::JRubySSLSocket::PEMUtils.read_certificate(@raw_cert)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def test_read_certificate_works_with_random_ascii_text_outside_begin_end
|
18
|
+
raw_cert_with_ascii = "some text before begin\n" + @raw_cert + "\nsome text after end"
|
19
|
+
assert_nothing_raised do
|
20
|
+
binary = HTTPClient::JRubySSLSocket::PEMUtils.read_certificate(raw_cert_with_ascii)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def test_read_certificate_uses_all_content_if_missing_begin_end
|
25
|
+
cert = @raw_cert.sub(/-----BEGIN CERTIFICATE-----/, '').sub(/-----END CERTIFICATE-----/, '')
|
26
|
+
assert_nothing_raised do
|
27
|
+
binary = HTTPClient::JRubySSLSocket::PEMUtils.read_certificate(cert)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
|
32
|
+
end
|
data/test/test_auth.rb
CHANGED
@@ -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
|
@@ -124,6 +123,7 @@ class TestAuth < Test::Unit::TestCase
|
|
124
123
|
end
|
125
124
|
# Make it work if @value == nil
|
126
125
|
class SecurityBuffer < FieldSet
|
126
|
+
remove_method(:data_size) if method_defined?(:data_size)
|
127
127
|
def data_size
|
128
128
|
@active && @value ? @value.size : 0
|
129
129
|
end
|
@@ -230,7 +230,7 @@ class TestAuth < Test::Unit::TestCase
|
|
230
230
|
c.www_auth.basic_auth.instance_eval { @scheme = "BASIC" }
|
231
231
|
c.set_auth("http://localhost:#{serverport}/", 'admin', 'admin')
|
232
232
|
|
233
|
-
|
233
|
+
100.times.map { |idx|
|
234
234
|
Thread.new(idx) { |idx2|
|
235
235
|
Thread.abort_on_exception = true
|
236
236
|
Thread.pass
|
@@ -251,7 +251,7 @@ class TestAuth < Test::Unit::TestCase
|
|
251
251
|
c.test_loopback_http_response << "HTTP/1.0 200 OK\nContent-Length: 2\n\nOK"
|
252
252
|
c.debug_dev = str = ''
|
253
253
|
c.get_content("http://localhost:#{serverport}/basic_auth/sub/dir/")
|
254
|
-
assert_match
|
254
|
+
assert_match(/Authorization: Basic YWRtaW46YWRtaW4=/, str)
|
255
255
|
end
|
256
256
|
|
257
257
|
def test_digest_auth
|
@@ -267,7 +267,7 @@ class TestAuth < Test::Unit::TestCase
|
|
267
267
|
c.test_loopback_http_response << "HTTP/1.0 200 OK\nContent-Length: 2\n\nOK"
|
268
268
|
c.debug_dev = str = ''
|
269
269
|
c.get_content("http://localhost:#{serverport}/digest_auth/sub/dir/")
|
270
|
-
assert_match
|
270
|
+
assert_match(/Authorization: Digest/, str)
|
271
271
|
end
|
272
272
|
|
273
273
|
def test_digest_auth_with_block
|
@@ -332,6 +332,16 @@ class TestAuth < Test::Unit::TestCase
|
|
332
332
|
assert_match(/Proxy-Authorization: Basic YWRtaW46YWRtaW4=/, str)
|
333
333
|
end
|
334
334
|
|
335
|
+
def test_proxy_auth_force
|
336
|
+
c = HTTPClient.new
|
337
|
+
c.set_proxy_auth('admin', 'admin')
|
338
|
+
c.force_basic_auth = true
|
339
|
+
c.test_loopback_http_response << "HTTP/1.0 200 OK\nContent-Length: 2\n\nOK"
|
340
|
+
c.debug_dev = str = ''
|
341
|
+
c.get_content('http://example.com/')
|
342
|
+
assert_match(/Proxy-Authorization: Basic YWRtaW46YWRtaW4=/, str)
|
343
|
+
end
|
344
|
+
|
335
345
|
def test_proxy_auth_reuses_credentials
|
336
346
|
c = HTTPClient.new
|
337
347
|
c.set_proxy_auth('admin', 'admin')
|
@@ -442,11 +452,20 @@ class TestAuth < Test::Unit::TestCase
|
|
442
452
|
end
|
443
453
|
|
444
454
|
def test_basic_auth_post_with_multipart
|
445
|
-
|
446
|
-
|
447
|
-
|
448
|
-
|
449
|
-
|
455
|
+
retry_times = 0
|
456
|
+
begin
|
457
|
+
c = HTTPClient.new
|
458
|
+
c.set_auth("http://localhost:#{serverport}/", 'admin', 'admin')
|
459
|
+
File.open(__FILE__) do |f|
|
460
|
+
# read 'f' twice for authorization negotiation
|
461
|
+
assert_equal('basic_auth OK', c.post("http://localhost:#{serverport}/basic_auth", :file => f).content)
|
462
|
+
end
|
463
|
+
rescue Errno::ECONNRESET, HTTPClient::KeepAliveDisconnected
|
464
|
+
# TODO: WEBrick server returns ECONNRESET/EPIPE before sending Unauthorized response to client?
|
465
|
+
raise if retry_times > 5
|
466
|
+
retry_times += 1
|
467
|
+
sleep 1
|
468
|
+
retry
|
450
469
|
end
|
451
470
|
end
|
452
471
|
|
data/test/test_cookie.rb
CHANGED
@@ -290,8 +290,8 @@ EOF
|
|
290
290
|
def test_load_cookies_escaped
|
291
291
|
uri = urify('http://example.org/')
|
292
292
|
f = Tempfile.new('test_cookie')
|
293
|
-
File.open(f.path, 'w') do |
|
294
|
-
|
293
|
+
File.open(f.path, 'w') do |out|
|
294
|
+
out.write <<EOF
|
295
295
|
http://example.org/ key1 "value" 0 .example.org / 13 0
|
296
296
|
http://example.org/ key2 "" 0 .example.org / 13 0
|
297
297
|
http://example.org/ key3 0 .example.org / 13 0
|
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
|