PageRenderTime 82ms CodeModel.GetById 17ms app.highlight 59ms RepoModel.GetById 1ms app.codeStats 0ms

/t/066-socket-receiveuntil.t

https://github.com/npk/lua-nginx-module
Unknown | 1332 lines | 1058 code | 274 blank | 0 comment | 0 complexity | ff066bb1a090f9683a360934ae76d2d2 MD5 | raw file
   1# vim:set ft= ts=4 sw=4 et fdm=marker:
   2
   3use lib 'lib';
   4use Test::Nginx::Socket;
   5
   6repeat_each(2);
   7
   8plan tests => repeat_each() * (blocks() * 3);
   9
  10our $HtmlDir = html_dir;
  11
  12$ENV{TEST_NGINX_CLIENT_PORT} ||= server_port();
  13$ENV{TEST_NGINX_MEMCACHED_PORT} ||= 11211;
  14
  15no_long_string();
  16#no_diff();
  17#log_level 'warn';
  18
  19run_tests();
  20
  21__DATA__
  22
  23=== TEST 1: memcached read lines
  24--- config
  25    server_tokens off;
  26    location /t {
  27        set $port $TEST_NGINX_MEMCACHED_PORT;
  28
  29        content_by_lua '
  30            local sock = ngx.socket.tcp()
  31            local port = ngx.var.port
  32
  33            local ok, err = sock:connect("127.0.0.1", port)
  34            if not ok then
  35                ngx.say("failed to connect: ", err)
  36                return
  37            end
  38
  39            ngx.say("connected: ", ok)
  40
  41            local req = "flush_all\\r\\n"
  42
  43            local bytes, err = sock:send(req)
  44            if not bytes then
  45                ngx.say("failed to send request: ", err)
  46                return
  47            end
  48            ngx.say("request sent: ", bytes)
  49
  50            local readline = sock:receiveuntil("\\r\\n")
  51            local line, err, part = readline()
  52            if line then
  53                ngx.say("received: ", line)
  54
  55            else
  56                ngx.say("failed to receive a line: ", err, " [", part, "]")
  57            end
  58
  59            ok, err = sock:close()
  60            ngx.say("close: ", ok, " ", err)
  61        ';
  62    }
  63--- request
  64GET /t
  65--- response_body
  66connected: 1
  67request sent: 11
  68received: OK
  69close: 1 nil
  70--- no_error_log
  71[error]
  72
  73
  74
  75=== TEST 2: http read lines
  76--- config
  77    server_tokens off;
  78    location /t {
  79        set $port $TEST_NGINX_CLIENT_PORT;
  80
  81        content_by_lua '
  82            local sock = ngx.socket.tcp()
  83            local port = ngx.var.port
  84
  85            local ok, err = sock:connect("127.0.0.1", port)
  86            if not ok then
  87                ngx.say("failed to connect: ", err)
  88                return
  89            end
  90
  91            ngx.say("connected: ", ok)
  92
  93            local req = "GET /foo HTTP/1.0\\r\\nHost: localhost\\r\\nConnection: close\\r\\n\\r\\n"
  94
  95            local bytes, err = sock:send(req)
  96            if not bytes then
  97                ngx.say("failed to send request: ", err)
  98                return
  99            end
 100            ngx.say("request sent: ", bytes)
 101
 102            local readline = sock:receiveuntil("\\r\\n")
 103            local line, err, part
 104
 105            for i = 1, 7 do
 106                line, err, part = readline()
 107                if line then
 108                    ngx.say("read: ", line)
 109
 110                else
 111                    ngx.say("failed to read a line: ", err, " [", part, "]")
 112                end
 113            end
 114
 115            ok, err = sock:close()
 116            ngx.say("close: ", ok, " ", err)
 117        ';
 118    }
 119
 120    location /foo {
 121        content_by_lua 'ngx.say("foo")';
 122        more_clear_headers Date;
 123    }
 124--- request
 125GET /t
 126--- response_body eval
 127qq{connected: 1
 128request sent: 57
 129read: HTTP/1.1 200 OK
 130read: Server: nginx
 131read: Content-Type: text/plain
 132read: Content-Length: 4
 133read: Connection: close
 134read: 
 135failed to read a line: closed [foo
 136]
 137close: nil closed
 138}
 139--- no_error_log
 140[error]
 141
 142
 143
 144=== TEST 3: http read all the headers in a single run
 145--- config
 146    server_tokens off;
 147    location /t {
 148        set $port $TEST_NGINX_CLIENT_PORT;
 149
 150        content_by_lua '
 151            local sock = ngx.socket.tcp()
 152            local port = ngx.var.port
 153
 154            local ok, err = sock:connect("127.0.0.1", port)
 155            if not ok then
 156                ngx.say("failed to connect: ", err)
 157                return
 158            end
 159
 160            ngx.say("connected: ", ok)
 161
 162            local req = "GET /foo HTTP/1.0\\r\\nHost: localhost\\r\\nConnection: close\\r\\n\\r\\n"
 163
 164            local bytes, err = sock:send(req)
 165            if not bytes then
 166                ngx.say("failed to send request: ", err)
 167                return
 168            end
 169            ngx.say("request sent: ", bytes)
 170
 171            local read_headers = sock:receiveuntil("\\r\\n\\r\\n")
 172            local line, err, part
 173
 174            for i = 1, 2 do
 175                line, err, part = read_headers()
 176                if line then
 177                    ngx.say("read: ", line)
 178
 179                else
 180                    ngx.say("failed to read a line: ", err, " [", part, "]")
 181                end
 182            end
 183
 184            ok, err = sock:close()
 185            ngx.say("close: ", ok, " ", err)
 186        ';
 187    }
 188
 189    location /foo {
 190        content_by_lua 'ngx.say("foo")';
 191        more_clear_headers Date;
 192    }
 193--- request
 194GET /t
 195--- response_body eval
 196qq{connected: 1
 197request sent: 57
 198read: HTTP/1.1 200 OK\r
 199Server: nginx\r
 200Content-Type: text/plain\r
 201Content-Length: 4\r
 202Connection: close
 203failed to read a line: closed [foo
 204]
 205close: nil closed
 206}
 207--- no_error_log
 208[error]
 209
 210
 211
 212=== TEST 4: ambiguous boundary patterns (abcabd)
 213--- config
 214    server_tokens off;
 215    location /t {
 216        set $port $TEST_NGINX_CLIENT_PORT;
 217
 218        content_by_lua '
 219            -- collectgarbage("collect")
 220
 221            local sock = ngx.socket.tcp()
 222            local port = ngx.var.port
 223
 224            local ok, err = sock:connect("127.0.0.1", port)
 225            if not ok then
 226                ngx.say("failed to connect: ", err)
 227                return
 228            end
 229
 230            ngx.say("connected: ", ok)
 231
 232            local req = "GET /foo HTTP/1.0\\r\\nHost: localhost\\r\\nConnection: close\\r\\n\\r\\n"
 233
 234            local bytes, err = sock:send(req)
 235            if not bytes then
 236                ngx.say("failed to send request: ", err)
 237                return
 238            end
 239            ngx.say("request sent: ", bytes)
 240
 241            local read_headers = sock:receiveuntil("\\r\\n\\r\\n")
 242            local headers, err, part = read_headers()
 243            if not headers then
 244                ngx.say("failed to read headers: ", err, " [", part, "]")
 245            end
 246
 247            local reader = sock:receiveuntil("abcabd")
 248
 249            for i = 1, 2 do
 250                line, err, part = reader()
 251                if line then
 252                    ngx.say("read: ", line)
 253
 254                else
 255                    ngx.say("failed to read a line: ", err, " [", part, "]")
 256                end
 257            end
 258
 259            ok, err = sock:close()
 260            ngx.say("close: ", ok, " ", err)
 261        ';
 262    }
 263
 264    location /foo {
 265        content_by_lua 'ngx.say("abcabcabd")';
 266        more_clear_headers Date;
 267    }
 268--- request
 269GET /t
 270--- response_body eval
 271qq{connected: 1
 272request sent: 57
 273read: abc
 274failed to read a line: closed [
 275]
 276close: nil closed
 277}
 278--- no_error_log
 279[error]
 280
 281
 282
 283=== TEST 5: ambiguous boundary patterns (aa)
 284--- config
 285    server_tokens off;
 286    location /t {
 287        set $port $TEST_NGINX_CLIENT_PORT;
 288
 289        content_by_lua '
 290            -- collectgarbage("collect")
 291
 292            local sock = ngx.socket.tcp()
 293            local port = ngx.var.port
 294
 295            local ok, err = sock:connect("127.0.0.1", port)
 296            if not ok then
 297                ngx.say("failed to connect: ", err)
 298                return
 299            end
 300
 301            ngx.say("connected: ", ok)
 302
 303            local req = "GET /foo HTTP/1.0\\r\\nHost: localhost\\r\\nConnection: close\\r\\n\\r\\n"
 304
 305            local bytes, err = sock:send(req)
 306            if not bytes then
 307                ngx.say("failed to send request: ", err)
 308                return
 309            end
 310            ngx.say("request sent: ", bytes)
 311
 312            local read_headers = sock:receiveuntil("\\r\\n\\r\\n")
 313            local headers, err, part = read_headers()
 314            if not headers then
 315                ngx.say("failed to read headers: ", err, " [", part, "]")
 316            end
 317
 318            local reader = sock:receiveuntil("aa")
 319
 320            for i = 1, 2 do
 321                line, err, part = reader()
 322                if line then
 323                    ngx.say("read: ", line)
 324
 325                else
 326                    ngx.say("failed to read a line: ", err, " [", part, "]")
 327                end
 328            end
 329
 330            ok, err = sock:close()
 331            ngx.say("close: ", ok, " ", err)
 332        ';
 333    }
 334
 335    location /foo {
 336        content_by_lua 'ngx.say("abcabcaad")';
 337        more_clear_headers Date;
 338    }
 339--- request
 340GET /t
 341--- response_body eval
 342qq{connected: 1
 343request sent: 57
 344read: abcabc
 345failed to read a line: closed [d
 346]
 347close: nil closed
 348}
 349--- no_error_log
 350[error]
 351
 352
 353
 354=== TEST 6: ambiguous boundary patterns (aaa)
 355--- config
 356    server_tokens off;
 357    location /t {
 358        set $port $TEST_NGINX_CLIENT_PORT;
 359
 360        content_by_lua '
 361            -- collectgarbage("collect")
 362
 363            local sock = ngx.socket.tcp()
 364            local port = ngx.var.port
 365
 366            local ok, err = sock:connect("127.0.0.1", port)
 367            if not ok then
 368                ngx.say("failed to connect: ", err)
 369                return
 370            end
 371
 372            ngx.say("connected: ", ok)
 373
 374            local req = "GET /foo HTTP/1.0\\r\\nHost: localhost\\r\\nConnection: close\\r\\n\\r\\n"
 375
 376            local bytes, err = sock:send(req)
 377            if not bytes then
 378                ngx.say("failed to send request: ", err)
 379                return
 380            end
 381            ngx.say("request sent: ", bytes)
 382
 383            local read_headers = sock:receiveuntil("\\r\\n\\r\\n")
 384            local headers, err, part = read_headers()
 385            if not headers then
 386                ngx.say("failed to read headers: ", err, " [", part, "]")
 387            end
 388
 389            local reader = sock:receiveuntil("aaa")
 390
 391            for i = 1, 2 do
 392                line, err, part = reader()
 393                if line then
 394                    ngx.say("read: ", line)
 395
 396                else
 397                    ngx.say("failed to read a line: ", err, " [", part, "]")
 398                end
 399            end
 400
 401            ok, err = sock:close()
 402            ngx.say("close: ", ok, " ", err)
 403        ';
 404    }
 405
 406    location /foo {
 407        echo abaabcaaaef;
 408        more_clear_headers Date;
 409    }
 410--- request
 411GET /t
 412--- response_body eval
 413qq{connected: 1
 414request sent: 57
 415read: abaabc
 416failed to read a line: closed [ef
 417]
 418close: nil closed
 419}
 420--- no_error_log
 421[error]
 422
 423
 424
 425=== TEST 7: ambiguous boundary patterns (aaaaad)
 426--- config
 427    server_tokens off;
 428    location /t {
 429        set $port $TEST_NGINX_CLIENT_PORT;
 430
 431        content_by_lua '
 432            -- collectgarbage("collect")
 433
 434            local sock = ngx.socket.tcp()
 435            local port = ngx.var.port
 436
 437            local ok, err = sock:connect("127.0.0.1", port)
 438            if not ok then
 439                ngx.say("failed to connect: ", err)
 440                return
 441            end
 442
 443            ngx.say("connected: ", ok)
 444
 445            local req = "GET /foo HTTP/1.0\\r\\nHost: localhost\\r\\nConnection: close\\r\\n\\r\\n"
 446
 447            local bytes, err = sock:send(req)
 448            if not bytes then
 449                ngx.say("failed to send request: ", err)
 450                return
 451            end
 452            ngx.say("request sent: ", bytes)
 453
 454            local read_headers = sock:receiveuntil("\\r\\n\\r\\n")
 455            local headers, err, part = read_headers()
 456            if not headers then
 457                ngx.say("failed to read headers: ", err, " [", part, "]")
 458            end
 459
 460            local reader = sock:receiveuntil("aaaaad")
 461
 462            for i = 1, 2 do
 463                line, err, part = reader()
 464                if line then
 465                    ngx.say("read: ", line)
 466
 467                else
 468                    ngx.say("failed to read a line: ", err, " [", part, "]")
 469                end
 470            end
 471
 472            ok, err = sock:close()
 473            ngx.say("close: ", ok, " ", err)
 474        ';
 475    }
 476
 477    location /foo {
 478        echo baaaaaaaaeaaaaaaadf;
 479        more_clear_headers Date;
 480    }
 481--- request
 482GET /t
 483--- response_body eval
 484qq{connected: 1
 485request sent: 57
 486read: baaaaaaaaeaa
 487failed to read a line: closed [f
 488]
 489close: nil closed
 490}
 491--- no_error_log
 492[error]
 493
 494
 495
 496=== TEST 8: ambiguous boundary patterns (aaaaad), small buffer, 2 bytes
 497--- config
 498    server_tokens off;
 499    lua_socket_buffer_size 2;
 500    location /t {
 501        set $port $TEST_NGINX_CLIENT_PORT;
 502
 503        content_by_lua '
 504            -- collectgarbage("collect")
 505
 506            local sock = ngx.socket.tcp()
 507            local port = ngx.var.port
 508
 509            local ok, err = sock:connect("127.0.0.1", port)
 510            if not ok then
 511                ngx.say("failed to connect: ", err)
 512                return
 513            end
 514
 515            ngx.say("connected: ", ok)
 516
 517            local req = "GET /foo HTTP/1.0\\r\\nHost: localhost\\r\\nConnection: close\\r\\n\\r\\n"
 518
 519            local bytes, err = sock:send(req)
 520            if not bytes then
 521                ngx.say("failed to send request: ", err)
 522                return
 523            end
 524            ngx.say("request sent: ", bytes)
 525
 526            local read_headers = sock:receiveuntil("\\r\\n\\r\\n")
 527            local headers, err, part = read_headers()
 528            if not headers then
 529                ngx.say("failed to read headers: ", err, " [", part, "]")
 530            end
 531
 532            local reader = sock:receiveuntil("aaaaad")
 533
 534            for i = 1, 2 do
 535                line, err, part = reader()
 536                if line then
 537                    ngx.say("read: ", line)
 538
 539                else
 540                    ngx.say("failed to read a line: ", err, " [", part, "]")
 541                end
 542            end
 543
 544            ok, err = sock:close()
 545            ngx.say("close: ", ok, " ", err)
 546        ';
 547    }
 548
 549    location /foo {
 550        echo baaaaaaaaeaaaaaaadf;
 551        more_clear_headers Date;
 552    }
 553--- request
 554GET /t
 555--- response_body eval
 556qq{connected: 1
 557request sent: 57
 558read: baaaaaaaaeaa
 559failed to read a line: closed [f
 560]
 561close: nil closed
 562}
 563--- no_error_log
 564[error]
 565
 566
 567
 568=== TEST 9: ambiguous boundary patterns (aaaaad), small buffer, 1 byte
 569--- config
 570    server_tokens off;
 571    lua_socket_buffer_size 1;
 572    location /t {
 573        set $port $TEST_NGINX_CLIENT_PORT;
 574
 575        content_by_lua '
 576            -- collectgarbage("collect")
 577
 578            local sock = ngx.socket.tcp()
 579            local port = ngx.var.port
 580
 581            local ok, err = sock:connect("127.0.0.1", port)
 582            if not ok then
 583                ngx.say("failed to connect: ", err)
 584                return
 585            end
 586
 587            ngx.say("connected: ", ok)
 588
 589            local req = "GET /foo HTTP/1.0\\r\\nHost: localhost\\r\\nConnection: close\\r\\n\\r\\n"
 590
 591            local bytes, err = sock:send(req)
 592            if not bytes then
 593                ngx.say("failed to send request: ", err)
 594                return
 595            end
 596            ngx.say("request sent: ", bytes)
 597
 598            local read_headers = sock:receiveuntil("\\r\\n\\r\\n")
 599            local headers, err, part = read_headers()
 600            if not headers then
 601                ngx.say("failed to read headers: ", err, " [", part, "]")
 602            end
 603
 604            local reader = sock:receiveuntil("aaaaad")
 605
 606            for i = 1, 2 do
 607                line, err, part = reader()
 608                if line then
 609                    ngx.say("read: ", line)
 610
 611                else
 612                    ngx.say("failed to read a line: ", err, " [", part, "]")
 613                end
 614            end
 615
 616            ok, err = sock:close()
 617            ngx.say("close: ", ok, " ", err)
 618        ';
 619    }
 620
 621    location /foo {
 622        echo baaaaaaaaeaaaaaaadf;
 623        more_clear_headers Date;
 624    }
 625--- request
 626GET /t
 627--- response_body eval
 628qq{connected: 1
 629request sent: 57
 630read: baaaaaaaaeaa
 631failed to read a line: closed [f
 632]
 633close: nil closed
 634}
 635--- no_error_log
 636[error]
 637
 638
 639
 640=== TEST 10: ambiguous boundary patterns (abcabdabcabe)
 641--- config
 642    server_tokens off;
 643    location /t {
 644        set $port $TEST_NGINX_CLIENT_PORT;
 645
 646        content_by_lua '
 647            -- collectgarbage("collect")
 648
 649            local sock = ngx.socket.tcp()
 650            local port = ngx.var.port
 651
 652            local ok, err = sock:connect("127.0.0.1", port)
 653            if not ok then
 654                ngx.say("failed to connect: ", err)
 655                return
 656            end
 657
 658            ngx.say("connected: ", ok)
 659
 660            local req = "GET /foo HTTP/1.0\\r\\nHost: localhost\\r\\nConnection: close\\r\\n\\r\\n"
 661
 662            local bytes, err = sock:send(req)
 663            if not bytes then
 664                ngx.say("failed to send request: ", err)
 665                return
 666            end
 667            ngx.say("request sent: ", bytes)
 668
 669            local read_headers = sock:receiveuntil("\\r\\n\\r\\n")
 670            local headers, err, part = read_headers()
 671            if not headers then
 672                ngx.say("failed to read headers: ", err, " [", part, "]")
 673            end
 674
 675            local reader = sock:receiveuntil("abcabdabcabe")
 676
 677            for i = 1, 2 do
 678                line, err, part = reader()
 679                if line then
 680                    ngx.say("read: ", line)
 681
 682                else
 683                    ngx.say("failed to read a line: ", err, " [", part, "]")
 684                end
 685            end
 686
 687            ok, err = sock:close()
 688            ngx.say("close: ", ok, " ", err)
 689        ';
 690    }
 691
 692    location /foo {
 693        echo abcabdabcabdabcabe;
 694        more_clear_headers Date;
 695    }
 696--- request
 697GET /t
 698--- response_body eval
 699qq{connected: 1
 700request sent: 57
 701read: abcabd
 702failed to read a line: closed [
 703]
 704close: nil closed
 705}
 706--- no_error_log
 707[error]
 708
 709
 710
 711=== TEST 11: ambiguous boundary patterns (abcabdabcabe 2)
 712--- config
 713    server_tokens off;
 714    location /t {
 715        set $port $TEST_NGINX_CLIENT_PORT;
 716
 717        content_by_lua '
 718            -- collectgarbage("collect")
 719
 720            local sock = ngx.socket.tcp()
 721            local port = ngx.var.port
 722
 723            local ok, err = sock:connect("127.0.0.1", port)
 724            if not ok then
 725                ngx.say("failed to connect: ", err)
 726                return
 727            end
 728
 729            ngx.say("connected: ", ok)
 730
 731            local req = "GET /foo HTTP/1.0\\r\\nHost: localhost\\r\\nConnection: close\\r\\n\\r\\n"
 732
 733            local bytes, err = sock:send(req)
 734            if not bytes then
 735                ngx.say("failed to send request: ", err)
 736                return
 737            end
 738            ngx.say("request sent: ", bytes)
 739
 740            local read_headers = sock:receiveuntil("\\r\\n\\r\\n")
 741            local headers, err, part = read_headers()
 742            if not headers then
 743                ngx.say("failed to read headers: ", err, " [", part, "]")
 744            end
 745
 746            local reader = sock:receiveuntil("abcabdabcabe")
 747
 748            for i = 1, 2 do
 749                line, err, part = reader()
 750                if line then
 751                    ngx.say("read: ", line)
 752
 753                else
 754                    ngx.say("failed to read a line: ", err, " [", part, "]")
 755                end
 756            end
 757
 758            ok, err = sock:close()
 759            ngx.say("close: ", ok, " ", err)
 760        ';
 761    }
 762
 763    location /foo {
 764        echo abcabdabcabcabdabcabe;
 765        more_clear_headers Date;
 766    }
 767--- request
 768GET /t
 769--- response_body eval
 770qq{connected: 1
 771request sent: 57
 772read: abcabdabc
 773failed to read a line: closed [
 774]
 775close: nil closed
 776}
 777--- no_error_log
 778[error]
 779
 780
 781
 782=== TEST 12: ambiguous boundary patterns (abcabdabcabe 3)
 783--- config
 784    server_tokens off;
 785    location /t {
 786        set $port $TEST_NGINX_CLIENT_PORT;
 787
 788        content_by_lua '
 789            -- collectgarbage("collect")
 790
 791            local sock = ngx.socket.tcp()
 792            local port = ngx.var.port
 793
 794            local ok, err = sock:connect("127.0.0.1", port)
 795            if not ok then
 796                ngx.say("failed to connect: ", err)
 797                return
 798            end
 799
 800            ngx.say("connected: ", ok)
 801
 802            local req = "GET /foo HTTP/1.0\\r\\nHost: localhost\\r\\nConnection: close\\r\\n\\r\\n"
 803
 804            local bytes, err = sock:send(req)
 805            if not bytes then
 806                ngx.say("failed to send request: ", err)
 807                return
 808            end
 809            ngx.say("request sent: ", bytes)
 810
 811            local read_headers = sock:receiveuntil("\\r\\n\\r\\n")
 812            local headers, err, part = read_headers()
 813            if not headers then
 814                ngx.say("failed to read headers: ", err, " [", part, "]")
 815            end
 816
 817            local reader = sock:receiveuntil("abcabdabcabe")
 818
 819            for i = 1, 2 do
 820                line, err, part = reader()
 821                if line then
 822                    ngx.say("read: ", line)
 823
 824                else
 825                    ngx.say("failed to read a line: ", err, " [", part, "]")
 826                end
 827            end
 828
 829            ok, err = sock:close()
 830            ngx.say("close: ", ok, " ", err)
 831        ';
 832    }
 833
 834    location /foo {
 835        echo abcabcabdabcabe;
 836        more_clear_headers Date;
 837    }
 838--- request
 839GET /t
 840--- response_body eval
 841qq{connected: 1
 842request sent: 57
 843read: abc
 844failed to read a line: closed [
 845]
 846close: nil closed
 847}
 848--- no_error_log
 849[error]
 850
 851
 852
 853=== TEST 13: ambiguous boundary patterns (abcabdabcabe 4)
 854--- config
 855    server_tokens off;
 856    location /t {
 857        set $port $TEST_NGINX_CLIENT_PORT;
 858
 859        content_by_lua '
 860            -- collectgarbage("collect")
 861
 862            local sock = ngx.socket.tcp()
 863            local port = ngx.var.port
 864
 865            local ok, err = sock:connect("127.0.0.1", port)
 866            if not ok then
 867                ngx.say("failed to connect: ", err)
 868                return
 869            end
 870
 871            ngx.say("connected: ", ok)
 872
 873            local req = "GET /foo HTTP/1.0\\r\\nHost: localhost\\r\\nConnection: close\\r\\n\\r\\n"
 874
 875            local bytes, err = sock:send(req)
 876            if not bytes then
 877                ngx.say("failed to send request: ", err)
 878                return
 879            end
 880            ngx.say("request sent: ", bytes)
 881
 882            local read_headers = sock:receiveuntil("\\r\\n\\r\\n")
 883            local headers, err, part = read_headers()
 884            if not headers then
 885                ngx.say("failed to read headers: ", err, " [", part, "]")
 886            end
 887
 888            local reader = sock:receiveuntil("abcabdabcabe")
 889
 890            for i = 1, 2 do
 891                line, err, part = reader()
 892                if line then
 893                    ngx.say("read: ", line)
 894
 895                else
 896                    ngx.say("failed to read a line: ", err, " [", part, "]")
 897                end
 898            end
 899
 900            ok, err = sock:close()
 901            ngx.say("close: ", ok, " ", err)
 902        ';
 903    }
 904
 905    location /foo {
 906        echo ababcabdabcabe;
 907        more_clear_headers Date;
 908    }
 909--- request
 910GET /t
 911--- response_body eval
 912qq{connected: 1
 913request sent: 57
 914read: ab
 915failed to read a line: closed [
 916]
 917close: nil closed
 918}
 919--- no_error_log
 920[error]
 921
 922
 923
 924=== TEST 14: ambiguous boundary patterns (--abc)
 925--- config
 926    server_tokens off;
 927    location /t {
 928        set $port $TEST_NGINX_CLIENT_PORT;
 929
 930        content_by_lua '
 931            -- collectgarbage("collect")
 932
 933            local sock = ngx.socket.tcp()
 934            local port = ngx.var.port
 935
 936            local ok, err = sock:connect("127.0.0.1", port)
 937            if not ok then
 938                ngx.say("failed to connect: ", err)
 939                return
 940            end
 941
 942            ngx.say("connected: ", ok)
 943
 944            local req = "GET /foo HTTP/1.0\\r\\nHost: localhost\\r\\nConnection: close\\r\\n\\r\\n"
 945
 946            local bytes, err = sock:send(req)
 947            if not bytes then
 948                ngx.say("failed to send request: ", err)
 949                return
 950            end
 951            ngx.say("request sent: ", bytes)
 952
 953            local read_headers = sock:receiveuntil("\\r\\n\\r\\n")
 954            local headers, err, part = read_headers()
 955            if not headers then
 956                ngx.say("failed to read headers: ", err, " [", part, "]")
 957            end
 958
 959            local reader = sock:receiveuntil("--abc")
 960
 961            for i = 1, 2 do
 962                line, err, part = reader()
 963                if line then
 964                    ngx.say("read: ", line)
 965
 966                else
 967                    ngx.say("failed to read a line: ", err, " [", part, "]")
 968                end
 969            end
 970
 971            ok, err = sock:close()
 972            ngx.say("close: ", ok, " ", err)
 973        ';
 974    }
 975
 976    location /foo {
 977        echo -- ----abc;
 978        more_clear_headers Date;
 979    }
 980--- request
 981GET /t
 982--- response_body eval
 983qq{connected: 1
 984request sent: 57
 985read: --
 986failed to read a line: closed [
 987]
 988close: nil closed
 989}
 990--- no_error_log
 991[error]
 992
 993
 994
 995=== TEST 15: ambiguous boundary patterns (--abc)
 996--- config
 997    server_tokens off;
 998    location /t {
 999        set $port $TEST_NGINX_CLIENT_PORT;
1000
1001        content_by_lua '
1002            -- collectgarbage("collect")
1003
1004            local sock = ngx.socket.tcp()
1005            local port = ngx.var.port
1006
1007            local ok, err = sock:connect("127.0.0.1", port)
1008            if not ok then
1009                ngx.say("failed to connect: ", err)
1010                return
1011            end
1012
1013            ngx.say("connected: ", ok)
1014
1015            local req = "GET /foo HTTP/1.0\\r\\nHost: localhost\\r\\nConnection: close\\r\\n\\r\\n"
1016
1017            local bytes, err = sock:send(req)
1018            if not bytes then
1019                ngx.say("failed to send request: ", err)
1020                return
1021            end
1022            ngx.say("request sent: ", bytes)
1023
1024            local read_headers = sock:receiveuntil("\\r\\n\\r\\n")
1025            local headers, err, part = read_headers()
1026            if not headers then
1027                ngx.say("failed to read headers: ", err, " [", part, "]")
1028            end
1029
1030            local reader = sock:receiveuntil("--abc")
1031
1032            for i = 1, 7 do
1033                line, err, part = reader(4)
1034                if line then
1035                    ngx.say("read: ", line)
1036
1037                else
1038                    ngx.say("failed to read a line: ", err, " [", part, "]")
1039                end
1040            end
1041
1042            ok, err = sock:close()
1043            ngx.say("close: ", ok, " ", err)
1044        ';
1045    }
1046
1047    location /foo {
1048        echo "hello, world ----abc";
1049        more_clear_headers Date;
1050    }
1051--- request
1052GET /t
1053--- response_body eval
1054qq{connected: 1
1055request sent: 57
1056read: hell
1057read: o, w
1058read: orld
1059read:  --
1060read: 
1061failed to read a line: nil [nil]
1062failed to read a line: closed [
1063]
1064close: nil closed
1065}
1066--- no_error_log
1067[error]
1068
1069
1070
1071=== TEST 16: ambiguous boundary patterns (--abc), small buffer
1072--- config
1073    server_tokens off;
1074    location /t {
1075        set $port $TEST_NGINX_CLIENT_PORT;
1076        lua_socket_buffer_size 1;
1077
1078        content_by_lua '
1079            -- collectgarbage("collect")
1080
1081            local sock = ngx.socket.tcp()
1082            local port = ngx.var.port
1083
1084            local ok, err = sock:connect("127.0.0.1", port)
1085            if not ok then
1086                ngx.say("failed to connect: ", err)
1087                return
1088            end
1089
1090            ngx.say("connected: ", ok)
1091
1092            local req = "GET /foo HTTP/1.0\\r\\nHost: localhost\\r\\nConnection: close\\r\\n\\r\\n"
1093
1094            local bytes, err = sock:send(req)
1095            if not bytes then
1096                ngx.say("failed to send request: ", err)
1097                return
1098            end
1099            ngx.say("request sent: ", bytes)
1100
1101            local read_headers = sock:receiveuntil("\\r\\n\\r\\n")
1102            local headers, err, part = read_headers()
1103            if not headers then
1104                ngx.say("failed to read headers: ", err, " [", part, "]")
1105            end
1106
1107            local reader = sock:receiveuntil("--abc")
1108
1109            for i = 1, 7 do
1110                line, err, part = reader(4)
1111                if line then
1112                    ngx.say("read: ", line)
1113
1114                else
1115                    ngx.say("failed to read a line: ", err, " [", part, "]")
1116                end
1117            end
1118
1119            ok, err = sock:close()
1120            ngx.say("close: ", ok, " ", err)
1121        ';
1122    }
1123
1124    location /foo {
1125        echo "hello, world ----abc";
1126        more_clear_headers Date;
1127    }
1128--- request
1129GET /t
1130--- response_body eval
1131qq{connected: 1
1132request sent: 57
1133read: hell
1134read: o, w
1135read: orld
1136read:  --
1137read: 
1138failed to read a line: nil [nil]
1139failed to read a line: closed [
1140]
1141close: nil closed
1142}
1143--- no_error_log
1144[error]
1145
1146
1147
1148=== TEST 17: ambiguous boundary patterns (--abc), small buffer, mixed by other reading calls
1149--- config
1150    server_tokens off;
1151    location /t {
1152        set $port $TEST_NGINX_CLIENT_PORT;
1153        lua_socket_buffer_size 1;
1154
1155        content_by_lua '
1156            -- collectgarbage("collect")
1157
1158            local sock = ngx.socket.tcp()
1159            local port = ngx.var.port
1160
1161            local ok, err = sock:connect("127.0.0.1", port)
1162            if not ok then
1163                ngx.say("failed to connect: ", err)
1164                return
1165            end
1166
1167            ngx.say("connected: ", ok)
1168
1169            local req = "GET /foo HTTP/1.0\\r\\nHost: localhost\\r\\nConnection: close\\r\\n\\r\\n"
1170
1171            local bytes, err = sock:send(req)
1172            if not bytes then
1173                ngx.say("failed to send request: ", err)
1174                return
1175            end
1176            ngx.say("request sent: ", bytes)
1177
1178            local read_headers = sock:receiveuntil("\\r\\n\\r\\n")
1179            local headers, err, part = read_headers()
1180            if not headers then
1181                ngx.say("failed to read headers: ", err, " [", part, "]")
1182            end
1183
1184            local reader = sock:receiveuntil("--abc")
1185
1186            for i = 1, 7 do
1187                line, err, part = reader(4)
1188                if line then
1189                    ngx.say("read: ", line)
1190
1191                else
1192                    ngx.say("failed to read a chunk: ", err, " [", part, "]")
1193                end
1194
1195                local data, err, part = sock:receive(1)
1196                if not data then
1197                    ngx.say("failed to read a byte: ", err, " [", part, "]")
1198                    break
1199                else
1200                    ngx.say("read one byte: ", data)
1201                end
1202            end
1203
1204            ok, err = sock:close()
1205            ngx.say("close: ", ok, " ", err)
1206        ';
1207    }
1208
1209    location /foo {
1210        echo "hello, world ----abc";
1211        more_clear_headers Date;
1212    }
1213--- request
1214GET /t
1215--- response_body eval
1216qq{connected: 1
1217request sent: 57
1218read: hell
1219read one byte: o
1220read: , wo
1221read one byte: r
1222read: ld -
1223read one byte: -
1224read: 
1225read one byte: 
1226
1227failed to read a chunk: nil [nil]
1228failed to read a byte: closed []
1229close: nil closed
1230}
1231--- no_error_log
1232[error]
1233
1234
1235
1236=== TEST 18: ambiguous boundary patterns (abcabd), small buffer
1237--- config
1238    server_tokens off;
1239    lua_socket_buffer_size 3;
1240    location /t {
1241        set $port $TEST_NGINX_CLIENT_PORT;
1242
1243        content_by_lua '
1244            -- collectgarbage("collect")
1245
1246            local sock = ngx.socket.tcp()
1247            local port = ngx.var.port
1248
1249            local ok, err = sock:connect("127.0.0.1", port)
1250            if not ok then
1251                ngx.say("failed to connect: ", err)
1252                return
1253            end
1254
1255            ngx.say("connected: ", ok)
1256
1257            local req = "GET /foo HTTP/1.0\\r\\nHost: localhost\\r\\nConnection: close\\r\\n\\r\\n"
1258
1259            local bytes, err = sock:send(req)
1260            if not bytes then
1261                ngx.say("failed to send request: ", err)
1262                return
1263            end
1264            ngx.say("request sent: ", bytes)
1265
1266            local read_headers = sock:receiveuntil("\\r\\n\\r\\n")
1267            local headers, err, part = read_headers()
1268            if not headers then
1269                ngx.say("failed to read headers: ", err, " [", part, "]")
1270            end
1271
1272            local reader = sock:receiveuntil("abcabd")
1273
1274            for i = 1, 2 do
1275                line, err, part = reader()
1276                if line then
1277                    ngx.say("read: ", line)
1278
1279                else
1280                    ngx.say("failed to read a line: ", err, " [", part, "]")
1281                end
1282            end
1283
1284            ok, err = sock:close()
1285            ngx.say("close: ", ok, " ", err)
1286        ';
1287    }
1288
1289    location /foo {
1290        echo abcabcabd;
1291        more_clear_headers Date;
1292    }
1293--- request
1294GET /t
1295--- response_body eval
1296qq{connected: 1
1297request sent: 57
1298read: abc
1299failed to read a line: closed [
1300]
1301close: nil closed
1302}
1303--- no_error_log
1304[error]
1305
1306
1307
1308=== TEST 19: long patterns
1309this exposed a memory leak in receiveuntil
1310--- config
1311    location /t {
1312        content_by_lua '
1313            local sock, err = ngx.req.socket()
1314            if not sock then
1315                ngx.say("failed to get req socket: ", err)
1316                return
1317            end
1318            local reader, err = sock:receiveuntil("------------------------------------------- abcdefghijklmnopqrstuvwxyz")
1319            if not reader then
1320                ngx.say("failed to get reader: ", err)
1321                return
1322            end
1323            ngx.say("ok")
1324        ';
1325    }
1326--- request
1327    GET /t
1328--- response_body
1329ok
1330--- no_error_log
1331[error]
1332