12c593315Sopenharmony_ci/*
22c593315Sopenharmony_ci * nghttp2 - HTTP/2 C Library
32c593315Sopenharmony_ci *
42c593315Sopenharmony_ci * Copyright (c) 2016 Tatsuhiro Tsujikawa
52c593315Sopenharmony_ci *
62c593315Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining
72c593315Sopenharmony_ci * a copy of this software and associated documentation files (the
82c593315Sopenharmony_ci * "Software"), to deal in the Software without restriction, including
92c593315Sopenharmony_ci * without limitation the rights to use, copy, modify, merge, publish,
102c593315Sopenharmony_ci * distribute, sublicense, and/or sell copies of the Software, and to
112c593315Sopenharmony_ci * permit persons to whom the Software is furnished to do so, subject to
122c593315Sopenharmony_ci * the following conditions:
132c593315Sopenharmony_ci *
142c593315Sopenharmony_ci * The above copyright notice and this permission notice shall be
152c593315Sopenharmony_ci * included in all copies or substantial portions of the Software.
162c593315Sopenharmony_ci *
172c593315Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
182c593315Sopenharmony_ci * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
192c593315Sopenharmony_ci * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
202c593315Sopenharmony_ci * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
212c593315Sopenharmony_ci * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
222c593315Sopenharmony_ci * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
232c593315Sopenharmony_ci * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
242c593315Sopenharmony_ci */
252c593315Sopenharmony_ci#include "shrpx_worker_test.h"
262c593315Sopenharmony_ci
272c593315Sopenharmony_ci#ifdef HAVE_UNISTD_H
282c593315Sopenharmony_ci#  include <unistd.h>
292c593315Sopenharmony_ci#endif // HAVE_UNISTD_H
302c593315Sopenharmony_ci
312c593315Sopenharmony_ci#include <cstdlib>
322c593315Sopenharmony_ci
332c593315Sopenharmony_ci#include <CUnit/CUnit.h>
342c593315Sopenharmony_ci
352c593315Sopenharmony_ci#include "shrpx_worker.h"
362c593315Sopenharmony_ci#include "shrpx_connect_blocker.h"
372c593315Sopenharmony_ci#include "shrpx_log.h"
382c593315Sopenharmony_ci
392c593315Sopenharmony_cinamespace shrpx {
402c593315Sopenharmony_ci
412c593315Sopenharmony_civoid test_shrpx_worker_match_downstream_addr_group(void) {
422c593315Sopenharmony_ci  auto groups = std::vector<std::shared_ptr<DownstreamAddrGroup>>();
432c593315Sopenharmony_ci  for (auto &s : {"nghttp2.org/", "nghttp2.org/alpha/bravo/",
442c593315Sopenharmony_ci                  "nghttp2.org/alpha/charlie", "nghttp2.org/delta%3A",
452c593315Sopenharmony_ci                  "www.nghttp2.org/", "[::1]/", "nghttp2.org/alpha/bravo/delta",
462c593315Sopenharmony_ci                  // Check that match is done in the single node
472c593315Sopenharmony_ci                  "example.com/alpha/bravo", "192.168.0.1/alpha/", "/golf/"}) {
482c593315Sopenharmony_ci    auto g = std::make_shared<DownstreamAddrGroup>();
492c593315Sopenharmony_ci    g->pattern = ImmutableString(s);
502c593315Sopenharmony_ci    groups.push_back(std::move(g));
512c593315Sopenharmony_ci  }
522c593315Sopenharmony_ci
532c593315Sopenharmony_ci  BlockAllocator balloc(1024, 1024);
542c593315Sopenharmony_ci  RouterConfig routerconf;
552c593315Sopenharmony_ci
562c593315Sopenharmony_ci  auto &router = routerconf.router;
572c593315Sopenharmony_ci  auto &wcrouter = routerconf.rev_wildcard_router;
582c593315Sopenharmony_ci  auto &wp = routerconf.wildcard_patterns;
592c593315Sopenharmony_ci
602c593315Sopenharmony_ci  for (size_t i = 0; i < groups.size(); ++i) {
612c593315Sopenharmony_ci    auto &g = groups[i];
622c593315Sopenharmony_ci    router.add_route(StringRef{g->pattern}, i);
632c593315Sopenharmony_ci  }
642c593315Sopenharmony_ci
652c593315Sopenharmony_ci  CU_ASSERT(0 == match_downstream_addr_group(
662c593315Sopenharmony_ci                     routerconf, StringRef::from_lit("nghttp2.org"),
672c593315Sopenharmony_ci                     StringRef::from_lit("/"), groups, 255, balloc));
682c593315Sopenharmony_ci
692c593315Sopenharmony_ci  // port is removed
702c593315Sopenharmony_ci  CU_ASSERT(0 == match_downstream_addr_group(
712c593315Sopenharmony_ci                     routerconf, StringRef::from_lit("nghttp2.org:8080"),
722c593315Sopenharmony_ci                     StringRef::from_lit("/"), groups, 255, balloc));
732c593315Sopenharmony_ci
742c593315Sopenharmony_ci  // host is case-insensitive
752c593315Sopenharmony_ci  CU_ASSERT(4 == match_downstream_addr_group(
762c593315Sopenharmony_ci                     routerconf, StringRef::from_lit("WWW.nghttp2.org"),
772c593315Sopenharmony_ci                     StringRef::from_lit("/alpha"), groups, 255, balloc));
782c593315Sopenharmony_ci
792c593315Sopenharmony_ci  CU_ASSERT(1 == match_downstream_addr_group(
802c593315Sopenharmony_ci                     routerconf, StringRef::from_lit("nghttp2.org"),
812c593315Sopenharmony_ci                     StringRef::from_lit("/alpha/bravo/"), groups, 255,
822c593315Sopenharmony_ci                     balloc));
832c593315Sopenharmony_ci
842c593315Sopenharmony_ci  // /alpha/bravo also matches /alpha/bravo/
852c593315Sopenharmony_ci  CU_ASSERT(1 == match_downstream_addr_group(
862c593315Sopenharmony_ci                     routerconf, StringRef::from_lit("nghttp2.org"),
872c593315Sopenharmony_ci                     StringRef::from_lit("/alpha/bravo"), groups, 255, balloc));
882c593315Sopenharmony_ci
892c593315Sopenharmony_ci  // path part is case-sensitive
902c593315Sopenharmony_ci  CU_ASSERT(0 == match_downstream_addr_group(
912c593315Sopenharmony_ci                     routerconf, StringRef::from_lit("nghttp2.org"),
922c593315Sopenharmony_ci                     StringRef::from_lit("/Alpha/bravo"), groups, 255, balloc));
932c593315Sopenharmony_ci
942c593315Sopenharmony_ci  CU_ASSERT(1 == match_downstream_addr_group(
952c593315Sopenharmony_ci                     routerconf, StringRef::from_lit("nghttp2.org"),
962c593315Sopenharmony_ci                     StringRef::from_lit("/alpha/bravo/charlie"), groups, 255,
972c593315Sopenharmony_ci                     balloc));
982c593315Sopenharmony_ci
992c593315Sopenharmony_ci  CU_ASSERT(2 == match_downstream_addr_group(
1002c593315Sopenharmony_ci                     routerconf, StringRef::from_lit("nghttp2.org"),
1012c593315Sopenharmony_ci                     StringRef::from_lit("/alpha/charlie"), groups, 255,
1022c593315Sopenharmony_ci                     balloc));
1032c593315Sopenharmony_ci
1042c593315Sopenharmony_ci  // pattern which does not end with '/' must match its entirely.  So
1052c593315Sopenharmony_ci  // this matches to group 0, not group 2.
1062c593315Sopenharmony_ci  CU_ASSERT(0 == match_downstream_addr_group(
1072c593315Sopenharmony_ci                     routerconf, StringRef::from_lit("nghttp2.org"),
1082c593315Sopenharmony_ci                     StringRef::from_lit("/alpha/charlie/"), groups, 255,
1092c593315Sopenharmony_ci                     balloc));
1102c593315Sopenharmony_ci
1112c593315Sopenharmony_ci  CU_ASSERT(255 == match_downstream_addr_group(
1122c593315Sopenharmony_ci                       routerconf, StringRef::from_lit("example.org"),
1132c593315Sopenharmony_ci                       StringRef::from_lit("/"), groups, 255, balloc));
1142c593315Sopenharmony_ci
1152c593315Sopenharmony_ci  CU_ASSERT(255 == match_downstream_addr_group(
1162c593315Sopenharmony_ci                       routerconf, StringRef::from_lit(""),
1172c593315Sopenharmony_ci                       StringRef::from_lit("/"), groups, 255, balloc));
1182c593315Sopenharmony_ci
1192c593315Sopenharmony_ci  CU_ASSERT(255 == match_downstream_addr_group(
1202c593315Sopenharmony_ci                       routerconf, StringRef::from_lit(""),
1212c593315Sopenharmony_ci                       StringRef::from_lit("alpha"), groups, 255, balloc));
1222c593315Sopenharmony_ci
1232c593315Sopenharmony_ci  CU_ASSERT(255 == match_downstream_addr_group(
1242c593315Sopenharmony_ci                       routerconf, StringRef::from_lit("foo/bar"),
1252c593315Sopenharmony_ci                       StringRef::from_lit("/"), groups, 255, balloc));
1262c593315Sopenharmony_ci
1272c593315Sopenharmony_ci  // If path is StringRef::from_lit("*", only match with host + "/").
1282c593315Sopenharmony_ci  CU_ASSERT(0 == match_downstream_addr_group(
1292c593315Sopenharmony_ci                     routerconf, StringRef::from_lit("nghttp2.org"),
1302c593315Sopenharmony_ci                     StringRef::from_lit("*"), groups, 255, balloc));
1312c593315Sopenharmony_ci
1322c593315Sopenharmony_ci  CU_ASSERT(5 == match_downstream_addr_group(
1332c593315Sopenharmony_ci                     routerconf, StringRef::from_lit("[::1]"),
1342c593315Sopenharmony_ci                     StringRef::from_lit("/"), groups, 255, balloc));
1352c593315Sopenharmony_ci  CU_ASSERT(5 == match_downstream_addr_group(
1362c593315Sopenharmony_ci                     routerconf, StringRef::from_lit("[::1]:8080"),
1372c593315Sopenharmony_ci                     StringRef::from_lit("/"), groups, 255, balloc));
1382c593315Sopenharmony_ci  CU_ASSERT(255 == match_downstream_addr_group(
1392c593315Sopenharmony_ci                       routerconf, StringRef::from_lit("[::1"),
1402c593315Sopenharmony_ci                       StringRef::from_lit("/"), groups, 255, balloc));
1412c593315Sopenharmony_ci  CU_ASSERT(255 == match_downstream_addr_group(
1422c593315Sopenharmony_ci                       routerconf, StringRef::from_lit("[::1]8000"),
1432c593315Sopenharmony_ci                       StringRef::from_lit("/"), groups, 255, balloc));
1442c593315Sopenharmony_ci
1452c593315Sopenharmony_ci  // Check the case where adding route extends tree
1462c593315Sopenharmony_ci  CU_ASSERT(6 == match_downstream_addr_group(
1472c593315Sopenharmony_ci                     routerconf, StringRef::from_lit("nghttp2.org"),
1482c593315Sopenharmony_ci                     StringRef::from_lit("/alpha/bravo/delta"), groups, 255,
1492c593315Sopenharmony_ci                     balloc));
1502c593315Sopenharmony_ci
1512c593315Sopenharmony_ci  CU_ASSERT(1 == match_downstream_addr_group(
1522c593315Sopenharmony_ci                     routerconf, StringRef::from_lit("nghttp2.org"),
1532c593315Sopenharmony_ci                     StringRef::from_lit("/alpha/bravo/delta/"), groups, 255,
1542c593315Sopenharmony_ci                     balloc));
1552c593315Sopenharmony_ci
1562c593315Sopenharmony_ci  // Check the case where query is done in a single node
1572c593315Sopenharmony_ci  CU_ASSERT(7 == match_downstream_addr_group(
1582c593315Sopenharmony_ci                     routerconf, StringRef::from_lit("example.com"),
1592c593315Sopenharmony_ci                     StringRef::from_lit("/alpha/bravo"), groups, 255, balloc));
1602c593315Sopenharmony_ci
1612c593315Sopenharmony_ci  CU_ASSERT(255 == match_downstream_addr_group(
1622c593315Sopenharmony_ci                       routerconf, StringRef::from_lit("example.com"),
1632c593315Sopenharmony_ci                       StringRef::from_lit("/alpha/bravo/"), groups, 255,
1642c593315Sopenharmony_ci                       balloc));
1652c593315Sopenharmony_ci
1662c593315Sopenharmony_ci  CU_ASSERT(255 == match_downstream_addr_group(
1672c593315Sopenharmony_ci                       routerconf, StringRef::from_lit("example.com"),
1682c593315Sopenharmony_ci                       StringRef::from_lit("/alpha"), groups, 255, balloc));
1692c593315Sopenharmony_ci
1702c593315Sopenharmony_ci  // Check the case where quey is done in a single node
1712c593315Sopenharmony_ci  CU_ASSERT(8 == match_downstream_addr_group(
1722c593315Sopenharmony_ci                     routerconf, StringRef::from_lit("192.168.0.1"),
1732c593315Sopenharmony_ci                     StringRef::from_lit("/alpha"), groups, 255, balloc));
1742c593315Sopenharmony_ci
1752c593315Sopenharmony_ci  CU_ASSERT(8 == match_downstream_addr_group(
1762c593315Sopenharmony_ci                     routerconf, StringRef::from_lit("192.168.0.1"),
1772c593315Sopenharmony_ci                     StringRef::from_lit("/alpha/"), groups, 255, balloc));
1782c593315Sopenharmony_ci
1792c593315Sopenharmony_ci  CU_ASSERT(8 == match_downstream_addr_group(
1802c593315Sopenharmony_ci                     routerconf, StringRef::from_lit("192.168.0.1"),
1812c593315Sopenharmony_ci                     StringRef::from_lit("/alpha/bravo"), groups, 255, balloc));
1822c593315Sopenharmony_ci
1832c593315Sopenharmony_ci  CU_ASSERT(255 == match_downstream_addr_group(
1842c593315Sopenharmony_ci                       routerconf, StringRef::from_lit("192.168.0.1"),
1852c593315Sopenharmony_ci                       StringRef::from_lit("/alph"), groups, 255, balloc));
1862c593315Sopenharmony_ci
1872c593315Sopenharmony_ci  CU_ASSERT(255 == match_downstream_addr_group(
1882c593315Sopenharmony_ci                       routerconf, StringRef::from_lit("192.168.0.1"),
1892c593315Sopenharmony_ci                       StringRef::from_lit("/"), groups, 255, balloc));
1902c593315Sopenharmony_ci
1912c593315Sopenharmony_ci  // Test for wildcard hosts
1922c593315Sopenharmony_ci  auto g1 = std::make_shared<DownstreamAddrGroup>();
1932c593315Sopenharmony_ci  g1->pattern = ImmutableString::from_lit("git.nghttp2.org");
1942c593315Sopenharmony_ci  groups.push_back(std::move(g1));
1952c593315Sopenharmony_ci
1962c593315Sopenharmony_ci  auto g2 = std::make_shared<DownstreamAddrGroup>();
1972c593315Sopenharmony_ci  g2->pattern = ImmutableString::from_lit(".nghttp2.org");
1982c593315Sopenharmony_ci  groups.push_back(std::move(g2));
1992c593315Sopenharmony_ci
2002c593315Sopenharmony_ci  auto g3 = std::make_shared<DownstreamAddrGroup>();
2012c593315Sopenharmony_ci  g3->pattern = ImmutableString::from_lit(".local");
2022c593315Sopenharmony_ci  groups.push_back(std::move(g3));
2032c593315Sopenharmony_ci
2042c593315Sopenharmony_ci  wp.emplace_back(StringRef::from_lit("git.nghttp2.org"));
2052c593315Sopenharmony_ci  wcrouter.add_route(StringRef::from_lit("gro.2ptthgn.tig"), 0);
2062c593315Sopenharmony_ci  wp.back().router.add_route(StringRef::from_lit("/echo/"), 10);
2072c593315Sopenharmony_ci
2082c593315Sopenharmony_ci  wp.emplace_back(StringRef::from_lit(".nghttp2.org"));
2092c593315Sopenharmony_ci  wcrouter.add_route(StringRef::from_lit("gro.2ptthgn."), 1);
2102c593315Sopenharmony_ci  wp.back().router.add_route(StringRef::from_lit("/echo/"), 11);
2112c593315Sopenharmony_ci  wp.back().router.add_route(StringRef::from_lit("/echo/foxtrot"), 12);
2122c593315Sopenharmony_ci
2132c593315Sopenharmony_ci  wp.emplace_back(StringRef::from_lit(".local"));
2142c593315Sopenharmony_ci  wcrouter.add_route(StringRef::from_lit("lacol."), 2);
2152c593315Sopenharmony_ci  wp.back().router.add_route(StringRef::from_lit("/"), 13);
2162c593315Sopenharmony_ci
2172c593315Sopenharmony_ci  CU_ASSERT(11 == match_downstream_addr_group(
2182c593315Sopenharmony_ci                      routerconf, StringRef::from_lit("git.nghttp2.org"),
2192c593315Sopenharmony_ci                      StringRef::from_lit("/echo"), groups, 255, balloc));
2202c593315Sopenharmony_ci
2212c593315Sopenharmony_ci  CU_ASSERT(10 == match_downstream_addr_group(
2222c593315Sopenharmony_ci                      routerconf, StringRef::from_lit("0git.nghttp2.org"),
2232c593315Sopenharmony_ci                      StringRef::from_lit("/echo"), groups, 255, balloc));
2242c593315Sopenharmony_ci
2252c593315Sopenharmony_ci  CU_ASSERT(11 == match_downstream_addr_group(
2262c593315Sopenharmony_ci                      routerconf, StringRef::from_lit("it.nghttp2.org"),
2272c593315Sopenharmony_ci                      StringRef::from_lit("/echo"), groups, 255, balloc));
2282c593315Sopenharmony_ci
2292c593315Sopenharmony_ci  CU_ASSERT(255 == match_downstream_addr_group(
2302c593315Sopenharmony_ci                       routerconf, StringRef::from_lit(".nghttp2.org"),
2312c593315Sopenharmony_ci                       StringRef::from_lit("/echo/foxtrot"), groups, 255,
2322c593315Sopenharmony_ci                       balloc));
2332c593315Sopenharmony_ci
2342c593315Sopenharmony_ci  CU_ASSERT(9 == match_downstream_addr_group(
2352c593315Sopenharmony_ci                     routerconf, StringRef::from_lit("alpha.nghttp2.org"),
2362c593315Sopenharmony_ci                     StringRef::from_lit("/golf"), groups, 255, balloc));
2372c593315Sopenharmony_ci
2382c593315Sopenharmony_ci  CU_ASSERT(0 == match_downstream_addr_group(
2392c593315Sopenharmony_ci                     routerconf, StringRef::from_lit("nghttp2.org"),
2402c593315Sopenharmony_ci                     StringRef::from_lit("/echo"), groups, 255, balloc));
2412c593315Sopenharmony_ci
2422c593315Sopenharmony_ci  CU_ASSERT(13 == match_downstream_addr_group(
2432c593315Sopenharmony_ci                      routerconf, StringRef::from_lit("test.local"),
2442c593315Sopenharmony_ci                      StringRef{}, groups, 255, balloc));
2452c593315Sopenharmony_ci}
2462c593315Sopenharmony_ci
2472c593315Sopenharmony_ci} // namespace shrpx
248