PageRenderTime 48ms CodeModel.GetById 13ms RepoModel.GetById 1ms app.codeStats 0ms

/Bazaar/nginx/ngx_ext_modules/lua-nginx-module/t/067-req-socket.t

https://bitbucket.org/redpitaya/redpitaya
Unknown | 754 lines | 649 code | 105 blank | 0 comment | 0 complexity | eeb2ee7810634912abf3ea9d4a03f2a6 MD5 | raw file
Possible License(s): BSD-3-Clause
  1. # vim:set ft= ts=4 sw=4 et fdm=marker:
  2. use lib 'lib';
  3. use t::TestNginxLua;
  4. repeat_each(2);
  5. plan tests => repeat_each() * (blocks() * 3 + 8);
  6. our $HtmlDir = html_dir;
  7. #$ENV{TEST_NGINX_MEMCACHED_PORT} ||= 11211;
  8. no_long_string();
  9. #no_diff();
  10. #log_level 'warn';
  11. no_shuffle();
  12. run_tests();
  13. __DATA__
  14. === TEST 1: sanity
  15. --- config
  16. location /t {
  17. content_by_lua '
  18. local sock, err = ngx.req.socket()
  19. if sock then
  20. ngx.say("got the request socket")
  21. else
  22. ngx.say("failed to get the request socket: ", err)
  23. end
  24. for i = 1, 3 do
  25. local data, err, part = sock:receive(5)
  26. if data then
  27. ngx.say("received: ", data)
  28. else
  29. ngx.say("failed to receive: ", err, " [", part, "]")
  30. end
  31. end
  32. ';
  33. }
  34. --- request
  35. POST /t
  36. hello world
  37. --- response_body
  38. got the request socket
  39. received: hello
  40. received: worl
  41. failed to receive: closed [d]
  42. --- no_error_log
  43. [error]
  44. === TEST 2: multipart rfc sample (just partial streaming)
  45. --- config
  46. location /t {
  47. content_by_lua '
  48. local sock, err = ngx.req.socket()
  49. if sock then
  50. ngx.say("got the request socket")
  51. else
  52. ngx.say("failed to get the request socket: ", err)
  53. end
  54. local boundary
  55. local header = ngx.var.http_content_type
  56. local m = ngx.re.match(header, [[; +boundary=(?:"(.*?)"|(\\w+))]], "jo")
  57. if m then
  58. boundary = m[1] or m[2]
  59. else
  60. ngx.say("invalid content-type header")
  61. return
  62. end
  63. local read_to_boundary = sock:receiveuntil("\\r\\n--" .. boundary)
  64. local read_line = sock:receiveuntil("\\r\\n")
  65. local data, err, part = read_to_boundary()
  66. if data then
  67. ngx.say("preamble: [" .. data .. "]")
  68. else
  69. ngx.say("failed to read the first boundary: ", err)
  70. return
  71. end
  72. local i = 1
  73. while true do
  74. local line, err = read_line()
  75. if not line then
  76. ngx.say("failed to read post-boundary line: ", err)
  77. return
  78. end
  79. m = ngx.re.match(line, "--$", "jo")
  80. if m then
  81. ngx.say("found the end of the stream")
  82. return
  83. end
  84. while true do
  85. local line, err = read_line()
  86. if not line then
  87. ngx.say("failed to read part ", i, " header: ", err)
  88. return
  89. end
  90. if line == "" then
  91. -- the header part completes
  92. break
  93. end
  94. ngx.say("part ", i, " header: [", line, "]")
  95. end
  96. local data, err, part = read_to_boundary()
  97. if data then
  98. ngx.say("part ", i, " body: [" .. data .. "]")
  99. else
  100. ngx.say("failed to read part ", i + 1, " boundary: ", err)
  101. return
  102. end
  103. i = i + 1
  104. end
  105. ';
  106. }
  107. --- request eval
  108. "POST /t
  109. This is the preamble. It is to be ignored, though it
  110. is a handy place for mail composers to include an
  111. explanatory note to non-MIME compliant readers.\r
  112. --simple boundary\r
  113. \r
  114. This is implicitly typed plain ASCII text.
  115. It does NOT end with a linebreak.\r
  116. --simple boundary\r
  117. Content-type: text/plain; charset=us-ascii\r
  118. \r
  119. This is explicitly typed plain ASCII text.
  120. It DOES end with a linebreak.
  121. \r
  122. --simple boundary--\r
  123. This is the epilogue. It is also to be ignored.
  124. "
  125. --- more_headers
  126. Content-Type: multipart/mixed; boundary="simple boundary"
  127. --- response_body
  128. got the request socket
  129. preamble: [This is the preamble. It is to be ignored, though it
  130. is a handy place for mail composers to include an
  131. explanatory note to non-MIME compliant readers.]
  132. part 1 body: [This is implicitly typed plain ASCII text.
  133. It does NOT end with a linebreak.]
  134. part 2 header: [Content-type: text/plain; charset=us-ascii]
  135. part 2 body: [This is explicitly typed plain ASCII text.
  136. It DOES end with a linebreak.
  137. ]
  138. found the end of the stream
  139. --- no_error_log
  140. [error]
  141. === TEST 3: multipart rfc sample (completely streaming)
  142. --- config
  143. location /t {
  144. content_by_lua '
  145. local sock, err = ngx.req.socket()
  146. if sock then
  147. ngx.say("got the request socket")
  148. else
  149. ngx.say("failed to get the request socket: ", err)
  150. end
  151. local boundary
  152. local header = ngx.var.http_content_type
  153. local m = ngx.re.match(header, [[; +boundary=(?:"(.*?)"|(\\w+))]], "jo")
  154. if m then
  155. boundary = m[1] or m[2]
  156. else
  157. ngx.say("invalid content-type header")
  158. return
  159. end
  160. local read_to_boundary = sock:receiveuntil("\\r\\n--" .. boundary)
  161. local read_line = sock:receiveuntil("\\r\\n")
  162. local preamble = ""
  163. while true do
  164. local data, err, part = read_to_boundary(1)
  165. if data then
  166. preamble = preamble .. data
  167. elseif not err then
  168. break
  169. else
  170. ngx.say("failed to read the first boundary: ", err)
  171. return
  172. end
  173. end
  174. ngx.say("preamble: [" .. preamble .. "]")
  175. local i = 1
  176. while true do
  177. local line, err = read_line(50)
  178. if not line and err then
  179. ngx.say("1: failed to read post-boundary line: ", err)
  180. return
  181. end
  182. if line then
  183. local dummy
  184. dummy, err = read_line(1)
  185. if err then
  186. ngx.say("2: failed to read post-boundary line: ", err)
  187. return
  188. end
  189. if dummy then
  190. ngx.say("bad post-boundary line: ", dummy)
  191. return
  192. end
  193. m = ngx.re.match(line, "--$", "jo")
  194. if m then
  195. ngx.say("found the end of the stream")
  196. return
  197. end
  198. end
  199. while true do
  200. local line, err = read_line(50)
  201. if not line and err then
  202. ngx.say("failed to read part ", i, " header: ", err)
  203. return
  204. end
  205. if line then
  206. local line, err = read_line(1)
  207. if line or err then
  208. ngx.say("error")
  209. return
  210. end
  211. end
  212. if line == "" then
  213. -- the header part completes
  214. break
  215. end
  216. ngx.say("part ", i, " header: [", line, "]")
  217. end
  218. local body = ""
  219. while true do
  220. local data, err, part = read_to_boundary(1)
  221. if data then
  222. body = body .. data
  223. elseif err then
  224. ngx.say("failed to read part ", i + 1, " boundary: ", err)
  225. return
  226. else
  227. break
  228. end
  229. end
  230. ngx.say("part ", i, " body: [" .. body .. "]")
  231. i = i + 1
  232. end
  233. ';
  234. }
  235. --- request eval
  236. "POST /t
  237. This is the preamble. It is to be ignored, though it
  238. is a handy place for mail composers to include an
  239. explanatory note to non-MIME compliant readers.\r
  240. --simple boundary\r
  241. \r
  242. This is implicitly typed plain ASCII text.
  243. It does NOT end with a linebreak.\r
  244. --simple boundary\r
  245. Content-type: text/plain; charset=us-ascii\r
  246. \r
  247. This is explicitly typed plain ASCII text.
  248. It DOES end with a linebreak.
  249. \r
  250. --simple boundary--\r
  251. This is the epilogue. It is also to be ignored.
  252. "
  253. --- more_headers
  254. Content-Type: multipart/mixed; boundary="simple boundary"
  255. --- response_body
  256. got the request socket
  257. preamble: [This is the preamble. It is to be ignored, though it
  258. is a handy place for mail composers to include an
  259. explanatory note to non-MIME compliant readers.]
  260. part 1 body: [This is implicitly typed plain ASCII text.
  261. It does NOT end with a linebreak.]
  262. part 2 header: [Content-type: text/plain; charset=us-ascii]
  263. part 2 body: [This is explicitly typed plain ASCII text.
  264. It DOES end with a linebreak.
  265. ]
  266. found the end of the stream
  267. --- no_error_log
  268. [error]
  269. === TEST 4: attempt to use the req socket across request boundary
  270. --- http_config eval
  271. "lua_package_path '$::HtmlDir/?.lua;./?.lua';"
  272. --- config
  273. location /t {
  274. content_by_lua '
  275. local test = require "test"
  276. test.go()
  277. ngx.say("done")
  278. ';
  279. }
  280. --- user_files
  281. >>> test.lua
  282. module("test", package.seeall)
  283. local sock, err
  284. function go()
  285. if not sock then
  286. sock, err = ngx.req.socket()
  287. if sock then
  288. ngx.say("got the request socket")
  289. else
  290. ngx.say("failed to get the request socket: ", err)
  291. end
  292. else
  293. for i = 1, 3 do
  294. local data, err, part = sock:receive(5)
  295. if data then
  296. ngx.say("received: ", data)
  297. else
  298. ngx.say("failed to receive: ", err, " [", part, "]")
  299. end
  300. end
  301. end
  302. end
  303. --- request
  304. POST /t
  305. hello world
  306. --- response_body_like
  307. (?:got the request socket
  308. |failed to receive: closed [d]
  309. )?done
  310. --- no_error_log
  311. [alert]
  312. === TEST 5: receive until on request_body - receiveuntil(1) on the last byte of the body
  313. See https://groups.google.com/group/openresty/browse_thread/thread/43cf01da3c681aba for details
  314. --- http_config eval
  315. "lua_package_path '$::HtmlDir/?.lua;./?.lua';"
  316. --- config
  317. location /t {
  318. content_by_lua '
  319. local test = require "test"
  320. test.go()
  321. ngx.say("done")
  322. ';
  323. }
  324. --- user_files
  325. >>> test.lua
  326. module("test", package.seeall)
  327. function go()
  328. local sock, err = ngx.req.socket()
  329. if sock then
  330. ngx.say("got the request socket")
  331. else
  332. ngx.say("failed to get the request socket: ", err)
  333. return
  334. end
  335. local data, err, part = sock:receive(56)
  336. if data then
  337. ngx.say("received: ", data)
  338. else
  339. ngx.say("failed to receive: ", err, " [", part, "]")
  340. end
  341. local discard_line = sock:receiveuntil('\r\n')
  342. local data, err, part = discard_line(8192)
  343. if data then
  344. ngx.say("received len: ", #data)
  345. else
  346. ngx.say("failed to receive: ", err, " [", part, "]")
  347. end
  348. local data, err, part = discard_line(1)
  349. if data then
  350. ngx.say("received: ", data)
  351. else
  352. ngx.say("failed to receive: ", err, " [", part, "]")
  353. end
  354. end
  355. --- request
  356. POST /t
  357. -----------------------------820127721219505131303151179################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################$
  358. --- response_body
  359. got the request socket
  360. received: -----------------------------820127721219505131303151179
  361. received len: 8192
  362. received: $
  363. done
  364. --- no_error_log
  365. [error]
  366. --- timeout: 10
  367. === TEST 6: pipelined POST requests
  368. --- http_config eval
  369. "lua_package_path '$::HtmlDir/?.lua;./?.lua';"
  370. --- config
  371. location /t {
  372. content_by_lua '
  373. local test = require "test"
  374. test.go()
  375. ngx.say("done")
  376. ';
  377. }
  378. --- user_files
  379. >>> test.lua
  380. module("test", package.seeall)
  381. function go()
  382. local sock, err = ngx.req.socket()
  383. if sock then
  384. ngx.say("got the request socket")
  385. else
  386. ngx.say("failed to get the request socket: ", err)
  387. return
  388. end
  389. while true do
  390. local data, err, part = sock:receive(4)
  391. if data then
  392. ngx.say("received: ", data)
  393. else
  394. ngx.say("failed to receive: ", err, " [", part, "]")
  395. return
  396. end
  397. end
  398. end
  399. --- pipelined_requests eval
  400. ["POST /t
  401. hello, world",
  402. "POST /t
  403. hiya, world"]
  404. --- response_body eval
  405. ["got the request socket
  406. received: hell
  407. received: o, w
  408. received: orld
  409. failed to receive: closed []
  410. done
  411. ",
  412. "got the request socket
  413. received: hiya
  414. received: , wo
  415. failed to receive: closed [rld]
  416. done
  417. "]
  418. --- no_error_log
  419. [error]
  420. === TEST 7: Expect & 100 Continue
  421. --- config
  422. location /t {
  423. content_by_lua '
  424. local sock, err = ngx.req.socket()
  425. if sock then
  426. ngx.say("got the request socket")
  427. else
  428. ngx.say("failed to get the request socket: ", err)
  429. return
  430. end
  431. for i = 1, 3 do
  432. local data, err, part = sock:receive(5)
  433. if data then
  434. ngx.say("received: ", data)
  435. else
  436. ngx.say("failed to receive: ", err, " [", part, "]")
  437. end
  438. end
  439. ';
  440. }
  441. --- request
  442. POST /t
  443. hello world
  444. --- more_headers
  445. Expect: 100-Continue
  446. --- error_code: 100
  447. --- response_body_like chomp
  448. \breceived: hello\b.*?\breceived: worl\b
  449. --- no_error_log
  450. [error]
  451. === TEST 8: pipelined requests, big buffer, small steps
  452. --- config
  453. location /t {
  454. lua_socket_buffer_size 5;
  455. content_by_lua '
  456. local sock, err = ngx.req.socket()
  457. if sock then
  458. ngx.say("got the request socket")
  459. else
  460. ngx.say("failed to get the request socket: ", err)
  461. end
  462. for i = 1, 6 do
  463. local data, err, part = sock:receive(2)
  464. if data then
  465. ngx.say("received: ", data)
  466. else
  467. ngx.say("failed to receive: ", err, " [", part, "]")
  468. end
  469. end
  470. ';
  471. }
  472. --- stap2
  473. M(http-lua-req-socket-consume-preread) {
  474. println("preread: ", user_string_n($arg2, $arg3))
  475. }
  476. --- pipelined_requests eval
  477. ["POST /t
  478. hello world","POST /t
  479. hiya globe"]
  480. --- response_body eval
  481. ["got the request socket
  482. received: he
  483. received: ll
  484. received: o
  485. received: wo
  486. received: rl
  487. failed to receive: closed [d]
  488. ","got the request socket
  489. received: hi
  490. received: ya
  491. received: g
  492. received: lo
  493. received: be
  494. failed to receive: closed []
  495. "]
  496. --- no_error_log
  497. [error]
  498. === TEST 9: chunked support is still a TODO
  499. --- config
  500. location /t {
  501. content_by_lua '
  502. local sock, err = ngx.req.socket()
  503. if sock then
  504. ngx.say("got the request socket")
  505. else
  506. ngx.req.read_body()
  507. ngx.say("failed to get the request socket: ", err)
  508. return
  509. end
  510. for i = 1, 3 do
  511. local data, err, part = sock:receive(5)
  512. if data then
  513. ngx.say("received: ", data)
  514. else
  515. ngx.say("failed to receive: ", err, " [", part, "]")
  516. end
  517. end
  518. ';
  519. }
  520. --- raw_request eval
  521. "POST /t HTTP/1.1\r
  522. Host: localhost\r
  523. Transfer-Encoding: chunked\r
  524. Connection: close\r
  525. \r
  526. b\r
  527. hello world\r
  528. 0\r
  529. \r
  530. "
  531. --- stap2
  532. /*
  533. F(ngx_http_finalize_request) {
  534. if ($r->main->count == 2) {
  535. print_ubacktrace()
  536. }
  537. }
  538. F(ngx_http_free_request) {
  539. print_ubacktrace()
  540. }
  541. */
  542. --- response_body
  543. failed to get the request socket: chunked request bodies not supported yet
  544. --- no_error_log
  545. [error]
  546. [alert]
  547. --- skip_nginx: 4: <1.3.9
  548. === TEST 10: chunked support in ngx.req.read_body
  549. --- config
  550. location /t {
  551. content_by_lua '
  552. ngx.req.read_body()
  553. ngx.say(ngx.req.get_body_data())
  554. ';
  555. }
  556. --- raw_request eval
  557. "POST /t HTTP/1.1\r
  558. Host: localhost\r
  559. Transfer-Encoding: chunked\r
  560. Connection: close\r
  561. \r
  562. b\r
  563. hello world\r
  564. 0\r
  565. \r
  566. "
  567. --- stap2
  568. /*
  569. F(ngx_http_finalize_request) {
  570. if ($r->main->count == 2) {
  571. print_ubacktrace()
  572. }
  573. }
  574. F(ngx_http_free_request) {
  575. print_ubacktrace()
  576. }
  577. */
  578. --- response_body
  579. hello world
  580. --- no_error_log
  581. [error]
  582. [alert]
  583. --- skip_nginx: 4: <1.3.9
  584. === TEST 11: downstream cosocket for GET requests (w/o request bodies)
  585. --- config
  586. #resolver 8.8.8.8;
  587. location = /t {
  588. content_by_lua '
  589. local sock, err = ngx.req.socket()
  590. if not sock then
  591. ngx.say("failed to get socket: ", err)
  592. return nil
  593. end
  594. while true do
  595. local data, err, partial = sock:receive(4096)
  596. ngx.log(ngx.INFO, "Received data")
  597. if err then
  598. ngx.say("err: ", err)
  599. if partial then
  600. ngx.print(partial)
  601. end
  602. break
  603. end
  604. if data then
  605. ngx.print(data)
  606. end
  607. end
  608. ';
  609. }
  610. --- request
  611. GET /t
  612. --- response_body
  613. failed to get socket: no body
  614. --- no_error_log
  615. [error]
  616. === TEST 12: downstream cosocket for POST requests with 0 size bodies
  617. --- config
  618. #resolver 8.8.8.8;
  619. location = /t {
  620. content_by_lua '
  621. local sock, err = ngx.req.socket()
  622. if not sock then
  623. ngx.say("failed to get socket: ", err)
  624. return nil
  625. end
  626. while true do
  627. local data, err, partial = sock:receive(4096)
  628. ngx.log(ngx.INFO, "Received data")
  629. if err then
  630. ngx.say("err: ", err)
  631. if partial then
  632. ngx.print(partial)
  633. end
  634. break
  635. end
  636. if data then
  637. ngx.print(data)
  638. end
  639. end
  640. ';
  641. }
  642. --- request
  643. POST /t
  644. --- more_headers
  645. Content-Length: 0
  646. --- response_body
  647. failed to get socket: no body
  648. --- no_error_log
  649. [error]