PageRenderTime 40ms CodeModel.GetById 7ms RepoModel.GetById 0ms app.codeStats 0ms

/test/webrick/test_httprequest.rb

http://github.com/ruby/ruby
Ruby | 476 lines | 420 code | 52 blank | 4 comment | 1 complexity | 20369f77635c88e930cbcc5c033c2add MD5 | raw file
Possible License(s): GPL-2.0, BSD-3-Clause, AGPL-3.0
  1. # frozen_string_literal: false
  2. require "webrick"
  3. require "stringio"
  4. require "test/unit"
  5. class TestWEBrickHTTPRequest < Test::Unit::TestCase
  6. def teardown
  7. WEBrick::Utils::TimeoutHandler.terminate
  8. super
  9. end
  10. def test_simple_request
  11. msg = <<-_end_of_message_
  12. GET /
  13. _end_of_message_
  14. req = WEBrick::HTTPRequest.new(WEBrick::Config::HTTP)
  15. req.parse(StringIO.new(msg))
  16. assert(req.meta_vars) # fails if @header was not initialized and iteration is attempted on the nil reference
  17. end
  18. def test_parse_09
  19. msg = <<-_end_of_message_
  20. GET /
  21. foobar # HTTP/0.9 request don't have header nor entity body.
  22. _end_of_message_
  23. req = WEBrick::HTTPRequest.new(WEBrick::Config::HTTP)
  24. req.parse(StringIO.new(msg.gsub(/^ {6}/, "")))
  25. assert_equal("GET", req.request_method)
  26. assert_equal("/", req.unparsed_uri)
  27. assert_equal(WEBrick::HTTPVersion.new("0.9"), req.http_version)
  28. assert_equal(WEBrick::Config::HTTP[:ServerName], req.host)
  29. assert_equal(80, req.port)
  30. assert_equal(false, req.keep_alive?)
  31. assert_equal(nil, req.body)
  32. assert(req.query.empty?)
  33. end
  34. def test_parse_10
  35. msg = <<-_end_of_message_
  36. GET / HTTP/1.0
  37. _end_of_message_
  38. req = WEBrick::HTTPRequest.new(WEBrick::Config::HTTP)
  39. req.parse(StringIO.new(msg.gsub(/^ {6}/, "")))
  40. assert_equal("GET", req.request_method)
  41. assert_equal("/", req.unparsed_uri)
  42. assert_equal(WEBrick::HTTPVersion.new("1.0"), req.http_version)
  43. assert_equal(WEBrick::Config::HTTP[:ServerName], req.host)
  44. assert_equal(80, req.port)
  45. assert_equal(false, req.keep_alive?)
  46. assert_equal(nil, req.body)
  47. assert(req.query.empty?)
  48. end
  49. def test_parse_11
  50. msg = <<-_end_of_message_
  51. GET /path HTTP/1.1
  52. _end_of_message_
  53. req = WEBrick::HTTPRequest.new(WEBrick::Config::HTTP)
  54. req.parse(StringIO.new(msg.gsub(/^ {6}/, "")))
  55. assert_equal("GET", req.request_method)
  56. assert_equal("/path", req.unparsed_uri)
  57. assert_equal("", req.script_name)
  58. assert_equal("/path", req.path_info)
  59. assert_equal(WEBrick::HTTPVersion.new("1.1"), req.http_version)
  60. assert_equal(WEBrick::Config::HTTP[:ServerName], req.host)
  61. assert_equal(80, req.port)
  62. assert_equal(true, req.keep_alive?)
  63. assert_equal(nil, req.body)
  64. assert(req.query.empty?)
  65. end
  66. def test_request_uri_too_large
  67. msg = <<-_end_of_message_
  68. GET /#{"a"*2084} HTTP/1.1
  69. _end_of_message_
  70. req = WEBrick::HTTPRequest.new(WEBrick::Config::HTTP)
  71. assert_raise(WEBrick::HTTPStatus::RequestURITooLarge){
  72. req.parse(StringIO.new(msg.gsub(/^ {6}/, "")))
  73. }
  74. end
  75. def test_parse_headers
  76. msg = <<-_end_of_message_
  77. GET /path HTTP/1.1
  78. Host: test.ruby-lang.org:8080
  79. Connection: close
  80. Accept: text/*;q=0.3, text/html;q=0.7, text/html;level=1,
  81. text/html;level=2;q=0.4, */*;q=0.5
  82. Accept-Encoding: compress;q=0.5
  83. Accept-Encoding: gzip;q=1.0, identity; q=0.4, *;q=0
  84. Accept-Language: en;q=0.5, *; q=0
  85. Accept-Language: ja
  86. Content-Type: text/plain
  87. Content-Length: 7
  88. X-Empty-Header:
  89. foobar
  90. _end_of_message_
  91. req = WEBrick::HTTPRequest.new(WEBrick::Config::HTTP)
  92. req.parse(StringIO.new(msg.gsub(/^ {6}/, "")))
  93. assert_equal(
  94. URI.parse("http://test.ruby-lang.org:8080/path"), req.request_uri)
  95. assert_equal("test.ruby-lang.org", req.host)
  96. assert_equal(8080, req.port)
  97. assert_equal(false, req.keep_alive?)
  98. assert_equal(
  99. %w(text/html;level=1 text/html */* text/html;level=2 text/*),
  100. req.accept)
  101. assert_equal(%w(gzip compress identity *), req.accept_encoding)
  102. assert_equal(%w(ja en *), req.accept_language)
  103. assert_equal(7, req.content_length)
  104. assert_equal("text/plain", req.content_type)
  105. assert_equal("foobar\n", req.body)
  106. assert_equal("", req["x-empty-header"])
  107. assert_equal(nil, req["x-no-header"])
  108. assert(req.query.empty?)
  109. end
  110. def test_parse_header2()
  111. msg = <<-_end_of_message_
  112. POST /foo/bar/../baz?q=a HTTP/1.0
  113. Content-Length: 9
  114. User-Agent:
  115. FOO BAR
  116. BAZ
  117. hogehoge
  118. _end_of_message_
  119. req = WEBrick::HTTPRequest.new(WEBrick::Config::HTTP)
  120. req.parse(StringIO.new(msg.gsub(/^ {6}/, "")))
  121. assert_equal("POST", req.request_method)
  122. assert_equal("/foo/baz", req.path)
  123. assert_equal("", req.script_name)
  124. assert_equal("/foo/baz", req.path_info)
  125. assert_equal("9", req['content-length'])
  126. assert_equal("FOO BAR BAZ", req['user-agent'])
  127. assert_equal("hogehoge\n", req.body)
  128. end
  129. def test_parse_headers3
  130. msg = <<-_end_of_message_
  131. GET /path HTTP/1.1
  132. Host: test.ruby-lang.org
  133. _end_of_message_
  134. req = WEBrick::HTTPRequest.new(WEBrick::Config::HTTP)
  135. req.parse(StringIO.new(msg.gsub(/^ {6}/, "")))
  136. assert_equal(URI.parse("http://test.ruby-lang.org/path"), req.request_uri)
  137. assert_equal("test.ruby-lang.org", req.host)
  138. assert_equal(80, req.port)
  139. msg = <<-_end_of_message_
  140. GET /path HTTP/1.1
  141. Host: 192.168.1.1
  142. _end_of_message_
  143. req = WEBrick::HTTPRequest.new(WEBrick::Config::HTTP)
  144. req.parse(StringIO.new(msg.gsub(/^ {6}/, "")))
  145. assert_equal(URI.parse("http://192.168.1.1/path"), req.request_uri)
  146. assert_equal("192.168.1.1", req.host)
  147. assert_equal(80, req.port)
  148. msg = <<-_end_of_message_
  149. GET /path HTTP/1.1
  150. Host: [fe80::208:dff:feef:98c7]
  151. _end_of_message_
  152. req = WEBrick::HTTPRequest.new(WEBrick::Config::HTTP)
  153. req.parse(StringIO.new(msg.gsub(/^ {6}/, "")))
  154. assert_equal(URI.parse("http://[fe80::208:dff:feef:98c7]/path"),
  155. req.request_uri)
  156. assert_equal("[fe80::208:dff:feef:98c7]", req.host)
  157. assert_equal(80, req.port)
  158. msg = <<-_end_of_message_
  159. GET /path HTTP/1.1
  160. Host: 192.168.1.1:8080
  161. _end_of_message_
  162. req = WEBrick::HTTPRequest.new(WEBrick::Config::HTTP)
  163. req.parse(StringIO.new(msg.gsub(/^ {6}/, "")))
  164. assert_equal(URI.parse("http://192.168.1.1:8080/path"), req.request_uri)
  165. assert_equal("192.168.1.1", req.host)
  166. assert_equal(8080, req.port)
  167. msg = <<-_end_of_message_
  168. GET /path HTTP/1.1
  169. Host: [fe80::208:dff:feef:98c7]:8080
  170. _end_of_message_
  171. req = WEBrick::HTTPRequest.new(WEBrick::Config::HTTP)
  172. req.parse(StringIO.new(msg.gsub(/^ {6}/, "")))
  173. assert_equal(URI.parse("http://[fe80::208:dff:feef:98c7]:8080/path"),
  174. req.request_uri)
  175. assert_equal("[fe80::208:dff:feef:98c7]", req.host)
  176. assert_equal(8080, req.port)
  177. end
  178. def test_parse_get_params
  179. param = "foo=1;foo=2;foo=3;bar=x"
  180. msg = <<-_end_of_message_
  181. GET /path?#{param} HTTP/1.1
  182. Host: test.ruby-lang.org:8080
  183. _end_of_message_
  184. req = WEBrick::HTTPRequest.new(WEBrick::Config::HTTP)
  185. req.parse(StringIO.new(msg.gsub(/^ {6}/, "")))
  186. query = req.query
  187. assert_equal("1", query["foo"])
  188. assert_equal(["1", "2", "3"], query["foo"].to_ary)
  189. assert_equal(["1", "2", "3"], query["foo"].list)
  190. assert_equal("x", query["bar"])
  191. assert_equal(["x"], query["bar"].list)
  192. end
  193. def test_parse_post_params
  194. param = "foo=1;foo=2;foo=3;bar=x"
  195. msg = <<-_end_of_message_
  196. POST /path?foo=x;foo=y;foo=z;bar=1 HTTP/1.1
  197. Host: test.ruby-lang.org:8080
  198. Content-Length: #{param.size}
  199. Content-Type: application/x-www-form-urlencoded
  200. #{param}
  201. _end_of_message_
  202. req = WEBrick::HTTPRequest.new(WEBrick::Config::HTTP)
  203. req.parse(StringIO.new(msg.gsub(/^ {6}/, "")))
  204. query = req.query
  205. assert_equal("1", query["foo"])
  206. assert_equal(["1", "2", "3"], query["foo"].to_ary)
  207. assert_equal(["1", "2", "3"], query["foo"].list)
  208. assert_equal("x", query["bar"])
  209. assert_equal(["x"], query["bar"].list)
  210. end
  211. def test_chunked
  212. crlf = "\x0d\x0a"
  213. expect = File.binread(__FILE__).freeze
  214. msg = <<-_end_of_message_
  215. POST /path HTTP/1.1
  216. Host: test.ruby-lang.org:8080
  217. Transfer-Encoding: chunked
  218. _end_of_message_
  219. msg.gsub!(/^ {6}/, "")
  220. open(__FILE__){|io|
  221. while chunk = io.read(100)
  222. msg << chunk.size.to_s(16) << crlf
  223. msg << chunk << crlf
  224. end
  225. }
  226. msg << "0" << crlf
  227. req = WEBrick::HTTPRequest.new(WEBrick::Config::HTTP)
  228. req.parse(StringIO.new(msg))
  229. assert_equal(expect, req.body)
  230. # chunked req.body_reader
  231. req = WEBrick::HTTPRequest.new(WEBrick::Config::HTTP)
  232. req.parse(StringIO.new(msg))
  233. dst = StringIO.new
  234. IO.copy_stream(req.body_reader, dst)
  235. assert_equal(expect, dst.string)
  236. end
  237. def test_forwarded
  238. msg = <<-_end_of_message_
  239. GET /foo HTTP/1.1
  240. Host: localhost:10080
  241. User-Agent: w3m/0.5.2
  242. X-Forwarded-For: 123.123.123.123
  243. X-Forwarded-Host: forward.example.com
  244. X-Forwarded-Server: server.example.com
  245. Connection: Keep-Alive
  246. _end_of_message_
  247. msg.gsub!(/^ {6}/, "")
  248. req = WEBrick::HTTPRequest.new(WEBrick::Config::HTTP)
  249. req.parse(StringIO.new(msg))
  250. assert_equal("server.example.com", req.server_name)
  251. assert_equal("http://forward.example.com/foo", req.request_uri.to_s)
  252. assert_equal("forward.example.com", req.host)
  253. assert_equal(80, req.port)
  254. assert_equal("123.123.123.123", req.remote_ip)
  255. assert(!req.ssl?)
  256. msg = <<-_end_of_message_
  257. GET /foo HTTP/1.1
  258. Host: localhost:10080
  259. User-Agent: w3m/0.5.2
  260. X-Forwarded-For: 192.168.1.10, 172.16.1.1, 123.123.123.123
  261. X-Forwarded-Host: forward.example.com:8080
  262. X-Forwarded-Server: server.example.com
  263. Connection: Keep-Alive
  264. _end_of_message_
  265. msg.gsub!(/^ {6}/, "")
  266. req = WEBrick::HTTPRequest.new(WEBrick::Config::HTTP)
  267. req.parse(StringIO.new(msg))
  268. assert_equal("server.example.com", req.server_name)
  269. assert_equal("http://forward.example.com:8080/foo", req.request_uri.to_s)
  270. assert_equal("forward.example.com", req.host)
  271. assert_equal(8080, req.port)
  272. assert_equal("123.123.123.123", req.remote_ip)
  273. assert(!req.ssl?)
  274. msg = <<-_end_of_message_
  275. GET /foo HTTP/1.1
  276. Host: localhost:10080
  277. Client-IP: 234.234.234.234
  278. X-Forwarded-Proto: https, http
  279. X-Forwarded-For: 192.168.1.10, 10.0.0.1, 123.123.123.123
  280. X-Forwarded-Host: forward.example.com
  281. X-Forwarded-Server: server.example.com
  282. X-Requested-With: XMLHttpRequest
  283. Connection: Keep-Alive
  284. _end_of_message_
  285. msg.gsub!(/^ {6}/, "")
  286. req = WEBrick::HTTPRequest.new(WEBrick::Config::HTTP)
  287. req.parse(StringIO.new(msg))
  288. assert_equal("server.example.com", req.server_name)
  289. assert_equal("https://forward.example.com/foo", req.request_uri.to_s)
  290. assert_equal("forward.example.com", req.host)
  291. assert_equal(443, req.port)
  292. assert_equal("234.234.234.234", req.remote_ip)
  293. assert(req.ssl?)
  294. msg = <<-_end_of_message_
  295. GET /foo HTTP/1.1
  296. Host: localhost:10080
  297. Client-IP: 234.234.234.234
  298. X-Forwarded-Proto: https
  299. X-Forwarded-For: 192.168.1.10
  300. X-Forwarded-Host: forward1.example.com:1234, forward2.example.com:5678
  301. X-Forwarded-Server: server1.example.com, server2.example.com
  302. X-Requested-With: XMLHttpRequest
  303. Connection: Keep-Alive
  304. _end_of_message_
  305. msg.gsub!(/^ {6}/, "")
  306. req = WEBrick::HTTPRequest.new(WEBrick::Config::HTTP)
  307. req.parse(StringIO.new(msg))
  308. assert_equal("server1.example.com", req.server_name)
  309. assert_equal("https://forward1.example.com:1234/foo", req.request_uri.to_s)
  310. assert_equal("forward1.example.com", req.host)
  311. assert_equal(1234, req.port)
  312. assert_equal("234.234.234.234", req.remote_ip)
  313. assert(req.ssl?)
  314. msg = <<-_end_of_message_
  315. GET /foo HTTP/1.1
  316. Host: localhost:10080
  317. Client-IP: 234.234.234.234
  318. X-Forwarded-Proto: https
  319. X-Forwarded-For: 192.168.1.10
  320. X-Forwarded-Host: [fd20:8b1e:b255:8154:250:56ff:fea8:4d84], forward2.example.com:5678
  321. X-Forwarded-Server: server1.example.com, server2.example.com
  322. X-Requested-With: XMLHttpRequest
  323. Connection: Keep-Alive
  324. _end_of_message_
  325. msg.gsub!(/^ {6}/, "")
  326. req = WEBrick::HTTPRequest.new(WEBrick::Config::HTTP)
  327. req.parse(StringIO.new(msg))
  328. assert_equal("server1.example.com", req.server_name)
  329. assert_equal("https://[fd20:8b1e:b255:8154:250:56ff:fea8:4d84]/foo", req.request_uri.to_s)
  330. assert_equal("[fd20:8b1e:b255:8154:250:56ff:fea8:4d84]", req.host)
  331. assert_equal(443, req.port)
  332. assert_equal("234.234.234.234", req.remote_ip)
  333. assert(req.ssl?)
  334. msg = <<-_end_of_message_
  335. GET /foo HTTP/1.1
  336. Host: localhost:10080
  337. Client-IP: 234.234.234.234
  338. X-Forwarded-Proto: https
  339. X-Forwarded-For: 192.168.1.10
  340. X-Forwarded-Host: [fd20:8b1e:b255:8154:250:56ff:fea8:4d84]:1234, forward2.example.com:5678
  341. X-Forwarded-Server: server1.example.com, server2.example.com
  342. X-Requested-With: XMLHttpRequest
  343. Connection: Keep-Alive
  344. _end_of_message_
  345. msg.gsub!(/^ {6}/, "")
  346. req = WEBrick::HTTPRequest.new(WEBrick::Config::HTTP)
  347. req.parse(StringIO.new(msg))
  348. assert_equal("server1.example.com", req.server_name)
  349. assert_equal("https://[fd20:8b1e:b255:8154:250:56ff:fea8:4d84]:1234/foo", req.request_uri.to_s)
  350. assert_equal("[fd20:8b1e:b255:8154:250:56ff:fea8:4d84]", req.host)
  351. assert_equal(1234, req.port)
  352. assert_equal("234.234.234.234", req.remote_ip)
  353. assert(req.ssl?)
  354. end
  355. def test_continue_sent
  356. msg = <<-_end_of_message_
  357. POST /path HTTP/1.1
  358. Expect: 100-continue
  359. _end_of_message_
  360. msg.gsub!(/^ {6}/, "")
  361. req = WEBrick::HTTPRequest.new(WEBrick::Config::HTTP)
  362. req.parse(StringIO.new(msg))
  363. assert req['expect']
  364. l = msg.size
  365. req.continue
  366. assert_not_equal l, msg.size
  367. assert_match(/HTTP\/1.1 100 continue\r\n\r\n\z/, msg)
  368. assert !req['expect']
  369. end
  370. def test_continue_not_sent
  371. msg = <<-_end_of_message_
  372. POST /path HTTP/1.1
  373. _end_of_message_
  374. msg.gsub!(/^ {6}/, "")
  375. req = WEBrick::HTTPRequest.new(WEBrick::Config::HTTP)
  376. req.parse(StringIO.new(msg))
  377. assert !req['expect']
  378. l = msg.size
  379. req.continue
  380. assert_equal l, msg.size
  381. end
  382. def test_bad_messages
  383. param = "foo=1;foo=2;foo=3;bar=x"
  384. msg = <<-_end_of_message_
  385. POST /path?foo=x;foo=y;foo=z;bar=1 HTTP/1.1
  386. Host: test.ruby-lang.org:8080
  387. Content-Type: application/x-www-form-urlencoded
  388. #{param}
  389. _end_of_message_
  390. assert_raise(WEBrick::HTTPStatus::LengthRequired){
  391. req = WEBrick::HTTPRequest.new(WEBrick::Config::HTTP)
  392. req.parse(StringIO.new(msg.gsub(/^ {6}/, "")))
  393. req.body
  394. }
  395. msg = <<-_end_of_message_
  396. POST /path?foo=x;foo=y;foo=z;bar=1 HTTP/1.1
  397. Host: test.ruby-lang.org:8080
  398. Content-Length: 100000
  399. body is too short.
  400. _end_of_message_
  401. assert_raise(WEBrick::HTTPStatus::BadRequest){
  402. req = WEBrick::HTTPRequest.new(WEBrick::Config::HTTP)
  403. req.parse(StringIO.new(msg.gsub(/^ {6}/, "")))
  404. req.body
  405. }
  406. msg = <<-_end_of_message_
  407. POST /path?foo=x;foo=y;foo=z;bar=1 HTTP/1.1
  408. Host: test.ruby-lang.org:8080
  409. Transfer-Encoding: foobar
  410. body is too short.
  411. _end_of_message_
  412. assert_raise(WEBrick::HTTPStatus::NotImplemented){
  413. req = WEBrick::HTTPRequest.new(WEBrick::Config::HTTP)
  414. req.parse(StringIO.new(msg.gsub(/^ {6}/, "")))
  415. req.body
  416. }
  417. end
  418. def test_eof_raised_when_line_is_nil
  419. assert_raise(WEBrick::HTTPStatus::EOFError) {
  420. req = WEBrick::HTTPRequest.new(WEBrick::Config::HTTP)
  421. req.parse(StringIO.new(""))
  422. }
  423. end
  424. end