1# -*- coding: utf-8 -*- 2import pytest 3 4from unit.applications.lang.python import ApplicationPython 5from unit.option import option 6 7prerequisites = {'modules': {'python': 'any'}} 8 9client = ApplicationPython() 10 11 12@pytest.fixture(autouse=True) 13def setup_method_fixture(): 14 assert 'success' in client.conf( 15 { 16 "listeners": {"*:8080": {"pass": "routes"}}, 17 "routes": [ 18 { 19 "match": {"method": "GET"}, 20 "action": {"return": 200}, 21 } 22 ], 23 "applications": {}, 24 } 25 ), 'routing configure' 26 27 28def route(conf_route): 29 return client.conf([conf_route], 'routes') 30 31 32def route_match(match): 33 assert 'success' in route( 34 {"match": match, "action": {"return": 200}} 35 ), 'route match configure' 36 37 38def route_match_invalid(match): 39 assert 'error' in route( 40 {"match": match, "action": {"return": 200}} 41 ), 'route match configure invalid' 42 43 44def host(host_header, status): 45 assert ( 46 client.get(headers={'Host': host_header, 'Connection': 'close'})[ 47 'status' 48 ] 49 == status 50 ), 'match host' 51 52 53def cookie(cookie_header, status): 54 assert ( 55 client.get( 56 headers={ 57 'Host': 'localhost', 58 'Cookie': cookie_header, 59 'Connection': 'close', 60 }, 61 )['status'] 62 == status 63 ), 'match cookie' 64 65 66def test_routes_match_method_positive(): 67 assert client.get()['status'] == 200, 'GET' 68 assert client.post()['status'] == 404, 'POST' 69 70 71def test_routes_match_method_positive_many(): 72 route_match({"method": ["GET", "POST"]}) 73 74 assert client.get()['status'] == 200, 'GET' 75 assert client.post()['status'] == 200, 'POST' 76 assert client.delete()['status'] == 404, 'DELETE' 77 78 79def test_routes_match_method_negative(): 80 route_match({"method": "!GET"}) 81 82 assert client.get()['status'] == 404, 'GET' 83 assert client.post()['status'] == 200, 'POST' 84 85 86def test_routes_match_method_negative_many(): 87 route_match({"method": ["!GET", "!POST"]}) 88 89 assert client.get()['status'] == 404, 'GET' 90 assert client.post()['status'] == 404, 'POST' 91 assert client.delete()['status'] == 200, 'DELETE' 92 93 94def test_routes_match_method_wildcard_left(): 95 route_match({"method": "*ET"}) 96 97 assert client.get()['status'] == 200, 'GET' 98 assert client.post()['status'] == 404, 'POST' 99 100 101def test_routes_match_method_wildcard_right(): 102 route_match({"method": "GE*"}) 103 104 assert client.get()['status'] == 200, 'GET' 105 assert client.post()['status'] == 404, 'POST' 106 107 108def test_routes_match_method_wildcard_left_right(): 109 route_match({"method": "*GET*"}) 110 111 assert client.get()['status'] == 200, 'GET' 112 assert client.post()['status'] == 404, 'POST' 113 114 115def test_routes_match_method_wildcard(): 116 route_match({"method": "*"}) 117 118 assert client.get()['status'] == 200, 'GET' 119 120 121def test_routes_match_invalid(): 122 route_match_invalid({"method": "**"}) 123 124 125def test_routes_match_valid(): 126 route_match({"method": "blah*"}) 127 route_match({"host": "*blah*blah"}) 128 route_match({"host": "blah*blah*blah"}) 129 route_match({"host": "blah*blah*"}) 130 131 132def test_routes_match_empty_exact(): 133 route_match({"uri": ""}) 134 assert client.get()['status'] == 404 135 136 route_match({"uri": "/"}) 137 assert client.get()['status'] == 200 138 assert client.get(url='/blah')['status'] == 404 139 140 141def test_routes_match_negative(): 142 route_match({"uri": "!"}) 143 assert client.get()['status'] == 200 144 145 route_match({"uri": "!*"}) 146 assert client.get()['status'] == 404 147 148 route_match({"uri": "!/"}) 149 assert client.get()['status'] == 404 150 assert client.get(url='/blah')['status'] == 200 151 152 route_match({"uri": "!*blah"}) 153 assert client.get()['status'] == 200 154 assert client.get(url='/bla')['status'] == 200 155 assert client.get(url='/blah')['status'] == 404 156 assert client.get(url='/blah1')['status'] == 200 157 158 route_match({"uri": "!/blah*1*"}) 159 assert client.get()['status'] == 200 160 assert client.get(url='/blah')['status'] == 200 161 assert client.get(url='/blah1')['status'] == 404 162 assert client.get(url='/blah12')['status'] == 404 163 assert client.get(url='/blah2')['status'] == 200 164 165 166def test_routes_match_wildcard_middle(): 167 route_match({"host": "ex*le"}) 168 169 host('example', 200) 170 host('www.example', 404) 171 host('example.com', 404) 172 host('exampl', 404) 173 174 175def test_routes_match_method_case_insensitive(): 176 route_match({"method": "get"}) 177 178 assert client.get()['status'] == 200, 'GET' 179 180 181def test_routes_match_wildcard_left_case_insensitive(): 182 route_match({"method": "*get"}) 183 assert client.get()['status'] == 200, 'GET' 184 185 route_match({"method": "*et"}) 186 assert client.get()['status'] == 200, 'GET' 187 188 189def test_routes_match_wildcard_middle_case_insensitive(): 190 route_match({"method": "g*t"}) 191 192 assert client.get()['status'] == 200, 'GET' 193 194 195def test_routes_match_wildcard_right_case_insensitive(): 196 route_match({"method": "get*"}) 197 assert client.get()['status'] == 200, 'GET' 198 199 route_match({"method": "ge*"}) 200 assert client.get()['status'] == 200, 'GET' 201 202 203def test_routes_match_wildcard_substring_case_insensitive(): 204 route_match({"method": "*et*"}) 205 206 assert client.get()['status'] == 200, 'GET' 207 208 209def test_routes_match_wildcard_left_case_sensitive(): 210 route_match({"uri": "*blah"}) 211 212 assert client.get(url='/blah')['status'] == 200, '/blah' 213 assert client.get(url='/BLAH')['status'] == 404, '/BLAH' 214 215 216def test_routes_match_wildcard_middle_case_sensitive(): 217 route_match({"uri": "/b*h"}) 218 219 assert client.get(url='/blah')['status'] == 200, '/blah' 220 assert client.get(url='/BLAH')['status'] == 404, '/BLAH' 221 222 223def test_route_match_wildcards_ordered(): 224 route_match({"uri": "/a*x*y*"}) 225 226 assert client.get(url='/axy')['status'] == 200, '/axy' 227 assert client.get(url='/ayx')['status'] == 404, '/ayx' 228 229 230def test_route_match_wildcards_adjust_start(): 231 route_match({"uri": "/bla*bla*"}) 232 233 assert client.get(url='/bla_foo')['status'] == 404, '/bla_foo' 234 235 236def test_route_match_wildcards_adjust_start_substr(): 237 route_match({"uri": "*bla*bla*"}) 238 239 assert client.get(url='/bla_foo')['status'] == 404, '/bla_foo' 240 241 242def test_route_match_wildcards_adjust_end(): 243 route_match({"uri": "/bla*bla"}) 244 245 assert client.get(url='/foo_bla')['status'] == 404, '/foo_bla' 246 247 248def test_routes_match_wildcard_right_case_sensitive(): 249 route_match({"uri": "/bla*"}) 250 251 assert client.get(url='/blah')['status'] == 200, '/blah' 252 assert client.get(url='/BLAH')['status'] == 404, '/BLAH' 253 254 255def test_routes_match_wildcard_substring_case_sensitive(): 256 route_match({"uri": "*bla*"}) 257 258 assert client.get(url='/blah')['status'] == 200, '/blah' 259 assert client.get(url='/BLAH')['status'] == 404, '/BLAH' 260 261 262def test_routes_match_many_wildcard_substrings_case_sensitive(): 263 route_match({"uri": "*a*B*c*"}) 264 265 assert client.get(url='/blah-a-B-c-blah')['status'] == 200 266 assert client.get(url='/a-B-c')['status'] == 200 267 assert client.get(url='/aBc')['status'] == 200 268 assert client.get(url='/aBCaBbc')['status'] == 200 269 assert client.get(url='/ABc')['status'] == 404 270 271 272def test_routes_empty_regex(require): 273 require({'modules': {'regex': True}}) 274 275 route_match({"uri": "~"}) 276 assert client.get(url='/')['status'] == 200, 'empty regexp' 277 assert client.get(url='/anything')['status'] == 200, '/anything' 278 279 route_match({"uri": "!~"}) 280 assert client.get(url='/')['status'] == 404, 'empty regexp 2' 281 assert client.get(url='/nothing')['status'] == 404, '/nothing' 282 283 284def test_routes_bad_regex(require): 285 require({'modules': {'regex': True}}) 286 287 assert 'error' in route( 288 {"match": {"uri": "~/bl[ah"}, "action": {"return": 200}} 289 ), 'bad regex' 290 291 status = route({"match": {"uri": "~(?R)?z"}, "action": {"return": 200}}) 292 if 'error' not in status: 293 assert client.get(url='/nothing_z')['status'] == 500, '/nothing_z' 294 295 status = route({"match": {"uri": "~((?1)?z)"}, "action": {"return": 200}}) 296 if 'error' not in status: 297 assert client.get(url='/nothing_z')['status'] == 500, '/nothing_z' 298 299 300def test_routes_match_regex_case_sensitive(require): 301 require({'modules': {'regex': True}}) 302 303 route_match({"uri": "~/bl[ah]"}) 304 305 assert client.get(url='/rlah')['status'] == 404, '/rlah' 306 assert client.get(url='/blah')['status'] == 200, '/blah' 307 assert client.get(url='/blh')['status'] == 200, '/blh' 308 assert client.get(url='/BLAH')['status'] == 404, '/BLAH' 309 310 311def test_routes_match_regex_negative_case_sensitive(require): 312 require({'modules': {'regex': True}}) 313 314 route_match({"uri": "!~/bl[ah]"}) 315 316 assert client.get(url='/rlah')['status'] == 200, '/rlah' 317 assert client.get(url='/blah')['status'] == 404, '/blah' 318 assert client.get(url='/blh')['status'] == 404, '/blh' 319 assert client.get(url='/BLAH')['status'] == 200, '/BLAH' 320 321 322def test_routes_pass_encode(): 323 python_dir = f'{option.test_dir}/python' 324 325 def check_pass(path, name): 326 assert 'success' in client.conf( 327 { 328 "listeners": {"*:8080": {"pass": f'applications/{path}'}}, 329 "applications": { 330 name: { 331 "type": client.get_application_type(), 332 "processes": {"spare": 0}, 333 "path": f'{python_dir}/empty', 334 "working_directory": f'{python_dir}/empty', 335 "module": "wsgi", 336 } 337 }, 338 } 339 ) 340 341 assert client.get()['status'] == 200 342 343 check_pass("%25", "%") 344 check_pass("blah%2Fblah", "blah/blah") 345 check_pass("%2Fblah%2F%2Fblah%2F", "/blah//blah/") 346 check_pass("%20blah%252Fblah%7E", " blah%2Fblah~") 347 348 def check_pass_error(path, name): 349 assert 'error' in client.conf( 350 { 351 "listeners": {"*:8080": {"pass": f'applications/{path}'}}, 352 "applications": { 353 name: { 354 "type": client.get_application_type(), 355 "processes": {"spare": 0}, 356 "path": f'{python_dir}/empty', 357 "working_directory": f'{python_dir}/empty', 358 "module": "wsgi", 359 } 360 }, 361 } 362 ) 363 364 check_pass_error("%", "%") 365 check_pass_error("%1", "%1") 366 367 368def test_routes_absent(): 369 assert 'success' in client.conf( 370 { 371 "listeners": {"*:8081": {"pass": "applications/empty"}}, 372 "applications": { 373 "empty": { 374 "type": client.get_application_type(), 375 "processes": {"spare": 0}, 376 "path": f'{option.test_dir}/python/empty', 377 "working_directory": f'{option.test_dir}/python/empty', 378 "module": "wsgi", 379 } 380 }, 381 } 382 ) 383 384 assert client.get(port=8081)['status'] == 200, 'routes absent' 385 386 387def test_routes_pass_invalid(): 388 assert 'error' in client.conf( 389 {"pass": "routes/blah"}, 'listeners/*:8080' 390 ), 'routes invalid' 391 392 393def test_route_empty(): 394 assert 'success' in client.conf( 395 { 396 "listeners": {"*:8080": {"pass": "routes/main"}}, 397 "routes": {"main": []}, 398 "applications": {}, 399 } 400 ), 'route empty configure' 401 402 assert client.get()['status'] == 404, 'route empty' 403 404 405def test_routes_route_empty(): 406 assert 'success' in client.conf( 407 {}, 'listeners' 408 ), 'routes empty listeners configure' 409 410 assert 'success' in client.conf({}, 'routes'), 'routes empty configure' 411 412 413def test_routes_route_match_absent(): 414 assert 'success' in client.conf( 415 [{"action": {"return": 200}}], 'routes' 416 ), 'route match absent configure' 417 418 assert client.get()['status'] == 200, 'route match absent' 419 420 421def test_routes_route_action_absent(skip_alert): 422 skip_alert(r'failed to apply new conf') 423 424 assert 'error' in client.conf( 425 [{"match": {"method": "GET"}}], 'routes' 426 ), 'route pass absent configure' 427 428 429def test_routes_route_pass(): 430 assert 'success' in client.conf( 431 { 432 "applications": { 433 "app": { 434 "type": client.get_application_type(), 435 "processes": {"spare": 0}, 436 "path": "/app", 437 "module": "wsgi", 438 } 439 }, 440 "upstreams": { 441 "one": { 442 "servers": { 443 "127.0.0.1:8081": {}, 444 "127.0.0.1:8082": {}, 445 }, 446 }, 447 "two": { 448 "servers": { 449 "127.0.0.1:8081": {}, 450 "127.0.0.1:8082": {}, 451 }, 452 }, 453 }, 454 } 455 ) 456 457 assert 'success' in client.conf([{"action": {"pass": "routes"}}], 'routes') 458 assert 'success' in client.conf( 459 [{"action": {"pass": "applications/app"}}], 'routes' 460 ) 461 assert 'success' in client.conf( 462 [{"action": {"pass": "upstreams/one"}}], 'routes' 463 ) 464 465 466def test_routes_route_pass_absent(): 467 assert 'error' in client.conf( 468 [{"match": {"method": "GET"}, "action": {}}], 'routes' 469 ), 'route pass absent configure' 470 471 472def test_routes_route_pass_invalid(): 473 assert 'success' in client.conf( 474 { 475 "applications": { 476 "app": { 477 "type": client.get_application_type(), 478 "processes": {"spare": 0}, 479 "path": "/app", 480 "module": "wsgi", 481 } 482 }, 483 "upstreams": { 484 "one": { 485 "servers": { 486 "127.0.0.1:8081": {}, 487 "127.0.0.1:8082": {}, 488 }, 489 }, 490 "two": { 491 "servers": { 492 "127.0.0.1:8081": {}, 493 "127.0.0.1:8082": {}, 494 }, 495 }, 496 }, 497 } 498 ) 499 500 assert 'error' in client.conf( 501 [{"action": {"pass": "blah"}}], 'routes' 502 ), 'route pass invalid' 503 assert 'error' in client.conf( 504 [{"action": {"pass": "routes/blah"}}], 'routes' 505 ), 'route pass routes invalid' 506 assert 'error' in client.conf( 507 [{"action": {"pass": "applications/blah"}}], 'routes' 508 ), 'route pass applications invalid' 509 assert 'error' in client.conf( 510 [{"action": {"pass": "upstreams/blah"}}], 'routes' 511 ), 'route pass upstreams invalid' 512 513 514def test_routes_action_unique(temp_dir): 515 assert 'success' in client.conf( 516 { 517 "listeners": { 518 "*:8080": {"pass": "routes"}, 519 "*:8081": {"pass": "applications/app"}, 520 }, 521 "routes": [{"action": {"proxy": "http://127.0.0.1:8081"}}], 522 "applications": { 523 "app": { 524 "type": client.get_application_type(), 525 "processes": {"spare": 0}, 526 "path": "/app", 527 "module": "wsgi", 528 } 529 }, 530 } 531 ) 532 533 assert 'error' in client.conf( 534 {"proxy": "http://127.0.0.1:8081", "share": temp_dir}, 535 'routes/0/action', 536 ), 'proxy share' 537 assert 'error' in client.conf( 538 { 539 "proxy": "http://127.0.0.1:8081", 540 "pass": "applications/app", 541 }, 542 'routes/0/action', 543 ), 'proxy pass' 544 assert 'error' in client.conf( 545 {"share": temp_dir, "pass": "applications/app"}, 546 'routes/0/action', 547 ), 'share pass' 548 549 550def test_routes_rules_two(): 551 assert 'success' in client.conf( 552 [ 553 {"match": {"method": "GET"}, "action": {"return": 200}}, 554 {"match": {"method": "POST"}, "action": {"return": 201}}, 555 ], 556 'routes', 557 ), 'rules two configure' 558 559 assert client.get()['status'] == 200, 'rules two match first' 560 assert client.post()['status'] == 201, 'rules two match second' 561 562 563def test_routes_two(): 564 assert 'success' in client.conf( 565 { 566 "listeners": {"*:8080": {"pass": "routes/first"}}, 567 "routes": { 568 "first": [ 569 { 570 "match": {"method": "GET"}, 571 "action": {"pass": "routes/second"}, 572 } 573 ], 574 "second": [ 575 { 576 "match": {"host": "localhost"}, 577 "action": {"return": 200}, 578 } 579 ], 580 }, 581 "applications": {}, 582 } 583 ), 'routes two configure' 584 585 assert client.get()['status'] == 200, 'routes two' 586 587 588def test_routes_match_host_positive(): 589 route_match({"host": "localhost"}) 590 591 assert client.get()['status'] == 200, 'localhost' 592 host('localhost.', 200) 593 host('localhost.', 200) 594 host('.localhost', 404) 595 host('www.localhost', 404) 596 host('localhost1', 404) 597 598 599@pytest.mark.skip('not yet') 600def test_routes_match_host_absent(): 601 route_match({"host": "localhost"}) 602 603 assert ( 604 client.get(headers={'Connection': 'close'})['status'] == 400 605 ), 'match host absent' 606 607 608def test_routes_match_host_ipv4(): 609 route_match({"host": "127.0.0.1"}) 610 611 host('127.0.0.1', 200) 612 host('127.0.0.1:8080', 200) 613 614 615def test_routes_match_host_ipv6(): 616 route_match({"host": "[::1]"}) 617 618 host('[::1]', 200) 619 host('[::1]:8080', 200) 620 621 622def test_routes_match_host_positive_many(): 623 route_match({"host": ["localhost", "example.com"]}) 624 625 assert client.get()['status'] == 200, 'localhost' 626 host('example.com', 200) 627 628 629def test_routes_match_host_positive_and_negative(): 630 route_match({"host": ["*example.com", "!www.example.com"]}) 631 632 assert client.get()['status'] == 404, 'localhost' 633 host('example.com', 200) 634 host('www.example.com', 404) 635 host('!www.example.com', 200) 636 637 638def test_routes_match_host_positive_and_negative_wildcard(): 639 route_match({"host": ["*example*", "!www.example*"]}) 640 641 host('example.com', 200) 642 host('www.example.com', 404) 643 644 645def test_routes_match_host_case_insensitive(): 646 route_match({"host": "Example.com"}) 647 648 host('example.com', 200) 649 host('EXAMPLE.COM', 200) 650 651 652def test_routes_match_host_port(): 653 route_match({"host": "example.com"}) 654 655 host('example.com:8080', 200) 656 657 658def test_routes_match_host_empty(): 659 route_match({"host": ""}) 660 661 host('', 200) 662 assert ( 663 client.get(http_10=True, headers={})['status'] == 200 664 ), 'match host empty 2' 665 assert client.get()['status'] == 404, 'match host empty 3' 666 667 668def test_routes_match_uri_positive(): 669 route_match({"uri": ["/blah", "/slash/"]}) 670 671 assert client.get()['status'] == 404, '/' 672 assert client.get(url='/blah')['status'] == 200, '/blah' 673 assert client.get(url='/blah#foo')['status'] == 200, '/blah#foo' 674 assert client.get(url='/blah?var')['status'] == 200, '/blah?var' 675 assert client.get(url='//blah')['status'] == 200, '//blah' 676 assert client.get(url='/slash/foo/../')['status'] == 200, 'relative' 677 assert client.get(url='/slash/./')['status'] == 200, '/slash/./' 678 assert client.get(url='/slash//.//')['status'] == 200, 'adjacent slashes' 679 assert client.get(url='/%')['status'] == 400, 'percent' 680 assert client.get(url='/%1')['status'] == 400, 'percent digit' 681 assert client.get(url='/%A')['status'] == 400, 'percent letter' 682 assert client.get(url='/slash/.?args')['status'] == 200, 'dot args' 683 assert client.get(url='/slash/.#frag')['status'] == 200, 'dot frag' 684 assert client.get(url='/slash/foo/..?args')['status'] == 200, 'dot dot args' 685 assert client.get(url='/slash/foo/..#frag')['status'] == 200, 'dot dot frag' 686 assert client.get(url='/slash/.')['status'] == 200, 'trailing dot' 687 assert client.get(url='/slash/foo/..')['status'] == 200, 'trailing dot dot' 688 689 690def test_routes_match_uri_case_sensitive(): 691 route_match({"uri": "/BLAH"}) 692 693 assert client.get(url='/blah')['status'] == 404, '/blah' 694 assert client.get(url='/BlaH')['status'] == 404, '/BlaH' 695 assert client.get(url='/BLAH')['status'] == 200, '/BLAH' 696 697 698def test_routes_match_uri_normalize(): 699 route_match({"uri": "/blah"}) 700 701 assert client.get(url='/%62%6c%61%68')['status'] == 200, 'normalize' 702 703 704def test_routes_match_empty_array(): 705 route_match({"uri": []}) 706 707 assert client.get(url='/blah')['status'] == 200, 'empty array' 708 709 710def test_routes_reconfigure(): 711 assert 'success' in client.conf([], 'routes'), 'redefine' 712 assert client.get()['status'] == 404, 'redefine request' 713 714 assert 'success' in client.conf( 715 [{"action": {"return": 200}}], 'routes' 716 ), 'redefine 2' 717 assert client.get()['status'] == 200, 'redefine request 2' 718 719 assert 'success' in client.conf([], 'routes'), 'redefine 3' 720 assert client.get()['status'] == 404, 'redefine request 3' 721 722 assert 'success' in client.conf( 723 { 724 "listeners": {"*:8080": {"pass": "routes/main"}}, 725 "routes": {"main": [{"action": {"return": 200}}]}, 726 "applications": {}, 727 } 728 ), 'redefine 4' 729 assert client.get()['status'] == 200, 'redefine request 4' 730 731 assert 'success' in client.conf_delete('routes/main/0'), 'redefine 5' 732 assert client.get()['status'] == 404, 'redefine request 5' 733 734 assert 'success' in client.conf_post( 735 {"action": {"return": 200}}, 'routes/main' 736 ), 'redefine 6' 737 assert client.get()['status'] == 200, 'redefine request 6' 738 739 assert 'error' in client.conf( 740 {"action": {"return": 200}}, 'routes/main/2' 741 ), 'redefine 7' 742 assert 'success' in client.conf( 743 {"action": {"return": 201}}, 'routes/main/1' 744 ), 'redefine 8' 745 746 assert len(client.conf_get('routes/main')) == 2, 'redefine conf 8' 747 assert client.get()['status'] == 200, 'redefine request 8' 748 749 750def test_routes_edit(): 751 route_match({"method": "GET"}) 752 753 assert client.get()['status'] == 200, 'routes edit GET' 754 assert client.post()['status'] == 404, 'routes edit POST' 755 756 assert 'success' in client.conf_post( 757 {"match": {"method": "POST"}, "action": {"return": 200}}, 758 'routes', 759 ), 'routes edit configure 2' 760 assert 'GET' == client.conf_get( 761 'routes/0/match/method' 762 ), 'routes edit configure 2 check' 763 assert 'POST' == client.conf_get( 764 'routes/1/match/method' 765 ), 'routes edit configure 2 check 2' 766 767 assert client.get()['status'] == 200, 'routes edit GET 2' 768 assert client.post()['status'] == 200, 'routes edit POST 2' 769 770 assert 'success' in client.conf_delete( 771 'routes/0' 772 ), 'routes edit configure 3' 773 774 assert client.get()['status'] == 404, 'routes edit GET 3' 775 assert client.post()['status'] == 200, 'routes edit POST 3' 776 777 assert 'error' in client.conf_delete( 778 'routes/1' 779 ), 'routes edit configure invalid' 780 assert 'error' in client.conf_delete( 781 'routes/-1' 782 ), 'routes edit configure invalid 2' 783 assert 'error' in client.conf_delete( 784 'routes/blah' 785 ), 'routes edit configure invalid 3' 786 787 assert client.get()['status'] == 404, 'routes edit GET 4' 788 assert client.post()['status'] == 200, 'routes edit POST 4' 789 790 assert 'success' in client.conf_delete( 791 'routes/0' 792 ), 'routes edit configure 5' 793 794 assert client.get()['status'] == 404, 'routes edit GET 5' 795 assert client.post()['status'] == 404, 'routes edit POST 5' 796 797 assert 'success' in client.conf_post( 798 {"match": {"method": "POST"}, "action": {"return": 200}}, 799 'routes', 800 ), 'routes edit configure 6' 801 802 assert client.get()['status'] == 404, 'routes edit GET 6' 803 assert client.post()['status'] == 200, 'routes edit POST 6' 804 805 assert 'success' in client.conf( 806 { 807 "listeners": {"*:8080": {"pass": "routes/main"}}, 808 "routes": {"main": [{"action": {"return": 200}}]}, 809 "applications": {}, 810 } 811 ), 'route edit configure 7' 812 813 assert 'error' in client.conf_delete( 814 'routes/0' 815 ), 'routes edit configure invalid 4' 816 assert 'error' in client.conf_delete( 817 'routes/main' 818 ), 'routes edit configure invalid 5' 819 820 assert client.get()['status'] == 200, 'routes edit GET 7' 821 822 assert 'success' in client.conf_delete( 823 'listeners/*:8080' 824 ), 'route edit configure 8' 825 assert 'success' in client.conf_delete( 826 'routes/main' 827 ), 'route edit configure 9' 828 829 830def test_match_edit(skip_alert): 831 skip_alert(r'failed to apply new conf') 832 833 route_match({"method": ["GET", "POST"]}) 834 835 assert client.get()['status'] == 200, 'match edit GET' 836 assert client.post()['status'] == 200, 'match edit POST' 837 assert client.put()['status'] == 404, 'match edit PUT' 838 839 assert 'success' in client.conf_post( 840 '\"PUT\"', 'routes/0/match/method' 841 ), 'match edit configure 2' 842 assert ['GET', 'POST', 'PUT'] == client.conf_get( 843 'routes/0/match/method' 844 ), 'match edit configure 2 check' 845 846 assert client.get()['status'] == 200, 'match edit GET 2' 847 assert client.post()['status'] == 200, 'match edit POST 2' 848 assert client.put()['status'] == 200, 'match edit PUT 2' 849 850 assert 'success' in client.conf_delete( 851 'routes/0/match/method/1' 852 ), 'match edit configure 3' 853 assert ['GET', 'PUT'] == client.conf_get( 854 'routes/0/match/method' 855 ), 'match edit configure 3 check' 856 857 assert client.get()['status'] == 200, 'match edit GET 3' 858 assert client.post()['status'] == 404, 'match edit POST 3' 859 assert client.put()['status'] == 200, 'match edit PUT 3' 860 861 assert 'success' in client.conf_delete( 862 'routes/0/match/method/1' 863 ), 'match edit configure 4' 864 assert ['GET'] == client.conf_get( 865 'routes/0/match/method' 866 ), 'match edit configure 4 check' 867 868 assert client.get()['status'] == 200, 'match edit GET 4' 869 assert client.post()['status'] == 404, 'match edit POST 4' 870 assert client.put()['status'] == 404, 'match edit PUT 4' 871 872 assert 'error' in client.conf_delete( 873 'routes/0/match/method/1' 874 ), 'match edit configure invalid' 875 assert 'error' in client.conf_delete( 876 'routes/0/match/method/-1' 877 ), 'match edit configure invalid 2' 878 assert 'error' in client.conf_delete( 879 'routes/0/match/method/blah' 880 ), 'match edit configure invalid 3' 881 assert ['GET'] == client.conf_get( 882 'routes/0/match/method' 883 ), 'match edit configure 5 check' 884 885 assert client.get()['status'] == 200, 'match edit GET 5' 886 assert client.post()['status'] == 404, 'match edit POST 5' 887 assert client.put()['status'] == 404, 'match edit PUT 5' 888 889 assert 'success' in client.conf_delete( 890 'routes/0/match/method/0' 891 ), 'match edit configure 6' 892 assert [] == client.conf_get( 893 'routes/0/match/method' 894 ), 'match edit configure 6 check' 895 896 assert client.get()['status'] == 200, 'match edit GET 6' 897 assert client.post()['status'] == 200, 'match edit POST 6' 898 assert client.put()['status'] == 200, 'match edit PUT 6' 899 900 assert 'success' in client.conf( 901 '"GET"', 'routes/0/match/method' 902 ), 'match edit configure 7' 903 904 assert client.get()['status'] == 200, 'match edit GET 7' 905 assert client.post()['status'] == 404, 'match edit POST 7' 906 assert client.put()['status'] == 404, 'match edit PUT 7' 907 908 assert 'error' in client.conf_delete( 909 'routes/0/match/method/0' 910 ), 'match edit configure invalid 5' 911 assert 'error' in client.conf( 912 {}, 'routes/0/action' 913 ), 'match edit configure invalid 6' 914 915 assert 'success' in client.conf( 916 {}, 'routes/0/match' 917 ), 'match edit configure 8' 918 919 assert client.get()['status'] == 200, 'match edit GET 8' 920 921 922def test_routes_match_rules(): 923 route_match({"method": "GET", "host": "localhost", "uri": "/"}) 924 925 assert client.get()['status'] == 200, 'routes match rules' 926 927 928def test_routes_loop(): 929 assert 'success' in route( 930 {"match": {"uri": "/"}, "action": {"pass": "routes"}} 931 ), 'routes loop configure' 932 933 assert client.get()['status'] == 500, 'routes loop' 934 935 936def test_routes_match_headers(): 937 route_match({"headers": {"host": "localhost"}}) 938 939 assert client.get()['status'] == 200, 'match headers' 940 host('Localhost', 200) 941 host('localhost.com', 404) 942 host('llocalhost', 404) 943 host('host', 404) 944 945 946def test_routes_match_headers_multiple(): 947 route_match({"headers": {"host": "localhost", "x-blah": "test"}}) 948 949 assert client.get()['status'] == 404, 'match headers multiple' 950 assert ( 951 client.get( 952 headers={ 953 "Host": "localhost", 954 "X-blah": "test", 955 "Connection": "close", 956 } 957 )['status'] 958 == 200 959 ), 'match headers multiple 2' 960 961 assert ( 962 client.get( 963 headers={ 964 "Host": "localhost", 965 "X-blah": "", 966 "Connection": "close", 967 } 968 )['status'] 969 == 404 970 ), 'match headers multiple 3' 971 972 973def test_routes_match_headers_multiple_values(): 974 route_match({"headers": {"x-blah": "test"}}) 975 976 assert ( 977 client.get( 978 headers={ 979 "Host": "localhost", 980 "X-blah": ["test", "test", "test"], 981 "Connection": "close", 982 } 983 )['status'] 984 == 200 985 ), 'match headers multiple values' 986 assert ( 987 client.get( 988 headers={ 989 "Host": "localhost", 990 "X-blah": ["test", "blah", "test"], 991 "Connection": "close", 992 } 993 )['status'] 994 == 404 995 ), 'match headers multiple values 2' 996 assert ( 997 client.get( 998 headers={ 999 "Host": "localhost", 1000 "X-blah": ["test", "", "test"], 1001 "Connection": "close", 1002 } 1003 )['status'] 1004 == 404 1005 ), 'match headers multiple values 3' 1006 1007 1008def test_routes_match_headers_multiple_rules(): 1009 route_match({"headers": {"x-blah": ["test", "blah"]}}) 1010 1011 assert client.get()['status'] == 404, 'match headers multiple rules' 1012 assert ( 1013 client.get( 1014 headers={ 1015 "Host": "localhost", 1016 "X-blah": "test", 1017 "Connection": "close", 1018 } 1019 )['status'] 1020 == 200 1021 ), 'match headers multiple rules 2' 1022 assert ( 1023 client.get( 1024 headers={ 1025 "Host": "localhost", 1026 "X-blah": "blah", 1027 "Connection": "close", 1028 } 1029 )['status'] 1030 == 200 1031 ), 'match headers multiple rules 3' 1032 assert ( 1033 client.get( 1034 headers={ 1035 "Host": "localhost", 1036 "X-blah": ["test", "blah", "test"], 1037 "Connection": "close", 1038 } 1039 )['status'] 1040 == 200 1041 ), 'match headers multiple rules 4' 1042 1043 assert ( 1044 client.get( 1045 headers={ 1046 "Host": "localhost", 1047 "X-blah": ["blah", ""], 1048 "Connection": "close", 1049 } 1050 )['status'] 1051 == 404 1052 ), 'match headers multiple rules 5' 1053 1054 1055def test_routes_match_headers_case_insensitive(): 1056 route_match({"headers": {"X-BLAH": "TEST"}}) 1057 1058 assert ( 1059 client.get( 1060 headers={ 1061 "Host": "localhost", 1062 "x-blah": "test", 1063 "Connection": "close", 1064 } 1065 )['status'] 1066 == 200 1067 ), 'match headers case insensitive' 1068 1069 1070def test_routes_match_headers_invalid(): 1071 route_match_invalid({"headers": ["blah"]}) 1072 route_match_invalid({"headers": {"foo": ["bar", {}]}}) 1073 route_match_invalid({"headers": {"": "blah"}}) 1074 1075 1076def test_routes_match_headers_empty_rule(): 1077 route_match({"headers": {"host": ""}}) 1078 1079 assert client.get()['status'] == 404, 'localhost' 1080 host('', 200) 1081 1082 1083def test_routes_match_headers_empty(): 1084 route_match({"headers": {}}) 1085 assert client.get()['status'] == 200, 'empty' 1086 1087 route_match({"headers": []}) 1088 assert client.get()['status'] == 200, 'empty 2' 1089 1090 1091def test_routes_match_headers_rule_array_empty(): 1092 route_match({"headers": {"blah": []}}) 1093 1094 assert client.get()['status'] == 404, 'array empty' 1095 assert ( 1096 client.get( 1097 headers={ 1098 "Host": "localhost", 1099 "blah": "foo", 1100 "Connection": "close", 1101 } 1102 )['status'] 1103 == 200 1104 ), 'match headers rule array empty 2' 1105 1106 1107def test_routes_match_headers_array(): 1108 route_match( 1109 { 1110 "headers": [ 1111 {"x-header1": "foo*"}, 1112 {"x-header2": "bar"}, 1113 {"x-header3": ["foo", "bar"]}, 1114 {"x-header1": "bar", "x-header4": "foo"}, 1115 ] 1116 } 1117 ) 1118 1119 def check_headers(hds): 1120 hds = dict({"Host": "localhost", "Connection": "close"}, **hds) 1121 assert client.get(headers=hds)['status'] == 200, 'headers array match' 1122 1123 def check_headers_404(hds): 1124 hds = dict({"Host": "localhost", "Connection": "close"}, **hds) 1125 assert ( 1126 client.get(headers=hds)['status'] == 404 1127 ), 'headers array no match' 1128 1129 assert client.get()['status'] == 404, 'match headers array' 1130 check_headers({"x-header1": "foo123"}) 1131 check_headers({"x-header2": "bar"}) 1132 check_headers({"x-header3": "bar"}) 1133 check_headers_404({"x-header1": "bar"}) 1134 check_headers({"x-header1": "bar", "x-header4": "foo"}) 1135 1136 assert 'success' in client.conf_delete( 1137 'routes/0/match/headers/1' 1138 ), 'match headers array configure 2' 1139 1140 check_headers_404({"x-header2": "bar"}) 1141 check_headers({"x-header3": "foo"}) 1142 1143 1144def test_routes_match_arguments(): 1145 route_match({"arguments": {"foo": "bar"}}) 1146 1147 assert client.get()['status'] == 404, 'args' 1148 assert client.get(url='/?foo=bar')['status'] == 200, 'args 2' 1149 assert client.get(url='/?foo=bar1')['status'] == 404, 'args 3' 1150 assert client.get(url='/?1foo=bar')['status'] == 404, 'args 4' 1151 assert client.get(url='/?Foo=bar')['status'] == 404, 'case' 1152 assert client.get(url='/?foo=Bar')['status'] == 404, 'case 2' 1153 1154 1155def test_routes_match_arguments_chars(): 1156 chars = ( 1157 " !\"%23$%25%26'()*%2B,-./0123456789:;<%3D>?@" 1158 "ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~" 1159 ) 1160 1161 chars_enc = "" 1162 for h1 in ["2", "3", "4", "5", "6", "7"]: 1163 for h2 in [ 1164 "0", 1165 "1", 1166 "2", 1167 "3", 1168 "4", 1169 "5", 1170 "6", 1171 "7", 1172 "8", 1173 "9", 1174 "A", 1175 "B", 1176 "C", 1177 "D", 1178 "E", 1179 "F", 1180 ]: 1181 chars_enc += f'%{h1}{h2}' 1182 chars_enc = chars_enc[:-3] 1183 1184 def check_args(args, query): 1185 route_match({"arguments": args}) 1186 assert client.get(url=f'/?{query}')['status'] == 200 1187 1188 check_args({chars: chars}, f'{chars}={chars}') 1189 check_args({chars: chars}, f'{chars}={chars_enc}') 1190 check_args({chars: chars}, f'{chars_enc}={chars}') 1191 check_args({chars: chars}, f'{chars_enc}={chars_enc}') 1192 check_args({chars_enc: chars_enc}, f'{chars}={chars}') 1193 check_args({chars_enc: chars_enc}, f'{chars}={chars_enc}') 1194 check_args({chars_enc: chars_enc}, f'{chars_enc}={chars}') 1195 check_args({chars_enc: chars_enc}, f'{chars_enc}={chars_enc}') 1196 1197 1198def test_routes_match_arguments_empty(): 1199 route_match({"arguments": {}}) 1200 assert client.get()['status'] == 200, 'arguments empty' 1201 1202 route_match({"arguments": []}) 1203 assert client.get()['status'] == 200, 'arguments empty 2' 1204 1205 1206def test_routes_match_arguments_space(): 1207 route_match({"arguments": {"+fo o%20": "%20b+a r"}}) 1208 assert client.get(url='/? fo o = b a r&')['status'] == 200 1209 assert client.get(url='/?+fo+o+=+b+a+r&')['status'] == 200 1210 assert client.get(url='/?%20fo%20o%20=%20b%20a%20r&')['status'] == 200 1211 1212 route_match({"arguments": {"%20foo": " bar"}}) 1213 assert client.get(url='/? foo= bar')['status'] == 200 1214 assert client.get(url='/?+foo=+bar')['status'] == 200 1215 assert client.get(url='/?%20foo=%20bar')['status'] == 200 1216 assert client.get(url='/?+foo= bar')['status'] == 200 1217 assert client.get(url='/?%20foo=+bar')['status'] == 200 1218 1219 1220def test_routes_match_arguments_equal(): 1221 route_match({"arguments": {"=": "="}}) 1222 assert client.get(url='/?%3D=%3D')['status'] == 200 1223 assert client.get(url='/?%3D==')['status'] == 200 1224 assert client.get(url='/?===')['status'] == 404 1225 assert client.get(url='/?%3D%3D%3D')['status'] == 404 1226 assert client.get(url='/?==%3D')['status'] == 404 1227 1228 1229def test_routes_match_arguments_enc(): 1230 route_match({"arguments": {"Ю": "н"}}) 1231 assert client.get(url='/?%D0%AE=%D0%BD')['status'] == 200 1232 assert client.get(url='/?%d0%ae=%d0%Bd')['status'] == 200 1233 1234 1235def test_routes_match_arguments_hash(): 1236 route_match({"arguments": {"#": "#"}}) 1237 assert client.get(url='/?%23=%23')['status'] == 200 1238 assert client.get(url='/?%23=%23#')['status'] == 200 1239 assert client.get(url='/?#=#')['status'] == 404 1240 assert client.get(url='/?%23=#')['status'] == 404 1241 1242 1243def test_routes_match_arguments_wildcard(): 1244 route_match({"arguments": {"foo": "*"}}) 1245 assert client.get(url='/?foo')['status'] == 200 1246 assert client.get(url='/?foo=')['status'] == 200 1247 assert client.get(url='/?foo=blah')['status'] == 200 1248 assert client.get(url='/?blah=foo')['status'] == 404 1249 1250 route_match({"arguments": {"foo": "%25*"}}) 1251 assert client.get(url='/?foo=%xx')['status'] == 200 1252 1253 route_match({"arguments": {"foo": "%2A*"}}) 1254 assert client.get(url='/?foo=*xx')['status'] == 200 1255 assert client.get(url='/?foo=xx')['status'] == 404 1256 1257 route_match({"arguments": {"foo": "*%2A"}}) 1258 assert client.get(url='/?foo=xx*')['status'] == 200 1259 assert client.get(url='/?foo=xx*x')['status'] == 404 1260 1261 route_match({"arguments": {"foo": "1*2"}}) 1262 assert client.get(url='/?foo=12')['status'] == 200 1263 assert client.get(url='/?foo=1blah2')['status'] == 200 1264 assert client.get(url='/?foo=1%2A2')['status'] == 200 1265 assert client.get(url='/?foo=x12')['status'] == 404 1266 1267 route_match({"arguments": {"foo": "bar*", "%25": "%25"}}) 1268 assert client.get(url='/?foo=barxx&%=%')['status'] == 200 1269 assert client.get(url='/?foo=barxx&x%=%')['status'] == 404 1270 1271 1272def test_routes_match_arguments_negative(): 1273 route_match({"arguments": {"foo": "!"}}) 1274 assert client.get(url='/?bar')['status'] == 404 1275 assert client.get(url='/?foo')['status'] == 404 1276 assert client.get(url='/?foo=')['status'] == 404 1277 assert client.get(url='/?foo=%25')['status'] == 200 1278 1279 route_match({"arguments": {"foo": "!*"}}) 1280 assert client.get(url='/?bar')['status'] == 404 1281 assert client.get(url='/?foo')['status'] == 404 1282 assert client.get(url='/?foo=')['status'] == 404 1283 assert client.get(url='/?foo=blah')['status'] == 404 1284 1285 route_match({"arguments": {"foo": "!%25"}}) 1286 assert client.get(url='/?foo=blah')['status'] == 200 1287 assert client.get(url='/?foo=%')['status'] == 404 1288 1289 route_match({"arguments": {"foo": "%21blah"}}) 1290 assert client.get(url='/?foo=%21blah')['status'] == 200 1291 assert client.get(url='/?foo=!blah')['status'] == 200 1292 assert client.get(url='/?foo=bar')['status'] == 404 1293 1294 route_match({"arguments": {"foo": "!!%21*a"}}) 1295 assert client.get(url='/?foo=blah')['status'] == 200 1296 assert client.get(url='/?foo=!blah')['status'] == 200 1297 assert client.get(url='/?foo=!!a')['status'] == 404 1298 assert client.get(url='/?foo=!!bla')['status'] == 404 1299 1300 1301def test_routes_match_arguments_percent(): 1302 route_match({"arguments": {"%25": "%25"}}) 1303 assert client.get(url='/?%=%')['status'] == 200 1304 assert client.get(url='/?%25=%25')['status'] == 200 1305 assert client.get(url='/?%25=%')['status'] == 200 1306 1307 route_match({"arguments": {"%251": "%252"}}) 1308 assert client.get(url='/?%1=%2')['status'] == 200 1309 assert client.get(url='/?%251=%252')['status'] == 200 1310 assert client.get(url='/?%251=%2')['status'] == 200 1311 1312 route_match({"arguments": {"%25%21%251": "%25%24%252"}}) 1313 assert client.get(url='/?%!%1=%$%2')['status'] == 200 1314 assert client.get(url='/?%25!%251=%25$%252')['status'] == 200 1315 assert client.get(url='/?%25!%1=%$%2')['status'] == 200 1316 1317 1318def test_routes_match_arguments_ampersand(): 1319 route_match({"arguments": {"foo": "&"}}) 1320 assert client.get(url='/?foo=%26')['status'] == 200 1321 assert client.get(url='/?foo=%26&')['status'] == 200 1322 assert client.get(url='/?foo=%26%26')['status'] == 404 1323 assert client.get(url='/?foo=&')['status'] == 404 1324 1325 route_match({"arguments": {"&": ""}}) 1326 assert client.get(url='/?%26=')['status'] == 200 1327 assert client.get(url='/?%26=&')['status'] == 200 1328 assert client.get(url='/?%26=%26')['status'] == 404 1329 assert client.get(url='/?&=')['status'] == 404 1330 1331 1332def test_routes_match_arguments_complex(): 1333 route_match({"arguments": {"foo": ""}}) 1334 1335 assert client.get(url='/?foo')['status'] == 200, 'complex' 1336 assert client.get(url='/?blah=blah&foo=')['status'] == 200, 'complex 2' 1337 assert client.get(url='/?&&&foo&&&')['status'] == 200, 'complex 3' 1338 assert client.get(url='/?foo&foo=bar&foo')['status'] == 404, 'complex 4' 1339 assert client.get(url='/?foo=&foo')['status'] == 200, 'complex 5' 1340 assert client.get(url='/?&=&foo&==&')['status'] == 200, 'complex 6' 1341 assert client.get(url='/?&=&bar&==&')['status'] == 404, 'complex 7' 1342 1343 1344def test_routes_match_arguments_multiple(): 1345 route_match({"arguments": {"foo": "bar", "blah": "test"}}) 1346 1347 assert client.get()['status'] == 404, 'multiple' 1348 assert client.get(url='/?foo=bar&blah=test')['status'] == 200, 'multiple 2' 1349 assert client.get(url='/?foo=bar&blah')['status'] == 404, 'multiple 3' 1350 assert client.get(url='/?foo=bar&blah=tes')['status'] == 404, 'multiple 4' 1351 assert ( 1352 client.get(url='/?foo=b%61r&bl%61h=t%65st')['status'] == 200 1353 ), 'multiple 5' 1354 1355 1356def test_routes_match_arguments_multiple_rules(): 1357 route_match({"arguments": {"foo": ["bar", "blah"]}}) 1358 1359 assert client.get()['status'] == 404, 'rules' 1360 assert client.get(url='/?foo=bar')['status'] == 200, 'rules 2' 1361 assert client.get(url='/?foo=blah')['status'] == 200, 'rules 3' 1362 assert ( 1363 client.get(url='/?foo=blah&foo=bar&foo=blah')['status'] == 200 1364 ), 'rules 4' 1365 assert client.get(url='/?foo=blah&foo=bar&foo=')['status'] == 404, 'rules 5' 1366 1367 1368def test_routes_match_arguments_array(): 1369 route_match( 1370 { 1371 "arguments": [ 1372 {"var1": "val1*"}, 1373 {"var2": "val2"}, 1374 {"var3": ["foo", "bar"]}, 1375 {"var1": "bar", "var4": "foo"}, 1376 ] 1377 } 1378 ) 1379 1380 assert client.get()['status'] == 404, 'arr' 1381 assert client.get(url='/?var1=val123')['status'] == 200, 'arr 2' 1382 assert client.get(url='/?var2=val2')['status'] == 200, 'arr 3' 1383 assert client.get(url='/?var3=bar')['status'] == 200, 'arr 4' 1384 assert client.get(url='/?var1=bar')['status'] == 404, 'arr 5' 1385 assert client.get(url='/?var1=bar&var4=foo')['status'] == 200, 'arr 6' 1386 1387 assert 'success' in client.conf_delete( 1388 'routes/0/match/arguments/1' 1389 ), 'match arguments array configure 2' 1390 1391 assert client.get(url='/?var2=val2')['status'] == 404, 'arr 7' 1392 assert client.get(url='/?var3=foo')['status'] == 200, 'arr 8' 1393 1394 1395def test_routes_match_arguments_invalid(): 1396 route_match_invalid({"arguments": ["var"]}) 1397 route_match_invalid({"arguments": [{"var1": {}}]}) 1398 route_match_invalid({"arguments": {"": "bar"}}) 1399 route_match_invalid({"arguments": {"foo": "%"}}) 1400 route_match_invalid({"arguments": {"foo": "%1G"}}) 1401 route_match_invalid({"arguments": {"%": "bar"}}) 1402 route_match_invalid({"arguments": {"foo": "%0"}}) 1403 route_match_invalid({"arguments": {"foo": "%%1F"}}) 1404 route_match_invalid({"arguments": {"%%1F": ""}}) 1405 route_match_invalid({"arguments": {"%7%F": ""}}) 1406 1407 1408def test_routes_match_query(): 1409 route_match({"query": "!"}) 1410 assert client.get(url='/')['status'] == 404 1411 assert client.get(url='/?')['status'] == 404 1412 assert client.get(url='/?foo')['status'] == 200 1413 assert client.get(url='/?foo=')['status'] == 200 1414 assert client.get(url='/?foo=baz')['status'] == 200 1415 1416 route_match({"query": "foo=%26"}) 1417 assert client.get(url='/?foo=&')['status'] == 200 1418 1419 route_match({"query": "a=b&c=d"}) 1420 assert client.get(url='/?a=b&c=d')['status'] == 200 1421 1422 route_match({"query": "a=b%26c%3Dd"}) 1423 assert client.get(url='/?a=b%26c%3Dd')['status'] == 200 1424 assert client.get(url='/?a=b&c=d')['status'] == 200 1425 1426 route_match({"query": "a=b%26c%3Dd+e"}) 1427 assert client.get(url='/?a=b&c=d e')['status'] == 200 1428 1429 1430def test_routes_match_query_array(): 1431 route_match({"query": ["foo", "bar"]}) 1432 1433 assert client.get()['status'] == 404, 'no args' 1434 assert client.get(url='/?foo')['status'] == 200, 'arg first' 1435 assert client.get(url='/?bar')['status'] == 200, 'arg second' 1436 1437 assert 'success' in client.conf_delete( 1438 'routes/0/match/query/1' 1439 ), 'query array remove second' 1440 1441 assert client.get(url='/?foo')['status'] == 200, 'still arg first' 1442 assert client.get(url='/?bar')['status'] == 404, 'no arg second' 1443 1444 route_match({"query": ["!f", "foo"]}) 1445 1446 assert client.get(url='/?f')['status'] == 404, 'negative arg' 1447 assert client.get(url='/?fo')['status'] == 404, 'negative arg 2' 1448 assert client.get(url='/?foo')['status'] == 200, 'negative arg 3' 1449 1450 route_match({"query": []}) 1451 assert client.get()['status'] == 200, 'empty array' 1452 1453 1454def test_routes_match_query_invalid(): 1455 route_match_invalid({"query": [1]}) 1456 route_match_invalid({"query": "%"}) 1457 route_match_invalid({"query": "%1G"}) 1458 route_match_invalid({"query": "%0"}) 1459 route_match_invalid({"query": "%%1F"}) 1460 route_match_invalid({"query": ["foo", "%3D", "%%1F"]}) 1461 1462 1463def test_routes_match_cookies(): 1464 route_match({"cookies": {"foO": "bar"}}) 1465 1466 assert client.get()['status'] == 404, 'cookie' 1467 cookie('foO=bar', 200) 1468 cookie('foO=bar;1', 200) 1469 cookie(['foO=bar', 'blah=blah'], 200) 1470 cookie('foO=bar; blah=blah', 200) 1471 cookie('Foo=bar', 404) 1472 cookie('foO=Bar', 404) 1473 cookie('foO=bar1', 404) 1474 cookie('1foO=bar;', 404) 1475 1476 1477def test_routes_match_cookies_empty(): 1478 route_match({"cookies": {}}) 1479 assert client.get()['status'] == 200, 'cookies empty' 1480 1481 route_match({"cookies": []}) 1482 assert client.get()['status'] == 200, 'cookies empty 2' 1483 1484 1485def test_routes_match_cookies_invalid(): 1486 route_match_invalid({"cookies": ["var"]}) 1487 route_match_invalid({"cookies": [{"foo": {}}]}) 1488 1489 1490def test_routes_match_cookies_complex(): 1491 route_match({"cookies": {"foo": "bar=baz"}}) 1492 cookie('foo=bar=baz', 200) 1493 cookie(' foo=bar=baz ', 200) 1494 cookie('=foo=bar=baz', 404) 1495 1496 route_match({"cookies": {"foo": ""}}) 1497 cookie('foo=', 200) 1498 cookie('foo=;', 200) 1499 cookie(' foo=;', 200) 1500 cookie('foo', 404) 1501 cookie('', 404) 1502 cookie('=', 404) 1503 1504 1505def test_routes_match_cookies_multiple(): 1506 route_match({"cookies": {"foo": "bar", "blah": "blah"}}) 1507 1508 assert client.get()['status'] == 404, 'multiple' 1509 cookie('foo=bar; blah=blah', 200) 1510 cookie(['foo=bar', 'blah=blah'], 200) 1511 cookie(['foo=bar; blah', 'blah'], 404) 1512 cookie(['foo=bar; blah=test', 'blah=blah'], 404) 1513 1514 1515def test_routes_match_cookies_multiple_values(): 1516 route_match({"cookies": {"blah": "blah"}}) 1517 1518 cookie(['blah=blah', 'blah=blah', 'blah=blah'], 200) 1519 cookie(['blah=blah', 'blah=test', 'blah=blah'], 404) 1520 cookie(['blah=blah; blah=', 'blah=blah'], 404) 1521 1522 1523def test_routes_match_cookies_multiple_rules(): 1524 route_match({"cookies": {"blah": ["test", "blah"]}}) 1525 1526 assert client.get()['status'] == 404, 'multiple rules' 1527 cookie('blah=test', 200) 1528 cookie('blah=blah', 200) 1529 cookie(['blah=blah', 'blah=test', 'blah=blah'], 200) 1530 cookie(['blah=blah; blah=test', 'blah=blah'], 200) 1531 cookie(['blah=blah', 'blah'], 200) # invalid cookie 1532 1533 1534def test_routes_match_cookies_array(): 1535 route_match( 1536 { 1537 "cookies": [ 1538 {"var1": "val1*"}, 1539 {"var2": "val2"}, 1540 {"var3": ["foo", "bar"]}, 1541 {"var1": "bar", "var4": "foo"}, 1542 ] 1543 } 1544 ) 1545 1546 assert client.get()['status'] == 404, 'cookies array' 1547 cookie('var1=val123', 200) 1548 cookie('var2=val2', 200) 1549 cookie(' var2=val2 ', 200) 1550 cookie('var3=bar', 200) 1551 cookie('var3=bar;', 200) 1552 cookie('var1=bar', 404) 1553 cookie('var1=bar; var4=foo;', 200) 1554 cookie(['var1=bar', 'var4=foo'], 200) 1555 1556 assert 'success' in client.conf_delete( 1557 'routes/0/match/cookies/1' 1558 ), 'match cookies array configure 2' 1559 1560 cookie('var2=val2', 404) 1561 cookie('var3=foo', 200) 1562 1563 1564def test_routes_match_scheme(): 1565 route_match({"scheme": "http"}) 1566 route_match({"scheme": "https"}) 1567 route_match({"scheme": "HtTp"}) 1568 route_match({"scheme": "HtTpS"}) 1569 1570 1571def test_routes_match_scheme_invalid(): 1572 route_match_invalid({"scheme": ["http"]}) 1573 route_match_invalid({"scheme": "ftp"}) 1574 route_match_invalid({"scheme": "ws"}) 1575 route_match_invalid({"scheme": "*"}) 1576 route_match_invalid({"scheme": ""}) 1577 1578 1579def test_routes_source_port(): 1580 def sock_port(): 1581 sock = client.http(b'', raw=True, no_recv=True) 1582 port = sock.getsockname()[1] 1583 return (sock, port) 1584 1585 sock, port = sock_port() 1586 sock2, _ = sock_port() 1587 1588 route_match({"source": f'127.0.0.1:{port}'}) 1589 assert client.get(sock=sock)['status'] == 200, 'exact' 1590 assert client.get(sock=sock2)['status'] == 404, 'exact 2' 1591 1592 sock, port = sock_port() 1593 sock2, _ = sock_port() 1594 1595 route_match({"source": f'!127.0.0.1:{port}'}) 1596 assert client.get(sock=sock)['status'] == 404, 'negative' 1597 assert client.get(sock=sock2)['status'] == 200, 'negative 2' 1598 1599 sock, port = sock_port() 1600 sock2, _ = sock_port() 1601 1602 route_match({"source": [f'*:{port}', "!127.0.0.1"]}) 1603 assert client.get(sock=sock)['status'] == 404, 'negative 3' 1604 assert client.get(sock=sock2)['status'] == 404, 'negative 4' 1605 1606 sock, port = sock_port() 1607 sock2, _ = sock_port() 1608 1609 route_match({"source": f'127.0.0.1:{port}-{port}'}) 1610 assert client.get(sock=sock)['status'] == 200, 'range single' 1611 assert client.get(sock=sock2)['status'] == 404, 'range single 2' 1612 1613 socks = [ 1614 sock_port(), 1615 sock_port(), 1616 sock_port(), 1617 sock_port(), 1618 sock_port(), 1619 ] 1620 socks.sort(key=lambda sock: sock[1]) 1621 1622 route_match({"source": f'127.0.0.1:{socks[1][1]}-{socks[3][1]}'}) 1623 assert client.get(sock=socks[0][0])['status'] == 404, 'range' 1624 assert client.get(sock=socks[1][0])['status'] == 200, 'range 2' 1625 assert client.get(sock=socks[2][0])['status'] == 200, 'range 3' 1626 assert client.get(sock=socks[3][0])['status'] == 200, 'range 4' 1627 assert client.get(sock=socks[4][0])['status'] == 404, 'range 5' 1628 1629 socks = [ 1630 sock_port(), 1631 sock_port(), 1632 sock_port(), 1633 ] 1634 socks.sort(key=lambda sock: sock[1]) 1635 1636 route_match( 1637 { 1638 "source": [ 1639 f'127.0.0.1:{socks[0][1]}', 1640 f'127.0.0.1:{socks[2][1]}', 1641 ] 1642 } 1643 ) 1644 assert client.get(sock=socks[0][0])['status'] == 200, 'array' 1645 assert client.get(sock=socks[1][0])['status'] == 404, 'array 2' 1646 assert client.get(sock=socks[2][0])['status'] == 200, 'array 3' 1647 1648 1649def test_routes_source_addr(): 1650 assert 'success' in client.conf( 1651 { 1652 "*:8080": {"pass": "routes"}, 1653 "[::1]:8081": {"pass": "routes"}, 1654 }, 1655 'listeners', 1656 ), 'source listeners configure' 1657 1658 def get_ipv6(): 1659 return client.get(sock_type='ipv6', port=8081) 1660 1661 route_match({"source": "127.0.0.1"}) 1662 assert client.get()['status'] == 200, 'exact' 1663 assert get_ipv6()['status'] == 404, 'exact ipv6' 1664 1665 route_match({"source": ["127.0.0.1"]}) 1666 assert client.get()['status'] == 200, 'exact 2' 1667 assert get_ipv6()['status'] == 404, 'exact 2 ipv6' 1668 1669 route_match({"source": "!127.0.0.1"}) 1670 assert client.get()['status'] == 404, 'exact neg' 1671 assert get_ipv6()['status'] == 200, 'exact neg ipv6' 1672 1673 route_match({"source": "127.0.0.2"}) 1674 assert client.get()['status'] == 404, 'exact 3' 1675 assert get_ipv6()['status'] == 404, 'exact 3 ipv6' 1676 1677 route_match({"source": "127.0.0.1-127.0.0.1"}) 1678 assert client.get()['status'] == 200, 'range single' 1679 assert get_ipv6()['status'] == 404, 'range single ipv6' 1680 1681 route_match({"source": "127.0.0.2-127.0.0.2"}) 1682 assert client.get()['status'] == 404, 'range single 2' 1683 assert get_ipv6()['status'] == 404, 'range single 2 ipv6' 1684 1685 route_match({"source": "127.0.0.2-127.0.0.3"}) 1686 assert client.get()['status'] == 404, 'range' 1687 assert get_ipv6()['status'] == 404, 'range ipv6' 1688 1689 route_match({"source": "127.0.0.1-127.0.0.2"}) 1690 assert client.get()['status'] == 200, 'range 2' 1691 assert get_ipv6()['status'] == 404, 'range 2 ipv6' 1692 1693 route_match({"source": "127.0.0.0-127.0.0.2"}) 1694 assert client.get()['status'] == 200, 'range 3' 1695 assert get_ipv6()['status'] == 404, 'range 3 ipv6' 1696 1697 route_match({"source": "127.0.0.0-127.0.0.1"}) 1698 assert client.get()['status'] == 200, 'range 4' 1699 assert get_ipv6()['status'] == 404, 'range 4 ipv6' 1700 1701 route_match({"source": "126.0.0.0-127.0.0.0"}) 1702 assert client.get()['status'] == 404, 'range 5' 1703 assert get_ipv6()['status'] == 404, 'range 5 ipv6' 1704 1705 route_match({"source": "126.126.126.126-127.0.0.2"}) 1706 assert client.get()['status'] == 200, 'range 6' 1707 assert get_ipv6()['status'] == 404, 'range 6 ipv6' 1708 1709 1710def test_routes_source_ipv6(): 1711 assert 'success' in client.conf( 1712 { 1713 "[::1]:8080": {"pass": "routes"}, 1714 "127.0.0.1:8081": {"pass": "routes"}, 1715 }, 1716 'listeners', 1717 ), 'source listeners configure' 1718 1719 route_match({"source": "::1"}) 1720 assert client.get(sock_type='ipv6')['status'] == 200, 'exact' 1721 assert client.get(port=8081)['status'] == 404, 'exact ipv4' 1722 1723 route_match({"source": ["::1"]}) 1724 assert client.get(sock_type='ipv6')['status'] == 200, 'exact 2' 1725 assert client.get(port=8081)['status'] == 404, 'exact 2 ipv4' 1726 1727 route_match({"source": "!::1"}) 1728 assert client.get(sock_type='ipv6')['status'] == 404, 'exact neg' 1729 assert client.get(port=8081)['status'] == 200, 'exact neg ipv4' 1730 1731 route_match({"source": "::2"}) 1732 assert client.get(sock_type='ipv6')['status'] == 404, 'exact 3' 1733 assert client.get(port=8081)['status'] == 404, 'exact 3 ipv4' 1734 1735 route_match({"source": "::1-::1"}) 1736 assert client.get(sock_type='ipv6')['status'] == 200, 'range' 1737 assert client.get(port=8081)['status'] == 404, 'range ipv4' 1738 1739 route_match({"source": "::2-::2"}) 1740 assert client.get(sock_type='ipv6')['status'] == 404, 'range 2' 1741 assert client.get(port=8081)['status'] == 404, 'range 2 ipv4' 1742 1743 route_match({"source": "::2-::3"}) 1744 assert client.get(sock_type='ipv6')['status'] == 404, 'range 3' 1745 assert client.get(port=8081)['status'] == 404, 'range 3 ipv4' 1746 1747 route_match({"source": "::1-::2"}) 1748 assert client.get(sock_type='ipv6')['status'] == 200, 'range 4' 1749 assert client.get(port=8081)['status'] == 404, 'range 4 ipv4' 1750 1751 route_match({"source": "::0-::2"}) 1752 assert client.get(sock_type='ipv6')['status'] == 200, 'range 5' 1753 assert client.get(port=8081)['status'] == 404, 'range 5 ipv4' 1754 1755 route_match({"source": "::0-::1"}) 1756 assert client.get(sock_type='ipv6')['status'] == 200, 'range 6' 1757 assert client.get(port=8081)['status'] == 404, 'range 6 ipv4' 1758 1759 1760def test_routes_source_cidr(): 1761 assert 'success' in client.conf( 1762 { 1763 "*:8080": {"pass": "routes"}, 1764 "[::1]:8081": {"pass": "routes"}, 1765 }, 1766 'listeners', 1767 ), 'source listeners configure' 1768 1769 def get_ipv6(): 1770 return client.get(sock_type='ipv6', port=8081) 1771 1772 route_match({"source": "127.0.0.1/32"}) 1773 assert client.get()['status'] == 200, '32' 1774 assert get_ipv6()['status'] == 404, '32 ipv6' 1775 1776 route_match({"source": "127.0.0.0/32"}) 1777 assert client.get()['status'] == 404, '32 2' 1778 assert get_ipv6()['status'] == 404, '32 2 ipv6' 1779 1780 route_match({"source": "127.0.0.0/31"}) 1781 assert client.get()['status'] == 200, '31' 1782 assert get_ipv6()['status'] == 404, '31 ipv6' 1783 1784 route_match({"source": "0.0.0.0/1"}) 1785 assert client.get()['status'] == 200, '1' 1786 assert get_ipv6()['status'] == 404, '1 ipv6' 1787 1788 route_match({"source": "0.0.0.0/0"}) 1789 assert client.get()['status'] == 200, '0' 1790 assert get_ipv6()['status'] == 404, '0 ipv6' 1791 1792 1793def test_routes_source_cidr_ipv6(): 1794 assert 'success' in client.conf( 1795 { 1796 "[::1]:8080": {"pass": "routes"}, 1797 "127.0.0.1:8081": {"pass": "routes"}, 1798 }, 1799 'listeners', 1800 ), 'source listeners configure' 1801 1802 route_match({"source": "::1/128"}) 1803 assert client.get(sock_type='ipv6')['status'] == 200, '128' 1804 assert client.get(port=8081)['status'] == 404, '128 ipv4' 1805 1806 route_match({"source": "::0/128"}) 1807 assert client.get(sock_type='ipv6')['status'] == 404, '128 2' 1808 assert client.get(port=8081)['status'] == 404, '128 ipv4' 1809 1810 route_match({"source": "::0/127"}) 1811 assert client.get(sock_type='ipv6')['status'] == 200, '127' 1812 assert client.get(port=8081)['status'] == 404, '127 ipv4' 1813 1814 route_match({"source": "::0/32"}) 1815 assert client.get(sock_type='ipv6')['status'] == 200, '32' 1816 assert client.get(port=8081)['status'] == 404, '32 ipv4' 1817 1818 route_match({"source": "::0/1"}) 1819 assert client.get(sock_type='ipv6')['status'] == 200, '1' 1820 assert client.get(port=8081)['status'] == 404, '1 ipv4' 1821 1822 route_match({"source": "::/0"}) 1823 assert client.get(sock_type='ipv6')['status'] == 200, '0' 1824 assert client.get(port=8081)['status'] == 404, '0 ipv4' 1825 1826 1827def test_routes_source_unix(temp_dir): 1828 addr = f'{temp_dir}/sock' 1829 1830 assert 'success' in client.conf( 1831 { 1832 "127.0.0.1:8081": {"pass": "routes"}, 1833 f'unix:{addr}': {"pass": "routes"}, 1834 }, 1835 'listeners', 1836 ), 'source listeners configure' 1837 1838 route_match({"source": "!0.0.0.0/0"}) 1839 assert ( 1840 client.get(sock_type='unix', addr=addr)['status'] == 200 1841 ), 'unix ipv4 neg' 1842 1843 route_match({"source": "!::/0"}) 1844 assert ( 1845 client.get(sock_type='unix', addr=addr)['status'] == 200 1846 ), 'unix ipv6 neg' 1847 1848 route_match({"source": "unix"}) 1849 assert client.get(port=8081)['status'] == 404, 'unix ipv4' 1850 assert client.get(sock_type='unix', addr=addr)['status'] == 200, 'unix' 1851 1852 1853def test_routes_match_source(): 1854 route_match({"source": "::"}) 1855 route_match( 1856 { 1857 "source": [ 1858 "127.0.0.1", 1859 "192.168.0.10:8080", 1860 "192.168.0.11:8080-8090", 1861 ] 1862 } 1863 ) 1864 route_match( 1865 { 1866 "source": [ 1867 "10.0.0.0/8", 1868 "10.0.0.0/7:1000", 1869 "10.0.0.0/32:8080-8090", 1870 ] 1871 } 1872 ) 1873 route_match( 1874 { 1875 "source": [ 1876 "10.0.0.0-10.0.0.1", 1877 "10.0.0.0-11.0.0.0:1000", 1878 "127.0.0.0-127.0.0.255:8080-8090", 1879 ] 1880 } 1881 ) 1882 route_match({"source": ["2001::", "[2002::]:8000", "[2003::]:8080-8090"]}) 1883 route_match( 1884 { 1885 "source": [ 1886 "2001::-200f:ffff:ffff:ffff:ffff:ffff:ffff:ffff", 1887 "[fe08::-feff::]:8000", 1888 "[fff0::-fff0::10]:8080-8090", 1889 ] 1890 } 1891 ) 1892 route_match( 1893 { 1894 "source": [ 1895 "2001::/16", 1896 "[0ff::/64]:8000", 1897 "[fff0:abcd:ffff:ffff:ffff::/128]:8080-8090", 1898 ] 1899 } 1900 ) 1901 route_match({"source": "*:0-65535"}) 1902 assert client.get()['status'] == 200, 'source any' 1903 1904 1905def test_routes_match_source_invalid(): 1906 route_match_invalid({"source": "127"}) 1907 route_match_invalid({"source": "256.0.0.1"}) 1908 route_match_invalid({"source": "127.0.0."}) 1909 route_match_invalid({"source": " 127.0.0.1"}) 1910 route_match_invalid({"source": "127.0.0.1:"}) 1911 route_match_invalid({"source": "127.0.0.1/"}) 1912 route_match_invalid({"source": "11.0.0.0/33"}) 1913 route_match_invalid({"source": "11.0.0.0/65536"}) 1914 route_match_invalid({"source": "11.0.0.0-10.0.0.0"}) 1915 route_match_invalid({"source": "11.0.0.0:3000-2000"}) 1916 route_match_invalid({"source": ["11.0.0.0:3000-2000"]}) 1917 route_match_invalid({"source": "[2001::]:3000-2000"}) 1918 route_match_invalid({"source": "2001::-2000::"}) 1919 route_match_invalid({"source": "2001::/129"}) 1920 route_match_invalid({"source": "::FFFFF"}) 1921 route_match_invalid({"source": "[::1]:"}) 1922 route_match_invalid({"source": "[:::]:8080"}) 1923 route_match_invalid({"source": "*:"}) 1924 route_match_invalid({"source": "*:1-a"}) 1925 route_match_invalid({"source": "*:65536"}) 1926 1927 1928def test_routes_match_source_none(): 1929 route_match({"source": []}) 1930 assert client.get()['status'] == 404, 'source none' 1931 1932 1933def test_routes_match_destination(): 1934 assert 'success' in client.conf( 1935 {"*:8080": {"pass": "routes"}, "*:8081": {"pass": "routes"}}, 1936 'listeners', 1937 ), 'listeners configure' 1938 1939 route_match({"destination": "*:8080"}) 1940 assert client.get()['status'] == 200, 'dest' 1941 assert client.get(port=8081)['status'] == 404, 'dest 2' 1942 1943 route_match({"destination": ["127.0.0.1:8080"]}) 1944 assert client.get()['status'] == 200, 'dest 3' 1945 assert client.get(port=8081)['status'] == 404, 'dest 4' 1946 1947 route_match({"destination": "!*:8080"}) 1948 assert client.get()['status'] == 404, 'dest neg' 1949 assert client.get(port=8081)['status'] == 200, 'dest neg 2' 1950 1951 route_match({"destination": ['!*:8080', '!*:8081']}) 1952 assert client.get()['status'] == 404, 'dest neg 3' 1953 assert client.get(port=8081)['status'] == 404, 'dest neg 4' 1954 1955 route_match({"destination": ['!*:8081', '!*:8082']}) 1956 assert client.get()['status'] == 200, 'dest neg 5' 1957 1958 route_match({"destination": ['*:8080', '!*:8080']}) 1959 assert client.get()['status'] == 404, 'dest neg 6' 1960 1961 route_match({"destination": ['127.0.0.1:8080', '*:8081', '!*:8080']}) 1962 assert client.get()['status'] == 404, 'dest neg 7' 1963 assert client.get(port=8081)['status'] == 200, 'dest neg 8' 1964 1965 route_match({"destination": ['!*:8081', '!*:8082', '*:8083']}) 1966 assert client.get()['status'] == 404, 'dest neg 9' 1967 1968 route_match({"destination": ['*:8081', '!127.0.0.1:8080', '*:8080']}) 1969 assert client.get()['status'] == 404, 'dest neg 10' 1970 assert client.get(port=8081)['status'] == 200, 'dest neg 11' 1971 1972 assert 'success' in client.conf_delete( 1973 'routes/0/match/destination/0' 1974 ), 'remove destination rule' 1975 assert client.get()['status'] == 404, 'dest neg 12' 1976 assert client.get(port=8081)['status'] == 404, 'dest neg 13' 1977 1978 assert 'success' in client.conf_delete( 1979 'routes/0/match/destination/0' 1980 ), 'remove destination rule 2' 1981 assert client.get()['status'] == 200, 'dest neg 14' 1982 assert client.get(port=8081)['status'] == 404, 'dest neg 15' 1983 1984 assert 'success' in client.conf_post( 1985 "\"!127.0.0.1\"", 'routes/0/match/destination' 1986 ), 'add destination rule' 1987 assert client.get()['status'] == 404, 'dest neg 16' 1988 assert client.get(port=8081)['status'] == 404, 'dest neg 17' 1989 1990 1991def test_routes_match_destination_proxy(): 1992 assert 'success' in client.conf( 1993 { 1994 "listeners": { 1995 "*:8080": {"pass": "routes/first"}, 1996 "*:8081": {"pass": "routes/second"}, 1997 }, 1998 "routes": { 1999 "first": [{"action": {"proxy": "http://127.0.0.1:8081"}}], 2000 "second": [ 2001 { 2002 "match": {"destination": ["127.0.0.1:8081"]}, 2003 "action": {"return": 200}, 2004 } 2005 ], 2006 }, 2007 "applications": {}, 2008 } 2009 ), 'proxy configure' 2010 2011 assert client.get()['status'] == 200, 'proxy' 2012