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/test/test_httpclient.rb
CHANGED
@@ -115,6 +115,14 @@ class TestHTTPClient < Test::Unit::TestCase
|
|
115
115
|
assert_equal("Accept: text/html", lines[4])
|
116
116
|
end
|
117
117
|
|
118
|
+
def test_header_symbol
|
119
|
+
str = ""
|
120
|
+
@client.debug_dev = str
|
121
|
+
@client.post(serverurl + 'servlet', :header => {:'Content-Type' => 'application/json'}, :body => 'hello')
|
122
|
+
lines = str.split(/(?:\r?\n)+/).grep(/^Content-Type/)
|
123
|
+
assert_equal(2, lines.size) # 1 for both request and response
|
124
|
+
end
|
125
|
+
|
118
126
|
def test_host_given
|
119
127
|
str = ""
|
120
128
|
@client.debug_dev = str
|
@@ -138,7 +146,7 @@ class TestHTTPClient < Test::Unit::TestCase
|
|
138
146
|
|
139
147
|
def test_redirect_returns_not_modified
|
140
148
|
assert_nothing_raised do
|
141
|
-
timeout(2) do
|
149
|
+
::Timeout.timeout(2) do
|
142
150
|
@client.get(serverurl + 'status', {:status => 306}, {:follow_redirect => true})
|
143
151
|
end
|
144
152
|
end
|
@@ -531,7 +539,7 @@ EOS
|
|
531
539
|
|
532
540
|
def test_no_content
|
533
541
|
assert_nothing_raised do
|
534
|
-
timeout(2) do
|
542
|
+
::Timeout.timeout(2) do
|
535
543
|
@client.get(serverurl + 'status', :status => 101)
|
536
544
|
@client.get(serverurl + 'status', :status => 204)
|
537
545
|
@client.get(serverurl + 'status', :status => 304)
|
@@ -568,7 +576,7 @@ EOS
|
|
568
576
|
end
|
569
577
|
|
570
578
|
def test_get_content_with_base_url
|
571
|
-
@client = HTTPClient.new(:base_url => serverurl
|
579
|
+
@client = HTTPClient.new(:base_url => serverurl)
|
572
580
|
assert_equal('hello', @client.get_content('/hello'))
|
573
581
|
assert_equal('hello', @client.get_content('/redirect1'))
|
574
582
|
assert_equal('hello', @client.get_content('/redirect2'))
|
@@ -591,17 +599,22 @@ EOS
|
|
591
599
|
|
592
600
|
GZIP_CONTENT = "\x1f\x8b\x08\x00\x1a\x96\xe0\x4c\x00\x03\xcb\x48\xcd\xc9\xc9\x07\x00\x86\xa6\x10\x36\x05\x00\x00\x00"
|
593
601
|
DEFLATE_CONTENT = "\x78\x9c\xcb\x48\xcd\xc9\xc9\x07\x00\x06\x2c\x02\x15"
|
594
|
-
|
595
|
-
DEFLATE_CONTENT.
|
602
|
+
DEFLATE_NOHEADER_CONTENT = "x\x9C\xCBH\xCD\xC9\xC9\a\x00\x06,\x02\x15"
|
603
|
+
[GZIP_CONTENT, DEFLATE_CONTENT, DEFLATE_NOHEADER_CONTENT].each do |content|
|
604
|
+
content.force_encoding('BINARY') if content.respond_to?(:force_encoding)
|
605
|
+
end
|
596
606
|
def test_get_gzipped_content
|
597
607
|
@client.transparent_gzip_decompression = false
|
598
608
|
content = @client.get_content(serverurl + 'compressed?enc=gzip')
|
599
609
|
assert_not_equal('hello', content)
|
600
610
|
assert_equal(GZIP_CONTENT, content)
|
601
611
|
@client.transparent_gzip_decompression = true
|
612
|
+
@client.reset_all
|
602
613
|
assert_equal('hello', @client.get_content(serverurl + 'compressed?enc=gzip'))
|
603
614
|
assert_equal('hello', @client.get_content(serverurl + 'compressed?enc=deflate'))
|
615
|
+
assert_equal('hello', @client.get_content(serverurl + 'compressed?enc=deflate_noheader'))
|
604
616
|
@client.transparent_gzip_decompression = false
|
617
|
+
@client.reset_all
|
605
618
|
end
|
606
619
|
|
607
620
|
def test_get_content_with_block
|
@@ -676,14 +689,14 @@ EOS
|
|
676
689
|
end
|
677
690
|
|
678
691
|
def test_get_with_base_url
|
679
|
-
@client = HTTPClient.new(:base_url => serverurl
|
692
|
+
@client = HTTPClient.new(:base_url => serverurl)
|
680
693
|
assert_equal("get", @client.get('/servlet').content)
|
681
694
|
param = {'1'=>'2', '3'=>'4'}
|
682
695
|
res = @client.get('/servlet', param)
|
683
696
|
assert_equal(param, params(res.header["x-query"][0]))
|
684
697
|
assert_nil(res.contenttype)
|
685
698
|
#
|
686
|
-
@client.base_url = serverurl[0
|
699
|
+
@client.base_url = serverurl[0...-1] + '/servlet'
|
687
700
|
url = '?5=6&7=8'
|
688
701
|
res = @client.get(url, param)
|
689
702
|
assert_equal(param.merge("5"=>"6", "7"=>"8"), params(res.header["x-query"][0]))
|
@@ -691,7 +704,7 @@ EOS
|
|
691
704
|
end
|
692
705
|
|
693
706
|
def test_get_with_default_header
|
694
|
-
@client = HTTPClient.new(:base_url => serverurl
|
707
|
+
@client = HTTPClient.new(:base_url => serverurl, :default_header => {'x-header' => 'custom'})
|
695
708
|
assert_equal('custom', @client.get('/servlet').headers['X-Header'])
|
696
709
|
@client.default_header = {'x-header' => 'custom2'}
|
697
710
|
assert_equal('custom2', @client.get('/servlet').headers['X-Header'])
|
@@ -754,6 +767,22 @@ EOS
|
|
754
767
|
assert_equal(1000*1000, res.content.read.length)
|
755
768
|
end
|
756
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
|
+
|
757
786
|
def test_get_with_block
|
758
787
|
called = false
|
759
788
|
res = @client.get(serverurl + 'servlet') { |str|
|
@@ -767,8 +796,31 @@ EOS
|
|
767
796
|
|
768
797
|
def test_get_with_block_arity_2
|
769
798
|
called = false
|
770
|
-
res = @client.get(serverurl + 'servlet') { |
|
771
|
-
assert_equal(200,
|
799
|
+
res = @client.get(serverurl + 'servlet') { |blk_res, str|
|
800
|
+
assert_equal(200, blk_res.status)
|
801
|
+
assert_equal('get', str)
|
802
|
+
called = true
|
803
|
+
}
|
804
|
+
assert(called)
|
805
|
+
# res does not have a content
|
806
|
+
assert_nil(res.content)
|
807
|
+
end
|
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)
|
772
824
|
assert_equal('get', str)
|
773
825
|
called = true
|
774
826
|
}
|
@@ -780,7 +832,7 @@ EOS
|
|
780
832
|
def test_get_with_block_string_recycle
|
781
833
|
@client.read_block_size = 2
|
782
834
|
body = []
|
783
|
-
|
835
|
+
_res = @client.get(serverurl + 'servlet') { |str|
|
784
836
|
body << str
|
785
837
|
}
|
786
838
|
assert_equal(2, body.size)
|
@@ -797,7 +849,7 @@ EOS
|
|
797
849
|
url = "http://localhost:#{server.addr[1]}/"
|
798
850
|
body = []
|
799
851
|
begin
|
800
|
-
|
852
|
+
_res = @client.get(url + 'chunked') { |str|
|
801
853
|
body << str
|
802
854
|
}
|
803
855
|
ensure
|
@@ -952,7 +1004,7 @@ EOS
|
|
952
1004
|
1
|
953
1005
|
end
|
954
1006
|
@client.debug_dev = str = StringIO.new
|
955
|
-
|
1007
|
+
_res = @client.post(serverurl + 'servlet', { :file => myio })
|
956
1008
|
assert_match(/\r\n4\r\n/, str.string, 'should send "4" not "45"')
|
957
1009
|
end
|
958
1010
|
|
@@ -969,7 +1021,7 @@ EOS
|
|
969
1021
|
end
|
970
1022
|
end
|
971
1023
|
@client.debug_dev = str = StringIO.new
|
972
|
-
|
1024
|
+
_res = @client.post(serverurl + 'servlet', { :file1 => myio1, :file2 => myio2 })
|
973
1025
|
assert_match(/\r\n45\r\n/, str.string)
|
974
1026
|
end
|
975
1027
|
|
@@ -1021,6 +1073,10 @@ EOS
|
|
1021
1073
|
def test_post_with_custom_multipart_and_file
|
1022
1074
|
STDOUT.sync = true
|
1023
1075
|
File.open(__FILE__) do |file|
|
1076
|
+
def file.original_filename
|
1077
|
+
'file.txt'
|
1078
|
+
end
|
1079
|
+
|
1024
1080
|
ext = { 'Content-Type' => 'multipart/alternative' }
|
1025
1081
|
body = [{ 'Content-Type' => 'text/plain', :content => "this is only a test" },
|
1026
1082
|
{ 'Content-Type' => 'application/x-ruby', :content => file }]
|
@@ -1028,10 +1084,41 @@ EOS
|
|
1028
1084
|
assert_match(/^Content-Type: text\/plain\r\n/m, res.content)
|
1029
1085
|
assert_match(/^this is only a test\r\n/m, res.content)
|
1030
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)
|
1031
1088
|
assert_match(/FIND_TAG_IN_THIS_FILE/, res.content)
|
1032
1089
|
end
|
1033
1090
|
end
|
1034
1091
|
|
1092
|
+
def test_patch
|
1093
|
+
assert_equal("patch", @client.patch(serverurl + 'servlet', '').content)
|
1094
|
+
param = {'1'=>'2', '3'=>'4'}
|
1095
|
+
@client.debug_dev = str = ''
|
1096
|
+
res = @client.patch(serverurl + 'servlet', param)
|
1097
|
+
assert_equal(param, params(res.header["x-query"][0]))
|
1098
|
+
assert_equal('Content-Type: application/x-www-form-urlencoded', str.split(/\r?\n/)[5])
|
1099
|
+
end
|
1100
|
+
|
1101
|
+
def test_patch_with_query_and_body
|
1102
|
+
res = @client.patch(serverurl + 'servlet', :query => {:query => 'query'}, :body => {:body => 'body'})
|
1103
|
+
assert_equal("patch", res.content)
|
1104
|
+
assert_equal("body=body", res.headers["X-Query"])
|
1105
|
+
assert_equal("query=query", res.headers["X-Request-Query"])
|
1106
|
+
end
|
1107
|
+
|
1108
|
+
def test_patch_bytesize
|
1109
|
+
res = @client.patch(serverurl + 'servlet', 'txt' => 'あいうえお')
|
1110
|
+
assert_equal('txt=%E3%81%82%E3%81%84%E3%81%86%E3%81%88%E3%81%8A', res.header["x-query"][0])
|
1111
|
+
assert_equal('15', res.header["x-size"][0])
|
1112
|
+
end
|
1113
|
+
|
1114
|
+
def test_patch_async
|
1115
|
+
param = {'1'=>'2', '3'=>'4'}
|
1116
|
+
conn = @client.patch_async(serverurl + 'servlet', param)
|
1117
|
+
Thread.pass while !conn.finished?
|
1118
|
+
res = conn.pop
|
1119
|
+
assert_equal(param, params(res.header["x-query"][0]))
|
1120
|
+
end
|
1121
|
+
|
1035
1122
|
def test_put
|
1036
1123
|
assert_equal("put", @client.put(serverurl + 'servlet', '').content)
|
1037
1124
|
param = {'1'=>'2', '3'=>'4'}
|
@@ -1240,7 +1327,7 @@ EOS
|
|
1240
1327
|
|
1241
1328
|
def test_http_custom_date_header
|
1242
1329
|
@client.debug_dev = (str = "")
|
1243
|
-
|
1330
|
+
_res = @client.get(serverurl + 'hello', :header => {'Date' => 'foo'})
|
1244
1331
|
lines = str.split(/(?:\r?\n)+/)
|
1245
1332
|
assert_equal('Date: foo', lines[4])
|
1246
1333
|
end
|
@@ -1270,11 +1357,13 @@ EOS
|
|
1270
1357
|
# this test takes 2 sec
|
1271
1358
|
assert_equal('hello?sec=2', @client.get_content(serverurl + 'sleep?sec=2'))
|
1272
1359
|
@client.receive_timeout = 1
|
1360
|
+
@client.reset_all
|
1273
1361
|
assert_equal('hello?sec=0', @client.get_content(serverurl + 'sleep?sec=0'))
|
1274
1362
|
assert_raise(HTTPClient::ReceiveTimeoutError) do
|
1275
1363
|
@client.get_content(serverurl + 'sleep?sec=2')
|
1276
1364
|
end
|
1277
1365
|
@client.receive_timeout = 3
|
1366
|
+
@client.reset_all
|
1278
1367
|
assert_equal('hello?sec=2', @client.get_content(serverurl + 'sleep?sec=2'))
|
1279
1368
|
end
|
1280
1369
|
|
@@ -1282,11 +1371,13 @@ EOS
|
|
1282
1371
|
# this test takes 2 sec
|
1283
1372
|
assert_equal('hello', @client.post(serverurl + 'sleep', :sec => 2).content)
|
1284
1373
|
@client.receive_timeout = 1
|
1374
|
+
@client.reset_all
|
1285
1375
|
assert_equal('hello', @client.post(serverurl + 'sleep', :sec => 0).content)
|
1286
1376
|
assert_raise(HTTPClient::ReceiveTimeoutError) do
|
1287
1377
|
@client.post(serverurl + 'sleep', :sec => 2)
|
1288
1378
|
end
|
1289
1379
|
@client.receive_timeout = 3
|
1380
|
+
@client.reset_all
|
1290
1381
|
assert_equal('hello', @client.post(serverurl + 'sleep', :sec => 2).content)
|
1291
1382
|
end
|
1292
1383
|
|
@@ -1445,6 +1536,7 @@ EOS
|
|
1445
1536
|
assert_equal('text/plain', HTTP::Message.mime_type('foo.txt'))
|
1446
1537
|
assert_equal('text/html', HTTP::Message.mime_type('foo.html'))
|
1447
1538
|
assert_equal('text/html', HTTP::Message.mime_type('foo.htm'))
|
1539
|
+
assert_equal('text/xml', HTTP::Message.mime_type('foo.xml'))
|
1448
1540
|
assert_equal('application/msword', HTTP::Message.mime_type('foo.doc'))
|
1449
1541
|
assert_equal('image/png', HTTP::Message.mime_type('foo.png'))
|
1450
1542
|
assert_equal('image/gif', HTTP::Message.mime_type('foo.gif'))
|
@@ -1738,6 +1830,19 @@ EOS
|
|
1738
1830
|
end
|
1739
1831
|
end
|
1740
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
|
+
|
1741
1846
|
def test_socket_local
|
1742
1847
|
@client.socket_local.host = '127.0.0.1'
|
1743
1848
|
assert_equal('hello', @client.get_content(serverurl + 'hello'))
|
@@ -1803,6 +1908,18 @@ EOS
|
|
1803
1908
|
end
|
1804
1909
|
end
|
1805
1910
|
|
1911
|
+
def test_tcp_keepalive
|
1912
|
+
@client.tcp_keepalive = true
|
1913
|
+
@client.get(serverurl)
|
1914
|
+
|
1915
|
+
# expecting HTTP keepalive caches the socket
|
1916
|
+
session = @client.instance_variable_get(:@session_manager).send(:get_cached_session, HTTPClient::Site.new(URI.parse(serverurl)))
|
1917
|
+
socket = session.instance_variable_get(:@socket)
|
1918
|
+
|
1919
|
+
assert_true(session.tcp_keepalive)
|
1920
|
+
assert_equal(Socket::SO_KEEPALIVE, socket.getsockopt(Socket::SOL_SOCKET, Socket::SO_KEEPALIVE).optname)
|
1921
|
+
end
|
1922
|
+
|
1806
1923
|
private
|
1807
1924
|
|
1808
1925
|
def check_query_get(query)
|
@@ -1840,14 +1957,6 @@ private
|
|
1840
1957
|
@server_thread = start_server_thread(@server)
|
1841
1958
|
end
|
1842
1959
|
|
1843
|
-
def escape_noproxy
|
1844
|
-
backup = HTTPClient::NO_PROXY_HOSTS.dup
|
1845
|
-
HTTPClient::NO_PROXY_HOSTS.clear
|
1846
|
-
yield
|
1847
|
-
ensure
|
1848
|
-
HTTPClient::NO_PROXY_HOSTS.replace(backup)
|
1849
|
-
end
|
1850
|
-
|
1851
1960
|
def add_query_string(req)
|
1852
1961
|
if req.query_string
|
1853
1962
|
'?' + req.query_string
|
@@ -1922,6 +2031,9 @@ private
|
|
1922
2031
|
elsif req.query['enc'] == 'deflate'
|
1923
2032
|
res['content-encoding'] = 'deflate'
|
1924
2033
|
res.body = DEFLATE_CONTENT
|
2034
|
+
elsif req.query['enc'] == 'deflate_noheader'
|
2035
|
+
res['content-encoding'] = 'deflate'
|
2036
|
+
res.body = DEFLATE_NOHEADER_CONTENT
|
1925
2037
|
end
|
1926
2038
|
end
|
1927
2039
|
|
@@ -1966,6 +2078,14 @@ private
|
|
1966
2078
|
res["x-request-query"] = req.query_string
|
1967
2079
|
end
|
1968
2080
|
|
2081
|
+
def do_PATCH(req, res)
|
2082
|
+
res["x-query"] = body_response(req)
|
2083
|
+
param = WEBrick::HTTPUtils.parse_query(req.body) || {}
|
2084
|
+
res["x-size"] = (param['txt'] || '').size
|
2085
|
+
res.body = param['txt'] || 'patch'
|
2086
|
+
res["x-request-query"] = req.query_string
|
2087
|
+
end
|
2088
|
+
|
1969
2089
|
def do_PUT(req, res)
|
1970
2090
|
res["x-query"] = body_response(req)
|
1971
2091
|
param = WEBrick::HTTPUtils.parse_query(req.body) || {}
|