PageRenderTime 62ms CodeModel.GetById 30ms RepoModel.GetById 0ms app.codeStats 1ms

/test/net/http/test_http.rb

https://github.com/ahwuyeah/ruby
Ruby | 922 lines | 757 code | 154 blank | 11 comment | 4 complexity | 82316d689ce3c331b190d0efae45c10a MD5 | raw file
Possible License(s): BSD-3-Clause, AGPL-3.0, Unlicense, GPL-2.0
  1. # coding: US-ASCII
  2. require 'test/unit'
  3. require 'net/http'
  4. require 'stringio'
  5. require_relative 'utils'
  6. require_relative '../../ruby/envutil'
  7. class TestNetHTTP < Test::Unit::TestCase
  8. def test_class_Proxy
  9. no_proxy_class = Net::HTTP.Proxy nil
  10. assert_equal Net::HTTP, no_proxy_class
  11. proxy_class = Net::HTTP.Proxy 'proxy.example', 8000, 'user', 'pass'
  12. refute_equal Net::HTTP, proxy_class
  13. assert_operator proxy_class, :<, Net::HTTP
  14. assert_equal 'proxy.example', proxy_class.proxy_address
  15. assert_equal 8000, proxy_class.proxy_port
  16. assert_equal 'user', proxy_class.proxy_user
  17. assert_equal 'pass', proxy_class.proxy_pass
  18. http = proxy_class.new 'example'
  19. refute http.proxy_from_env?
  20. proxy_class = Net::HTTP.Proxy 'proxy.example'
  21. assert_equal 'proxy.example', proxy_class.proxy_address
  22. assert_equal 80, proxy_class.proxy_port
  23. end
  24. def test_class_Proxy_from_ENV
  25. clean_http_proxy_env do
  26. ENV['http_proxy'] = 'http://proxy.example:8000'
  27. # These are ignored on purpose. See Bug 4388 and Feature 6546
  28. ENV['http_proxy_user'] = 'user'
  29. ENV['http_proxy_pass'] = 'pass'
  30. proxy_class = Net::HTTP.Proxy :ENV
  31. refute_equal Net::HTTP, proxy_class
  32. assert_operator proxy_class, :<, Net::HTTP
  33. assert_nil proxy_class.proxy_address
  34. assert_nil proxy_class.proxy_user
  35. assert_nil proxy_class.proxy_pass
  36. refute_equal 8000, proxy_class.proxy_port
  37. http = proxy_class.new 'example'
  38. assert http.proxy_from_env?
  39. end
  40. end
  41. def test_edit_path
  42. http = Net::HTTP.new 'example', nil, nil
  43. edited = http.send :edit_path, '/path'
  44. assert_equal '/path', edited
  45. http.use_ssl = true
  46. edited = http.send :edit_path, '/path'
  47. assert_equal '/path', edited
  48. end
  49. def test_edit_path_proxy
  50. http = Net::HTTP.new 'example', nil, 'proxy.example'
  51. edited = http.send :edit_path, '/path'
  52. assert_equal 'http://example/path', edited
  53. http.use_ssl = true
  54. edited = http.send :edit_path, '/path'
  55. assert_equal '/path', edited
  56. end
  57. def test_proxy_address
  58. clean_http_proxy_env do
  59. http = Net::HTTP.new 'example', nil, 'proxy.example'
  60. assert_equal 'proxy.example', http.proxy_address
  61. http = Net::HTTP.new 'example', nil
  62. assert_equal nil, http.proxy_address
  63. end
  64. end
  65. def test_proxy_address_ENV
  66. clean_http_proxy_env do
  67. ENV['http_proxy'] = 'http://proxy.example:8000'
  68. http = Net::HTTP.new 'example'
  69. assert_equal 'proxy.example', http.proxy_address
  70. end
  71. end
  72. def test_proxy_eh_no_proxy
  73. clean_http_proxy_env do
  74. assert_equal false, Net::HTTP.new('example', nil, nil).proxy?
  75. end
  76. end
  77. def test_proxy_eh_ENV
  78. clean_http_proxy_env do
  79. ENV['http_proxy'] = 'http://proxy.example:8000'
  80. http = Net::HTTP.new 'example'
  81. assert_equal true, http.proxy?
  82. end
  83. end
  84. def test_proxy_eh_ENV_none_set
  85. clean_http_proxy_env do
  86. assert_equal false, Net::HTTP.new('example').proxy?
  87. end
  88. end
  89. def test_proxy_eh_ENV_no_proxy
  90. clean_http_proxy_env do
  91. ENV['http_proxy'] = 'http://proxy.example:8000'
  92. ENV['no_proxy'] = 'example'
  93. assert_equal false, Net::HTTP.new('example').proxy?
  94. end
  95. end
  96. def test_proxy_port
  97. clean_http_proxy_env do
  98. http = Net::HTTP.new 'exmaple', nil, 'proxy.example'
  99. assert_equal 'proxy.example', http.proxy_address
  100. assert_equal 80, http.proxy_port
  101. http = Net::HTTP.new 'exmaple', nil, 'proxy.example', 8000
  102. assert_equal 8000, http.proxy_port
  103. http = Net::HTTP.new 'exmaple', nil
  104. assert_equal nil, http.proxy_port
  105. end
  106. end
  107. def test_proxy_port_ENV
  108. clean_http_proxy_env do
  109. ENV['http_proxy'] = 'http://proxy.example:8000'
  110. http = Net::HTTP.new 'example'
  111. assert_equal 8000, http.proxy_port
  112. end
  113. end
  114. def test_newobj
  115. clean_http_proxy_env do
  116. ENV['http_proxy'] = 'http://proxy.example:8000'
  117. http = Net::HTTP.newobj 'example'
  118. assert_equal false, http.proxy?
  119. end
  120. end
  121. def clean_http_proxy_env
  122. orig = {
  123. 'http_proxy' => ENV['http_proxy'],
  124. 'http_proxy_user' => ENV['http_proxy_user'],
  125. 'http_proxy_pass' => ENV['http_proxy_pass'],
  126. 'no_proxy' => ENV['no_proxy'],
  127. }
  128. orig.each_key do |key|
  129. ENV.delete key
  130. end
  131. yield
  132. ensure
  133. orig.each do |key, value|
  134. ENV[key] = value
  135. end
  136. end
  137. end
  138. module TestNetHTTP_version_1_1_methods
  139. def test_s_get
  140. assert_equal $test_net_http_data,
  141. Net::HTTP.get(config('host'), '/', config('port'))
  142. end
  143. def test_head
  144. start {|http|
  145. res = http.head('/')
  146. assert_kind_of Net::HTTPResponse, res
  147. assert_equal $test_net_http_data_type, res['Content-Type']
  148. unless self.is_a?(TestNetHTTP_v1_2_chunked)
  149. assert_equal $test_net_http_data.size, res['Content-Length'].to_i
  150. end
  151. }
  152. end
  153. def test_get
  154. start {|http|
  155. _test_get__get http
  156. _test_get__iter http
  157. _test_get__chunked http
  158. }
  159. end
  160. def _test_get__get(http)
  161. res = http.get('/')
  162. assert_kind_of Net::HTTPResponse, res
  163. assert_kind_of String, res.body
  164. unless self.is_a?(TestNetHTTP_v1_2_chunked)
  165. assert_not_nil res['content-length']
  166. assert_equal $test_net_http_data.size, res['content-length'].to_i
  167. end
  168. assert_equal $test_net_http_data_type, res['Content-Type']
  169. assert_equal $test_net_http_data.size, res.body.size
  170. assert_equal $test_net_http_data, res.body
  171. assert_nothing_raised {
  172. http.get('/', { 'User-Agent' => 'test' }.freeze)
  173. }
  174. assert res.decode_content, '[Bug #7924]' if Net::HTTP::HAVE_ZLIB
  175. end
  176. def _test_get__iter(http)
  177. buf = ''
  178. res = http.get('/') {|s| buf << s }
  179. assert_kind_of Net::HTTPResponse, res
  180. # assert_kind_of String, res.body
  181. unless self.is_a?(TestNetHTTP_v1_2_chunked)
  182. assert_not_nil res['content-length']
  183. assert_equal $test_net_http_data.size, res['content-length'].to_i
  184. end
  185. assert_equal $test_net_http_data_type, res['Content-Type']
  186. assert_equal $test_net_http_data.size, buf.size
  187. assert_equal $test_net_http_data, buf
  188. # assert_equal $test_net_http_data.size, res.body.size
  189. # assert_equal $test_net_http_data, res.body
  190. end
  191. def _test_get__chunked(http)
  192. buf = ''
  193. res = http.get('/') {|s| buf << s }
  194. assert_kind_of Net::HTTPResponse, res
  195. # assert_kind_of String, res.body
  196. unless self.is_a?(TestNetHTTP_v1_2_chunked)
  197. assert_not_nil res['content-length']
  198. assert_equal $test_net_http_data.size, res['content-length'].to_i
  199. end
  200. assert_equal $test_net_http_data_type, res['Content-Type']
  201. assert_equal $test_net_http_data.size, buf.size
  202. assert_equal $test_net_http_data, buf
  203. # assert_equal $test_net_http_data.size, res.body.size
  204. # assert_equal $test_net_http_data, res.body
  205. end
  206. def test_get__break
  207. i = 0
  208. start {|http|
  209. http.get('/') do |str|
  210. i += 1
  211. break
  212. end
  213. }
  214. assert_equal 1, i
  215. end
  216. def test_get__implicit_start
  217. res = new().get('/')
  218. assert_kind_of Net::HTTPResponse, res
  219. assert_kind_of String, res.body
  220. unless self.is_a?(TestNetHTTP_v1_2_chunked)
  221. assert_not_nil res['content-length']
  222. end
  223. assert_equal $test_net_http_data_type, res['Content-Type']
  224. assert_equal $test_net_http_data.size, res.body.size
  225. assert_equal $test_net_http_data, res.body
  226. end
  227. def test_get2
  228. start {|http|
  229. http.get2('/') {|res|
  230. EnvUtil.suppress_warning do
  231. assert_kind_of Net::HTTPResponse, res
  232. assert_kind_of Net::HTTPResponse, res.header
  233. end
  234. unless self.is_a?(TestNetHTTP_v1_2_chunked)
  235. assert_not_nil res['content-length']
  236. end
  237. assert_equal $test_net_http_data_type, res['Content-Type']
  238. assert_kind_of String, res.body
  239. assert_kind_of String, res.entity
  240. assert_equal $test_net_http_data.size, res.body.size
  241. assert_equal $test_net_http_data, res.body
  242. assert_equal $test_net_http_data, res.entity
  243. }
  244. }
  245. end
  246. def test_post
  247. start {|http|
  248. _test_post__base http
  249. _test_post__file http
  250. _test_post__no_data http
  251. }
  252. end
  253. def _test_post__base(http)
  254. uheader = {}
  255. uheader['Accept'] = 'application/octet-stream'
  256. uheader['Content-Type'] = 'application/x-www-form-urlencoded'
  257. data = 'post data'
  258. res = http.post('/', data, uheader)
  259. assert_kind_of Net::HTTPResponse, res
  260. assert_kind_of String, res.body
  261. assert_equal data, res.body
  262. assert_equal data, res.entity
  263. end
  264. def _test_post__file(http)
  265. data = 'post data'
  266. f = StringIO.new
  267. http.post('/', data, {'content-type' => 'application/x-www-form-urlencoded'}, f)
  268. assert_equal data, f.string
  269. end
  270. def _test_post__no_data(http)
  271. unless self.is_a?(TestNetHTTP_v1_2_chunked)
  272. EnvUtil.suppress_warning do
  273. data = nil
  274. res = http.post('/', data)
  275. assert_not_equal '411', res.code
  276. end
  277. end
  278. end
  279. def test_s_post_form
  280. url = "http://#{config('host')}:#{config('port')}/"
  281. res = Net::HTTP.post_form(
  282. URI.parse(url),
  283. "a" => "x")
  284. assert_equal ["a=x"], res.body.split(/[;&]/).sort
  285. res = Net::HTTP.post_form(
  286. URI.parse(url),
  287. "a" => "x",
  288. "b" => "y")
  289. assert_equal ["a=x", "b=y"], res.body.split(/[;&]/).sort
  290. res = Net::HTTP.post_form(
  291. URI.parse(url),
  292. "a" => ["x1", "x2"],
  293. "b" => "y")
  294. assert_equal url, res['X-request-uri']
  295. assert_equal ["a=x1", "a=x2", "b=y"], res.body.split(/[;&]/).sort
  296. res = Net::HTTP.post_form(
  297. URI.parse(url + '?a=x'),
  298. "b" => "y")
  299. assert_equal url + '?a=x', res['X-request-uri']
  300. assert_equal ["b=y"], res.body.split(/[;&]/).sort
  301. end
  302. def test_patch
  303. start {|http|
  304. _test_patch__base http
  305. }
  306. end
  307. def _test_patch__base(http)
  308. uheader = {}
  309. uheader['Accept'] = 'application/octet-stream'
  310. uheader['Content-Type'] = 'application/x-www-form-urlencoded'
  311. data = 'patch data'
  312. res = http.patch('/', data, uheader)
  313. assert_kind_of Net::HTTPResponse, res
  314. assert_kind_of String, res.body
  315. assert_equal data, res.body
  316. assert_equal data, res.entity
  317. end
  318. def test_timeout_during_HTTP_session
  319. bug4246 = "expected the HTTP session to have timed out but have not. c.f. [ruby-core:34203]"
  320. th = nil
  321. # listen for connections... but deliberately do not read
  322. TCPServer.open('localhost', 0) {|server|
  323. port = server.addr[1]
  324. conn = Net::HTTP.new('localhost', port)
  325. conn.read_timeout = 0.01
  326. conn.open_timeout = 0.1
  327. th = Thread.new do
  328. assert_raise(Net::ReadTimeout) {
  329. conn.get('/')
  330. }
  331. end
  332. assert th.join(10), bug4246
  333. }
  334. ensure
  335. th.kill
  336. th.join
  337. end
  338. end
  339. module TestNetHTTP_version_1_2_methods
  340. def test_request
  341. start {|http|
  342. _test_request__GET http
  343. _test_request__accept_encoding http
  344. _test_request__file http
  345. # _test_request__range http # WEBrick does not support Range: header.
  346. _test_request__HEAD http
  347. _test_request__POST http
  348. _test_request__stream_body http
  349. _test_request__uri http
  350. _test_request__uri_host http
  351. }
  352. end
  353. def _test_request__GET(http)
  354. req = Net::HTTP::Get.new('/')
  355. http.request(req) {|res|
  356. assert_kind_of Net::HTTPResponse, res
  357. assert_kind_of String, res.body
  358. unless self.is_a?(TestNetHTTP_v1_2_chunked)
  359. assert_not_nil res['content-length']
  360. assert_equal $test_net_http_data.size, res['content-length'].to_i
  361. end
  362. assert_equal $test_net_http_data.size, res.body.size
  363. assert_equal $test_net_http_data, res.body
  364. assert res.decode_content, 'Bug #7831' if Net::HTTP::HAVE_ZLIB
  365. }
  366. end
  367. def _test_request__accept_encoding(http)
  368. req = Net::HTTP::Get.new('/', 'accept-encoding' => 'deflate')
  369. http.request(req) {|res|
  370. assert_kind_of Net::HTTPResponse, res
  371. assert_kind_of String, res.body
  372. unless self.is_a?(TestNetHTTP_v1_2_chunked)
  373. assert_not_nil res['content-length']
  374. assert_equal $test_net_http_data.size, res['content-length'].to_i
  375. end
  376. assert_equal $test_net_http_data.size, res.body.size
  377. assert_equal $test_net_http_data, res.body
  378. refute res.decode_content, 'Bug #7831' if Net::HTTP::HAVE_ZLIB
  379. }
  380. end
  381. def _test_request__file(http)
  382. req = Net::HTTP::Get.new('/')
  383. http.request(req) {|res|
  384. assert_kind_of Net::HTTPResponse, res
  385. unless self.is_a?(TestNetHTTP_v1_2_chunked)
  386. assert_not_nil res['content-length']
  387. assert_equal $test_net_http_data.size, res['content-length'].to_i
  388. end
  389. f = StringIO.new("".force_encoding("ASCII-8BIT"))
  390. res.read_body f
  391. assert_equal $test_net_http_data.bytesize, f.string.bytesize
  392. assert_equal $test_net_http_data.encoding, f.string.encoding
  393. assert_equal $test_net_http_data, f.string
  394. }
  395. end
  396. def _test_request__range(http)
  397. req = Net::HTTP::Get.new('/')
  398. req['range'] = 'bytes=0-5'
  399. assert_equal $test_net_http_data[0,6], http.request(req).body
  400. end
  401. def _test_request__HEAD(http)
  402. req = Net::HTTP::Head.new('/')
  403. http.request(req) {|res|
  404. assert_kind_of Net::HTTPResponse, res
  405. unless self.is_a?(TestNetHTTP_v1_2_chunked)
  406. assert_not_nil res['content-length']
  407. assert_equal $test_net_http_data.size, res['content-length'].to_i
  408. end
  409. assert_nil res.body
  410. }
  411. end
  412. def _test_request__POST(http)
  413. data = 'post data'
  414. req = Net::HTTP::Post.new('/')
  415. req['Accept'] = $test_net_http_data_type
  416. req['Content-Type'] = 'application/x-www-form-urlencoded'
  417. http.request(req, data) {|res|
  418. assert_kind_of Net::HTTPResponse, res
  419. unless self.is_a?(TestNetHTTP_v1_2_chunked)
  420. assert_equal data.size, res['content-length'].to_i
  421. end
  422. assert_kind_of String, res.body
  423. assert_equal data, res.body
  424. }
  425. end
  426. def _test_request__stream_body(http)
  427. req = Net::HTTP::Post.new('/')
  428. data = $test_net_http_data
  429. req.content_length = data.size
  430. req['Content-Type'] = 'application/x-www-form-urlencoded'
  431. req.body_stream = StringIO.new(data)
  432. res = http.request(req)
  433. assert_kind_of Net::HTTPResponse, res
  434. assert_kind_of String, res.body
  435. assert_equal data.size, res.body.size
  436. assert_equal data, res.body
  437. end
  438. def _test_request__path(http)
  439. uri = URI 'https://example/'
  440. req = Net::HTTP::Get.new('/')
  441. res = http.request(req)
  442. assert_kind_of URI::Generic, req.uri
  443. refute_equal uri, req.uri
  444. assert_equal uri, res.uri
  445. refute_same uri, req.uri
  446. refute_same req.uri, res.uri
  447. end
  448. def _test_request__uri(http)
  449. uri = URI 'https://example/'
  450. req = Net::HTTP::Get.new(uri)
  451. res = http.request(req)
  452. assert_kind_of URI::Generic, req.uri
  453. refute_equal uri, req.uri
  454. assert_equal req.uri, res.uri
  455. refute_same uri, req.uri
  456. refute_same req.uri, res.uri
  457. end
  458. def _test_request__uri_host(http)
  459. uri = URI 'http://example/'
  460. req = Net::HTTP::Get.new(uri)
  461. req['host'] = 'other.example'
  462. res = http.request(req)
  463. assert_kind_of URI::Generic, req.uri
  464. assert_equal URI("http://example:#{http.port}"), res.uri
  465. end
  466. def test_send_request
  467. start {|http|
  468. _test_send_request__GET http
  469. _test_send_request__POST http
  470. }
  471. end
  472. def _test_send_request__GET(http)
  473. res = http.send_request('GET', '/')
  474. assert_kind_of Net::HTTPResponse, res
  475. unless self.is_a?(TestNetHTTP_v1_2_chunked)
  476. assert_equal $test_net_http_data.size, res['content-length'].to_i
  477. end
  478. assert_kind_of String, res.body
  479. assert_equal $test_net_http_data, res.body
  480. end
  481. def _test_send_request__POST(http)
  482. data = 'aaabbb cc ddddddddddd lkjoiu4j3qlkuoa'
  483. res = http.send_request('POST', '/', data, 'content-type' => 'application/x-www-form-urlencoded')
  484. assert_kind_of Net::HTTPResponse, res
  485. assert_kind_of String, res.body
  486. assert_equal data.size, res.body.size
  487. assert_equal data, res.body
  488. end
  489. def test_set_form
  490. require 'tempfile'
  491. Tempfile.create('ruby-test') {|file|
  492. file << "\u{30c7}\u{30fc}\u{30bf}"
  493. data = [
  494. ['name', 'Gonbei Nanashi'],
  495. ['name', "\u{540d}\u{7121}\u{3057}\u{306e}\u{6a29}\u{5175}\u{885b}"],
  496. ['s"i\o', StringIO.new("\u{3042 3044 4e9c 925b}")],
  497. ["file", file, filename: "ruby-test"]
  498. ]
  499. expected = <<"__EOM__".gsub(/\n/, "\r\n")
  500. --<boundary>
  501. Content-Disposition: form-data; name="name"
  502. Gonbei Nanashi
  503. --<boundary>
  504. Content-Disposition: form-data; name="name"
  505. \xE5\x90\x8D\xE7\x84\xA1\xE3\x81\x97\xE3\x81\xAE\xE6\xA8\xA9\xE5\x85\xB5\xE8\xA1\x9B
  506. --<boundary>
  507. Content-Disposition: form-data; name="s\\"i\\\\o"
  508. \xE3\x81\x82\xE3\x81\x84\xE4\xBA\x9C\xE9\x89\x9B
  509. --<boundary>
  510. Content-Disposition: form-data; name="file"; filename="ruby-test"
  511. Content-Type: application/octet-stream
  512. \xE3\x83\x87\xE3\x83\xBC\xE3\x82\xBF
  513. --<boundary>--
  514. __EOM__
  515. start {|http|
  516. _test_set_form_urlencoded(http, data.reject{|k,v|!v.is_a?(String)})
  517. _test_set_form_multipart(http, false, data, expected)
  518. _test_set_form_multipart(http, true, data, expected)
  519. }
  520. }
  521. end
  522. def _test_set_form_urlencoded(http, data)
  523. req = Net::HTTP::Post.new('/')
  524. req.set_form(data)
  525. res = http.request req
  526. assert_equal "name=Gonbei+Nanashi&name=%E5%90%8D%E7%84%A1%E3%81%97%E3%81%AE%E6%A8%A9%E5%85%B5%E8%A1%9B", res.body
  527. end
  528. def _test_set_form_multipart(http, chunked_p, data, expected)
  529. data.each{|k,v|v.rewind rescue nil}
  530. req = Net::HTTP::Post.new('/')
  531. req.set_form(data, 'multipart/form-data')
  532. req['Transfer-Encoding'] = 'chunked' if chunked_p
  533. res = http.request req
  534. body = res.body
  535. assert_match(/\A--(?<boundary>\S+)/, body)
  536. /\A--(?<boundary>\S+)/ =~ body
  537. expected = expected.gsub(/<boundary>/, boundary)
  538. assert_equal(expected, body)
  539. end
  540. def test_set_form_with_file
  541. require 'tempfile'
  542. Tempfile.create('ruby-test') {|file|
  543. file.binmode
  544. file << $test_net_http_data
  545. filename = File.basename(file.to_path)
  546. data = [['file', file]]
  547. expected = <<"__EOM__".gsub(/\n/, "\r\n")
  548. --<boundary>
  549. Content-Disposition: form-data; name="file"; filename="<filename>"
  550. Content-Type: application/octet-stream
  551. <data>
  552. --<boundary>--
  553. __EOM__
  554. expected.sub!(/<filename>/, filename)
  555. expected.sub!(/<data>/, $test_net_http_data)
  556. start {|http|
  557. data.each{|k,v|v.rewind rescue nil}
  558. req = Net::HTTP::Post.new('/')
  559. req.set_form(data, 'multipart/form-data')
  560. res = http.request req
  561. body = res.body
  562. header, _ = body.split(/\r\n\r\n/, 2)
  563. assert_match(/\A--(?<boundary>\S+)/, body)
  564. /\A--(?<boundary>\S+)/ =~ body
  565. expected = expected.gsub(/<boundary>/, boundary)
  566. assert_match(/^--(?<boundary>\S+)\r\n/, header)
  567. assert_match(
  568. /^Content-Disposition: form-data; name="file"; filename="#{filename}"\r\n/,
  569. header)
  570. assert_equal(expected, body)
  571. data.each{|k,v|v.rewind rescue nil}
  572. req['Transfer-Encoding'] = 'chunked'
  573. res = http.request req
  574. #assert_equal(expected, res.body)
  575. }
  576. }
  577. end
  578. end
  579. class TestNetHTTP_v1_2 < Test::Unit::TestCase
  580. CONFIG = {
  581. 'host' => '127.0.0.1',
  582. 'proxy_host' => nil,
  583. 'proxy_port' => nil,
  584. }
  585. include TestNetHTTPUtils
  586. include TestNetHTTP_version_1_1_methods
  587. include TestNetHTTP_version_1_2_methods
  588. def new
  589. Net::HTTP.version_1_2
  590. super
  591. end
  592. end
  593. class TestNetHTTP_v1_2_chunked < Test::Unit::TestCase
  594. CONFIG = {
  595. 'host' => '127.0.0.1',
  596. 'proxy_host' => nil,
  597. 'proxy_port' => nil,
  598. 'chunked' => true,
  599. }
  600. include TestNetHTTPUtils
  601. include TestNetHTTP_version_1_1_methods
  602. include TestNetHTTP_version_1_2_methods
  603. def new
  604. Net::HTTP.version_1_2
  605. super
  606. end
  607. def test_chunked_break
  608. assert_nothing_raised("[ruby-core:29229]") {
  609. start {|http|
  610. http.request_get('/') {|res|
  611. res.read_body {|chunk|
  612. break
  613. }
  614. }
  615. }
  616. }
  617. end
  618. end
  619. class TestNetHTTPContinue < Test::Unit::TestCase
  620. CONFIG = {
  621. 'host' => '127.0.0.1',
  622. 'proxy_host' => nil,
  623. 'proxy_port' => nil,
  624. 'chunked' => true,
  625. }
  626. include TestNetHTTPUtils
  627. def logfile
  628. @debug = StringIO.new('')
  629. end
  630. def mount_proc(&block)
  631. @server.mount('/continue', WEBrick::HTTPServlet::ProcHandler.new(block.to_proc))
  632. end
  633. def test_expect_continue
  634. mount_proc {|req, res|
  635. req.continue
  636. res.body = req.query['body']
  637. }
  638. start {|http|
  639. uheader = {'content-type' => 'application/x-www-form-urlencoded', 'expect' => '100-continue'}
  640. http.continue_timeout = 0.2
  641. http.request_post('/continue', 'body=BODY', uheader) {|res|
  642. assert_equal('BODY', res.read_body)
  643. }
  644. }
  645. assert_match(/Expect: 100-continue/, @debug.string)
  646. assert_match(/HTTP\/1.1 100 continue/, @debug.string)
  647. end
  648. def test_expect_continue_timeout
  649. mount_proc {|req, res|
  650. sleep 0.2
  651. req.continue # just ignored because it's '100'
  652. res.body = req.query['body']
  653. }
  654. start {|http|
  655. uheader = {'content-type' => 'application/x-www-form-urlencoded', 'expect' => '100-continue'}
  656. http.continue_timeout = 0
  657. http.request_post('/continue', 'body=BODY', uheader) {|res|
  658. assert_equal('BODY', res.read_body)
  659. }
  660. }
  661. assert_match(/Expect: 100-continue/, @debug.string)
  662. assert_match(/HTTP\/1.1 100 continue/, @debug.string)
  663. end
  664. def test_expect_continue_error
  665. mount_proc {|req, res|
  666. res.status = 501
  667. res.body = req.query['body']
  668. }
  669. start {|http|
  670. uheader = {'content-type' => 'application/x-www-form-urlencoded', 'expect' => '100-continue'}
  671. http.continue_timeout = 0
  672. http.request_post('/continue', 'body=ERROR', uheader) {|res|
  673. assert_equal('ERROR', res.read_body)
  674. }
  675. }
  676. assert_match(/Expect: 100-continue/, @debug.string)
  677. assert_not_match(/HTTP\/1.1 100 continue/, @debug.string)
  678. end
  679. def test_expect_continue_error_while_waiting
  680. mount_proc {|req, res|
  681. res.status = 501
  682. res.body = req.query['body']
  683. }
  684. start {|http|
  685. uheader = {'content-type' => 'application/x-www-form-urlencoded', 'expect' => '100-continue'}
  686. http.continue_timeout = 0.5
  687. http.request_post('/continue', 'body=ERROR', uheader) {|res|
  688. assert_equal('ERROR', res.read_body)
  689. }
  690. }
  691. assert_match(/Expect: 100-continue/, @debug.string)
  692. assert_not_match(/HTTP\/1.1 100 continue/, @debug.string)
  693. end
  694. end
  695. class TestNetHTTPKeepAlive < Test::Unit::TestCase
  696. CONFIG = {
  697. 'host' => '127.0.0.1',
  698. 'proxy_host' => nil,
  699. 'proxy_port' => nil,
  700. 'RequestTimeout' => 1,
  701. }
  702. include TestNetHTTPUtils
  703. def test_keep_alive_get_auto_reconnect
  704. start {|http|
  705. res = http.get('/')
  706. http.keep_alive_timeout = 1
  707. assert_kind_of Net::HTTPResponse, res
  708. assert_kind_of String, res.body
  709. sleep 1.5
  710. assert_nothing_raised {
  711. res = http.get('/')
  712. }
  713. assert_kind_of Net::HTTPResponse, res
  714. assert_kind_of String, res.body
  715. }
  716. end
  717. def test_keep_alive_get_auto_retry
  718. start {|http|
  719. res = http.get('/')
  720. http.keep_alive_timeout = 5
  721. assert_kind_of Net::HTTPResponse, res
  722. assert_kind_of String, res.body
  723. sleep 1.5
  724. res = http.get('/')
  725. assert_kind_of Net::HTTPResponse, res
  726. assert_kind_of String, res.body
  727. }
  728. end
  729. def test_keep_alive_server_close
  730. def @server.run(sock)
  731. sock.close
  732. end
  733. start {|http|
  734. assert_raises(EOFError, Errno::ECONNRESET, IOError) {
  735. http.get('/')
  736. }
  737. }
  738. end
  739. end
  740. class TestNetHTTPLocalBind < Test::Unit::TestCase
  741. CONFIG = {
  742. 'host' => 'localhost',
  743. 'proxy_host' => nil,
  744. 'proxy_port' => nil,
  745. }
  746. include TestNetHTTPUtils
  747. def test_bind_to_local_host
  748. @server.mount_proc('/show_ip') { |req, res| res.body = req.remote_ip }
  749. http = Net::HTTP.new(config('host'), config('port'))
  750. http.local_host = Addrinfo.tcp(config('host'), config('port')).ip_address
  751. assert_not_nil(http.local_host)
  752. assert_nil(http.local_port)
  753. res = http.get('/show_ip')
  754. assert_equal(http.local_host, res.body)
  755. end
  756. def test_bind_to_local_port
  757. @server.mount_proc('/show_port') { |req, res| res.body = req.peeraddr[1].to_s }
  758. http = Net::HTTP.new(config('host'), config('port'))
  759. http.local_host = Addrinfo.tcp(config('host'), config('port')).ip_address
  760. http.local_port = Addrinfo.tcp(config('host'), 0).bind {|s|
  761. s.local_address.ip_port.to_s
  762. }
  763. assert_not_nil(http.local_host)
  764. assert_not_nil(http.local_port)
  765. res = http.get('/show_port')
  766. assert_equal(http.local_port, res.body)
  767. end
  768. end