12c593315Sopenharmony_ci/* 22c593315Sopenharmony_ci * nghttp2 - HTTP/2 C Library 32c593315Sopenharmony_ci * 42c593315Sopenharmony_ci * Copyright (c) 2013 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 "http2_test.h" 262c593315Sopenharmony_ci 272c593315Sopenharmony_ci#include <cassert> 282c593315Sopenharmony_ci#include <cstring> 292c593315Sopenharmony_ci#include <iostream> 302c593315Sopenharmony_ci 312c593315Sopenharmony_ci#include <CUnit/CUnit.h> 322c593315Sopenharmony_ci 332c593315Sopenharmony_ci#include "url-parser/url_parser.h" 342c593315Sopenharmony_ci 352c593315Sopenharmony_ci#include "http2.h" 362c593315Sopenharmony_ci#include "util.h" 372c593315Sopenharmony_ci 382c593315Sopenharmony_ciusing namespace nghttp2; 392c593315Sopenharmony_ci 402c593315Sopenharmony_ci#define MAKE_NV(K, V) \ 412c593315Sopenharmony_ci { \ 422c593315Sopenharmony_ci (uint8_t *)K, (uint8_t *)V, sizeof(K) - 1, sizeof(V) - 1, \ 432c593315Sopenharmony_ci NGHTTP2_NV_FLAG_NONE \ 442c593315Sopenharmony_ci } 452c593315Sopenharmony_ci 462c593315Sopenharmony_cinamespace shrpx { 472c593315Sopenharmony_ci 482c593315Sopenharmony_cinamespace { 492c593315Sopenharmony_civoid check_nv(const HeaderRef &a, const nghttp2_nv *b) { 502c593315Sopenharmony_ci CU_ASSERT(a.name.size() == b->namelen); 512c593315Sopenharmony_ci CU_ASSERT(a.value.size() == b->valuelen); 522c593315Sopenharmony_ci CU_ASSERT(memcmp(a.name.c_str(), b->name, b->namelen) == 0); 532c593315Sopenharmony_ci CU_ASSERT(memcmp(a.value.c_str(), b->value, b->valuelen) == 0); 542c593315Sopenharmony_ci} 552c593315Sopenharmony_ci} // namespace 562c593315Sopenharmony_ci 572c593315Sopenharmony_civoid test_http2_add_header(void) { 582c593315Sopenharmony_ci auto nva = Headers(); 592c593315Sopenharmony_ci 602c593315Sopenharmony_ci http2::add_header(nva, (const uint8_t *)"alpha", 5, (const uint8_t *)"123", 3, 612c593315Sopenharmony_ci false, -1); 622c593315Sopenharmony_ci CU_ASSERT(Headers::value_type("alpha", "123") == nva[0]); 632c593315Sopenharmony_ci CU_ASSERT(!nva[0].no_index); 642c593315Sopenharmony_ci 652c593315Sopenharmony_ci nva.clear(); 662c593315Sopenharmony_ci 672c593315Sopenharmony_ci http2::add_header(nva, (const uint8_t *)"alpha", 5, (const uint8_t *)"", 0, 682c593315Sopenharmony_ci true, -1); 692c593315Sopenharmony_ci CU_ASSERT(Headers::value_type("alpha", "") == nva[0]); 702c593315Sopenharmony_ci CU_ASSERT(nva[0].no_index); 712c593315Sopenharmony_ci 722c593315Sopenharmony_ci nva.clear(); 732c593315Sopenharmony_ci 742c593315Sopenharmony_ci http2::add_header(nva, (const uint8_t *)"a", 1, (const uint8_t *)" b", 2, 752c593315Sopenharmony_ci false, -1); 762c593315Sopenharmony_ci CU_ASSERT(Headers::value_type("a", "b") == nva[0]); 772c593315Sopenharmony_ci 782c593315Sopenharmony_ci nva.clear(); 792c593315Sopenharmony_ci 802c593315Sopenharmony_ci http2::add_header(nva, (const uint8_t *)"a", 1, (const uint8_t *)"b ", 2, 812c593315Sopenharmony_ci false, -1); 822c593315Sopenharmony_ci CU_ASSERT(Headers::value_type("a", "b") == nva[0]); 832c593315Sopenharmony_ci 842c593315Sopenharmony_ci nva.clear(); 852c593315Sopenharmony_ci 862c593315Sopenharmony_ci http2::add_header(nva, (const uint8_t *)"a", 1, (const uint8_t *)" b ", 5, 872c593315Sopenharmony_ci false, -1); 882c593315Sopenharmony_ci CU_ASSERT(Headers::value_type("a", "b") == nva[0]); 892c593315Sopenharmony_ci 902c593315Sopenharmony_ci nva.clear(); 912c593315Sopenharmony_ci 922c593315Sopenharmony_ci http2::add_header(nva, (const uint8_t *)"a", 1, (const uint8_t *)" bravo ", 932c593315Sopenharmony_ci 9, false, -1); 942c593315Sopenharmony_ci CU_ASSERT(Headers::value_type("a", "bravo") == nva[0]); 952c593315Sopenharmony_ci 962c593315Sopenharmony_ci nva.clear(); 972c593315Sopenharmony_ci 982c593315Sopenharmony_ci http2::add_header(nva, (const uint8_t *)"a", 1, (const uint8_t *)" ", 4, 992c593315Sopenharmony_ci false, -1); 1002c593315Sopenharmony_ci CU_ASSERT(Headers::value_type("a", "") == nva[0]); 1012c593315Sopenharmony_ci 1022c593315Sopenharmony_ci nva.clear(); 1032c593315Sopenharmony_ci 1042c593315Sopenharmony_ci http2::add_header(nva, (const uint8_t *)"te", 2, (const uint8_t *)"trailers", 1052c593315Sopenharmony_ci 8, false, http2::HD_TE); 1062c593315Sopenharmony_ci CU_ASSERT(http2::HD_TE == nva[0].token); 1072c593315Sopenharmony_ci} 1082c593315Sopenharmony_ci 1092c593315Sopenharmony_civoid test_http2_get_header(void) { 1102c593315Sopenharmony_ci auto nva = Headers{{"alpha", "1"}, {"bravo", "2"}, {"bravo", "3"}, 1112c593315Sopenharmony_ci {"charlie", "4"}, {"delta", "5"}, {"echo", "6"}, 1122c593315Sopenharmony_ci {"content-length", "7"}}; 1132c593315Sopenharmony_ci const Headers::value_type *rv; 1142c593315Sopenharmony_ci rv = http2::get_header(nva, "delta"); 1152c593315Sopenharmony_ci CU_ASSERT(rv != nullptr); 1162c593315Sopenharmony_ci CU_ASSERT("delta" == rv->name); 1172c593315Sopenharmony_ci 1182c593315Sopenharmony_ci rv = http2::get_header(nva, "bravo"); 1192c593315Sopenharmony_ci CU_ASSERT(rv != nullptr); 1202c593315Sopenharmony_ci CU_ASSERT("bravo" == rv->name); 1212c593315Sopenharmony_ci 1222c593315Sopenharmony_ci rv = http2::get_header(nva, "foxtrot"); 1232c593315Sopenharmony_ci CU_ASSERT(rv == nullptr); 1242c593315Sopenharmony_ci 1252c593315Sopenharmony_ci http2::HeaderIndex hdidx; 1262c593315Sopenharmony_ci http2::init_hdidx(hdidx); 1272c593315Sopenharmony_ci hdidx[http2::HD_CONTENT_LENGTH] = 6; 1282c593315Sopenharmony_ci rv = http2::get_header(hdidx, http2::HD_CONTENT_LENGTH, nva); 1292c593315Sopenharmony_ci CU_ASSERT("content-length" == rv->name); 1302c593315Sopenharmony_ci} 1312c593315Sopenharmony_ci 1322c593315Sopenharmony_cinamespace { 1332c593315Sopenharmony_ciauto headers = HeaderRefs{ 1342c593315Sopenharmony_ci {StringRef::from_lit("alpha"), StringRef::from_lit("0"), true}, 1352c593315Sopenharmony_ci {StringRef::from_lit("bravo"), StringRef::from_lit("1")}, 1362c593315Sopenharmony_ci {StringRef::from_lit("connection"), StringRef::from_lit("2"), false, 1372c593315Sopenharmony_ci http2::HD_CONNECTION}, 1382c593315Sopenharmony_ci {StringRef::from_lit("connection"), StringRef::from_lit("3"), false, 1392c593315Sopenharmony_ci http2::HD_CONNECTION}, 1402c593315Sopenharmony_ci {StringRef::from_lit("delta"), StringRef::from_lit("4")}, 1412c593315Sopenharmony_ci {StringRef::from_lit("expect"), StringRef::from_lit("5")}, 1422c593315Sopenharmony_ci {StringRef::from_lit("foxtrot"), StringRef::from_lit("6")}, 1432c593315Sopenharmony_ci {StringRef::from_lit("tango"), StringRef::from_lit("7")}, 1442c593315Sopenharmony_ci {StringRef::from_lit("te"), StringRef::from_lit("8"), false, http2::HD_TE}, 1452c593315Sopenharmony_ci {StringRef::from_lit("te"), StringRef::from_lit("9"), false, http2::HD_TE}, 1462c593315Sopenharmony_ci {StringRef::from_lit("x-forwarded-proto"), StringRef::from_lit("10"), false, 1472c593315Sopenharmony_ci http2::HD_X_FORWARDED_FOR}, 1482c593315Sopenharmony_ci {StringRef::from_lit("x-forwarded-proto"), StringRef::from_lit("11"), false, 1492c593315Sopenharmony_ci http2::HD_X_FORWARDED_FOR}, 1502c593315Sopenharmony_ci {StringRef::from_lit("zulu"), StringRef::from_lit("12")}}; 1512c593315Sopenharmony_ci} // namespace 1522c593315Sopenharmony_ci 1532c593315Sopenharmony_cinamespace { 1542c593315Sopenharmony_ciauto headers2 = HeaderRefs{ 1552c593315Sopenharmony_ci {StringRef::from_lit("x-forwarded-for"), StringRef::from_lit("xff1"), false, 1562c593315Sopenharmony_ci http2::HD_X_FORWARDED_FOR}, 1572c593315Sopenharmony_ci {StringRef::from_lit("x-forwarded-for"), StringRef::from_lit("xff2"), false, 1582c593315Sopenharmony_ci http2::HD_X_FORWARDED_FOR}, 1592c593315Sopenharmony_ci {StringRef::from_lit("x-forwarded-proto"), StringRef::from_lit("xfp1"), 1602c593315Sopenharmony_ci false, http2::HD_X_FORWARDED_PROTO}, 1612c593315Sopenharmony_ci {StringRef::from_lit("x-forwarded-proto"), StringRef::from_lit("xfp2"), 1622c593315Sopenharmony_ci false, http2::HD_X_FORWARDED_PROTO}, 1632c593315Sopenharmony_ci {StringRef::from_lit("forwarded"), StringRef::from_lit("fwd1"), false, 1642c593315Sopenharmony_ci http2::HD_FORWARDED}, 1652c593315Sopenharmony_ci {StringRef::from_lit("forwarded"), StringRef::from_lit("fwd2"), false, 1662c593315Sopenharmony_ci http2::HD_FORWARDED}, 1672c593315Sopenharmony_ci {StringRef::from_lit("via"), StringRef::from_lit("via1"), false, 1682c593315Sopenharmony_ci http2::HD_VIA}, 1692c593315Sopenharmony_ci {StringRef::from_lit("via"), StringRef::from_lit("via2"), false, 1702c593315Sopenharmony_ci http2::HD_VIA}, 1712c593315Sopenharmony_ci}; 1722c593315Sopenharmony_ci} // namespace 1732c593315Sopenharmony_ci 1742c593315Sopenharmony_civoid test_http2_copy_headers_to_nva(void) { 1752c593315Sopenharmony_ci auto ans = std::vector<int>{0, 1, 4, 5, 6, 7, 12}; 1762c593315Sopenharmony_ci std::vector<nghttp2_nv> nva; 1772c593315Sopenharmony_ci 1782c593315Sopenharmony_ci http2::copy_headers_to_nva_nocopy(nva, headers, 1792c593315Sopenharmony_ci http2::HDOP_STRIP_X_FORWARDED_FOR); 1802c593315Sopenharmony_ci CU_ASSERT(7 == nva.size()); 1812c593315Sopenharmony_ci for (size_t i = 0; i < ans.size(); ++i) { 1822c593315Sopenharmony_ci check_nv(headers[ans[i]], &nva[i]); 1832c593315Sopenharmony_ci 1842c593315Sopenharmony_ci if (ans[i] == 0) { 1852c593315Sopenharmony_ci CU_ASSERT((NGHTTP2_NV_FLAG_NO_COPY_NAME | NGHTTP2_NV_FLAG_NO_COPY_VALUE | 1862c593315Sopenharmony_ci NGHTTP2_NV_FLAG_NO_INDEX) == nva[i].flags); 1872c593315Sopenharmony_ci } else { 1882c593315Sopenharmony_ci CU_ASSERT((NGHTTP2_NV_FLAG_NO_COPY_NAME | 1892c593315Sopenharmony_ci NGHTTP2_NV_FLAG_NO_COPY_VALUE) == nva[i].flags); 1902c593315Sopenharmony_ci } 1912c593315Sopenharmony_ci } 1922c593315Sopenharmony_ci 1932c593315Sopenharmony_ci nva.clear(); 1942c593315Sopenharmony_ci http2::copy_headers_to_nva(nva, headers, http2::HDOP_STRIP_X_FORWARDED_FOR); 1952c593315Sopenharmony_ci CU_ASSERT(7 == nva.size()); 1962c593315Sopenharmony_ci for (size_t i = 0; i < ans.size(); ++i) { 1972c593315Sopenharmony_ci check_nv(headers[ans[i]], &nva[i]); 1982c593315Sopenharmony_ci 1992c593315Sopenharmony_ci if (ans[i] == 0) { 2002c593315Sopenharmony_ci CU_ASSERT(nva[i].flags & NGHTTP2_NV_FLAG_NO_INDEX); 2012c593315Sopenharmony_ci } else { 2022c593315Sopenharmony_ci CU_ASSERT(NGHTTP2_NV_FLAG_NONE == nva[i].flags); 2032c593315Sopenharmony_ci } 2042c593315Sopenharmony_ci } 2052c593315Sopenharmony_ci 2062c593315Sopenharmony_ci nva.clear(); 2072c593315Sopenharmony_ci 2082c593315Sopenharmony_ci auto ans2 = std::vector<int>{0, 2, 4, 6}; 2092c593315Sopenharmony_ci http2::copy_headers_to_nva(nva, headers2, http2::HDOP_NONE); 2102c593315Sopenharmony_ci CU_ASSERT(ans2.size() == nva.size()); 2112c593315Sopenharmony_ci for (size_t i = 0; i < ans2.size(); ++i) { 2122c593315Sopenharmony_ci check_nv(headers2[ans2[i]], &nva[i]); 2132c593315Sopenharmony_ci } 2142c593315Sopenharmony_ci 2152c593315Sopenharmony_ci nva.clear(); 2162c593315Sopenharmony_ci 2172c593315Sopenharmony_ci http2::copy_headers_to_nva(nva, headers2, http2::HDOP_STRIP_ALL); 2182c593315Sopenharmony_ci CU_ASSERT(nva.empty()); 2192c593315Sopenharmony_ci} 2202c593315Sopenharmony_ci 2212c593315Sopenharmony_civoid test_http2_build_http1_headers_from_headers(void) { 2222c593315Sopenharmony_ci MemchunkPool pool; 2232c593315Sopenharmony_ci DefaultMemchunks buf(&pool); 2242c593315Sopenharmony_ci http2::build_http1_headers_from_headers(&buf, headers, 2252c593315Sopenharmony_ci http2::HDOP_STRIP_X_FORWARDED_FOR); 2262c593315Sopenharmony_ci auto hdrs = std::string(buf.head->pos, buf.head->last); 2272c593315Sopenharmony_ci CU_ASSERT("Alpha: 0\r\n" 2282c593315Sopenharmony_ci "Bravo: 1\r\n" 2292c593315Sopenharmony_ci "Delta: 4\r\n" 2302c593315Sopenharmony_ci "Expect: 5\r\n" 2312c593315Sopenharmony_ci "Foxtrot: 6\r\n" 2322c593315Sopenharmony_ci "Tango: 7\r\n" 2332c593315Sopenharmony_ci "Te: 8\r\n" 2342c593315Sopenharmony_ci "Te: 9\r\n" 2352c593315Sopenharmony_ci "Zulu: 12\r\n" == hdrs); 2362c593315Sopenharmony_ci 2372c593315Sopenharmony_ci buf.reset(); 2382c593315Sopenharmony_ci 2392c593315Sopenharmony_ci http2::build_http1_headers_from_headers(&buf, headers2, http2::HDOP_NONE); 2402c593315Sopenharmony_ci hdrs = std::string(buf.head->pos, buf.head->last); 2412c593315Sopenharmony_ci CU_ASSERT("X-Forwarded-For: xff1\r\n" 2422c593315Sopenharmony_ci "X-Forwarded-Proto: xfp1\r\n" 2432c593315Sopenharmony_ci "Forwarded: fwd1\r\n" 2442c593315Sopenharmony_ci "Via: via1\r\n" == hdrs); 2452c593315Sopenharmony_ci 2462c593315Sopenharmony_ci buf.reset(); 2472c593315Sopenharmony_ci 2482c593315Sopenharmony_ci http2::build_http1_headers_from_headers(&buf, headers2, 2492c593315Sopenharmony_ci http2::HDOP_STRIP_ALL); 2502c593315Sopenharmony_ci CU_ASSERT(0 == buf.rleft()); 2512c593315Sopenharmony_ci} 2522c593315Sopenharmony_ci 2532c593315Sopenharmony_civoid test_http2_lws(void) { 2542c593315Sopenharmony_ci CU_ASSERT(!http2::lws("alpha")); 2552c593315Sopenharmony_ci CU_ASSERT(http2::lws(" ")); 2562c593315Sopenharmony_ci CU_ASSERT(http2::lws("")); 2572c593315Sopenharmony_ci} 2582c593315Sopenharmony_ci 2592c593315Sopenharmony_cinamespace { 2602c593315Sopenharmony_civoid check_rewrite_location_uri(const std::string &want, const std::string &uri, 2612c593315Sopenharmony_ci const std::string &match_host, 2622c593315Sopenharmony_ci const std::string &req_authority, 2632c593315Sopenharmony_ci const std::string &upstream_scheme) { 2642c593315Sopenharmony_ci BlockAllocator balloc(4096, 4096); 2652c593315Sopenharmony_ci http_parser_url u{}; 2662c593315Sopenharmony_ci CU_ASSERT(0 == http_parser_parse_url(uri.c_str(), uri.size(), 0, &u)); 2672c593315Sopenharmony_ci auto got = http2::rewrite_location_uri( 2682c593315Sopenharmony_ci balloc, StringRef{uri}, u, StringRef{match_host}, 2692c593315Sopenharmony_ci StringRef{req_authority}, StringRef{upstream_scheme}); 2702c593315Sopenharmony_ci CU_ASSERT(want == got); 2712c593315Sopenharmony_ci} 2722c593315Sopenharmony_ci} // namespace 2732c593315Sopenharmony_ci 2742c593315Sopenharmony_civoid test_http2_rewrite_location_uri(void) { 2752c593315Sopenharmony_ci check_rewrite_location_uri("https://localhost:3000/alpha?bravo#charlie", 2762c593315Sopenharmony_ci "http://localhost:3001/alpha?bravo#charlie", 2772c593315Sopenharmony_ci "localhost:3001", "localhost:3000", "https"); 2782c593315Sopenharmony_ci check_rewrite_location_uri("https://localhost/", "http://localhost:3001/", 2792c593315Sopenharmony_ci "localhost", "localhost", "https"); 2802c593315Sopenharmony_ci check_rewrite_location_uri("http://localhost/", "http://localhost:3001/", 2812c593315Sopenharmony_ci "localhost", "localhost", "http"); 2822c593315Sopenharmony_ci check_rewrite_location_uri("http://localhost:443/", "http://localhost:3001/", 2832c593315Sopenharmony_ci "localhost", "localhost:443", "http"); 2842c593315Sopenharmony_ci check_rewrite_location_uri("https://localhost:80/", "http://localhost:3001/", 2852c593315Sopenharmony_ci "localhost", "localhost:80", "https"); 2862c593315Sopenharmony_ci check_rewrite_location_uri("", "http://localhost:3001/", "127.0.0.1", 2872c593315Sopenharmony_ci "127.0.0.1", "https"); 2882c593315Sopenharmony_ci check_rewrite_location_uri("https://localhost:3000/", 2892c593315Sopenharmony_ci "http://localhost:3001/", "localhost", 2902c593315Sopenharmony_ci "localhost:3000", "https"); 2912c593315Sopenharmony_ci check_rewrite_location_uri("https://localhost:3000/", "http://localhost/", 2922c593315Sopenharmony_ci "localhost", "localhost:3000", "https"); 2932c593315Sopenharmony_ci 2942c593315Sopenharmony_ci // match_host != req_authority 2952c593315Sopenharmony_ci check_rewrite_location_uri("https://example.org", "http://127.0.0.1:8080", 2962c593315Sopenharmony_ci "127.0.0.1", "example.org", "https"); 2972c593315Sopenharmony_ci check_rewrite_location_uri("", "http://example.org", "127.0.0.1", 2982c593315Sopenharmony_ci "example.org", "https"); 2992c593315Sopenharmony_ci} 3002c593315Sopenharmony_ci 3012c593315Sopenharmony_civoid test_http2_parse_http_status_code(void) { 3022c593315Sopenharmony_ci CU_ASSERT(200 == http2::parse_http_status_code(StringRef::from_lit("200"))); 3032c593315Sopenharmony_ci CU_ASSERT(102 == http2::parse_http_status_code(StringRef::from_lit("102"))); 3042c593315Sopenharmony_ci CU_ASSERT(-1 == http2::parse_http_status_code(StringRef::from_lit("099"))); 3052c593315Sopenharmony_ci CU_ASSERT(-1 == http2::parse_http_status_code(StringRef::from_lit("99"))); 3062c593315Sopenharmony_ci CU_ASSERT(-1 == http2::parse_http_status_code(StringRef::from_lit("-1"))); 3072c593315Sopenharmony_ci CU_ASSERT(-1 == http2::parse_http_status_code(StringRef::from_lit("20a"))); 3082c593315Sopenharmony_ci CU_ASSERT(-1 == http2::parse_http_status_code(StringRef{})); 3092c593315Sopenharmony_ci} 3102c593315Sopenharmony_ci 3112c593315Sopenharmony_civoid test_http2_index_header(void) { 3122c593315Sopenharmony_ci http2::HeaderIndex hdidx; 3132c593315Sopenharmony_ci http2::init_hdidx(hdidx); 3142c593315Sopenharmony_ci 3152c593315Sopenharmony_ci http2::index_header(hdidx, http2::HD__AUTHORITY, 0); 3162c593315Sopenharmony_ci http2::index_header(hdidx, -1, 1); 3172c593315Sopenharmony_ci 3182c593315Sopenharmony_ci CU_ASSERT(0 == hdidx[http2::HD__AUTHORITY]); 3192c593315Sopenharmony_ci} 3202c593315Sopenharmony_ci 3212c593315Sopenharmony_civoid test_http2_lookup_token(void) { 3222c593315Sopenharmony_ci CU_ASSERT(http2::HD__AUTHORITY == 3232c593315Sopenharmony_ci http2::lookup_token(StringRef::from_lit(":authority"))); 3242c593315Sopenharmony_ci CU_ASSERT(-1 == http2::lookup_token(StringRef::from_lit(":authorit"))); 3252c593315Sopenharmony_ci CU_ASSERT(-1 == http2::lookup_token(StringRef::from_lit(":Authority"))); 3262c593315Sopenharmony_ci CU_ASSERT(http2::HD_EXPECT == 3272c593315Sopenharmony_ci http2::lookup_token(StringRef::from_lit("expect"))); 3282c593315Sopenharmony_ci} 3292c593315Sopenharmony_ci 3302c593315Sopenharmony_civoid test_http2_parse_link_header(void) { 3312c593315Sopenharmony_ci { 3322c593315Sopenharmony_ci // only URI appears; we don't extract URI unless it bears rel=preload 3332c593315Sopenharmony_ci auto res = http2::parse_link_header(StringRef::from_lit("<url>")); 3342c593315Sopenharmony_ci CU_ASSERT(0 == res.size()); 3352c593315Sopenharmony_ci } 3362c593315Sopenharmony_ci { 3372c593315Sopenharmony_ci // URI url should be extracted 3382c593315Sopenharmony_ci auto res = 3392c593315Sopenharmony_ci http2::parse_link_header(StringRef::from_lit("<url>; rel=preload")); 3402c593315Sopenharmony_ci CU_ASSERT(1 == res.size()); 3412c593315Sopenharmony_ci CU_ASSERT("url" == res[0].uri); 3422c593315Sopenharmony_ci } 3432c593315Sopenharmony_ci { 3442c593315Sopenharmony_ci // With extra link-param. URI url should be extracted 3452c593315Sopenharmony_ci auto res = http2::parse_link_header( 3462c593315Sopenharmony_ci StringRef::from_lit("<url>; rel=preload; as=file")); 3472c593315Sopenharmony_ci CU_ASSERT(1 == res.size()); 3482c593315Sopenharmony_ci CU_ASSERT("url" == res[0].uri); 3492c593315Sopenharmony_ci } 3502c593315Sopenharmony_ci { 3512c593315Sopenharmony_ci // With extra link-param. URI url should be extracted 3522c593315Sopenharmony_ci auto res = http2::parse_link_header( 3532c593315Sopenharmony_ci StringRef::from_lit("<url>; as=file; rel=preload")); 3542c593315Sopenharmony_ci CU_ASSERT(1 == res.size()); 3552c593315Sopenharmony_ci CU_ASSERT("url" == res[0].uri); 3562c593315Sopenharmony_ci } 3572c593315Sopenharmony_ci { 3582c593315Sopenharmony_ci // With extra link-param and quote-string. URI url should be 3592c593315Sopenharmony_ci // extracted 3602c593315Sopenharmony_ci auto res = http2::parse_link_header( 3612c593315Sopenharmony_ci StringRef::from_lit(R"(<url>; rel=preload; title="foo,bar")")); 3622c593315Sopenharmony_ci CU_ASSERT(1 == res.size()); 3632c593315Sopenharmony_ci CU_ASSERT("url" == res[0].uri); 3642c593315Sopenharmony_ci } 3652c593315Sopenharmony_ci { 3662c593315Sopenharmony_ci // With extra link-param and quote-string. URI url should be 3672c593315Sopenharmony_ci // extracted 3682c593315Sopenharmony_ci auto res = http2::parse_link_header( 3692c593315Sopenharmony_ci StringRef::from_lit(R"(<url>; title="foo,bar"; rel=preload)")); 3702c593315Sopenharmony_ci CU_ASSERT(1 == res.size()); 3712c593315Sopenharmony_ci CU_ASSERT("url" == res[0].uri); 3722c593315Sopenharmony_ci } 3732c593315Sopenharmony_ci { 3742c593315Sopenharmony_ci // ',' after quote-string 3752c593315Sopenharmony_ci auto res = http2::parse_link_header( 3762c593315Sopenharmony_ci StringRef::from_lit(R"(<url>; title="foo,bar", <url2>; rel=preload)")); 3772c593315Sopenharmony_ci CU_ASSERT(1 == res.size()); 3782c593315Sopenharmony_ci CU_ASSERT("url2" == res[0].uri); 3792c593315Sopenharmony_ci } 3802c593315Sopenharmony_ci { 3812c593315Sopenharmony_ci // Only first URI should be extracted. 3822c593315Sopenharmony_ci auto res = http2::parse_link_header( 3832c593315Sopenharmony_ci StringRef::from_lit("<url>; rel=preload, <url2>")); 3842c593315Sopenharmony_ci CU_ASSERT(1 == res.size()); 3852c593315Sopenharmony_ci CU_ASSERT("url" == res[0].uri); 3862c593315Sopenharmony_ci } 3872c593315Sopenharmony_ci { 3882c593315Sopenharmony_ci // Both have rel=preload, so both urls should be extracted 3892c593315Sopenharmony_ci auto res = http2::parse_link_header( 3902c593315Sopenharmony_ci StringRef::from_lit("<url>; rel=preload, <url2>; rel=preload")); 3912c593315Sopenharmony_ci CU_ASSERT(2 == res.size()); 3922c593315Sopenharmony_ci CU_ASSERT("url" == res[0].uri); 3932c593315Sopenharmony_ci CU_ASSERT("url2" == res[1].uri); 3942c593315Sopenharmony_ci } 3952c593315Sopenharmony_ci { 3962c593315Sopenharmony_ci // Second URI uri should be extracted. 3972c593315Sopenharmony_ci auto res = http2::parse_link_header( 3982c593315Sopenharmony_ci StringRef::from_lit("<url>, <url2>;rel=preload")); 3992c593315Sopenharmony_ci CU_ASSERT(1 == res.size()); 4002c593315Sopenharmony_ci CU_ASSERT("url2" == res[0].uri); 4012c593315Sopenharmony_ci } 4022c593315Sopenharmony_ci { 4032c593315Sopenharmony_ci // Error if input ends with ';' 4042c593315Sopenharmony_ci auto res = 4052c593315Sopenharmony_ci http2::parse_link_header(StringRef::from_lit("<url>;rel=preload;")); 4062c593315Sopenharmony_ci CU_ASSERT(0 == res.size()); 4072c593315Sopenharmony_ci } 4082c593315Sopenharmony_ci { 4092c593315Sopenharmony_ci // Error if link header ends with ';' 4102c593315Sopenharmony_ci auto res = http2::parse_link_header( 4112c593315Sopenharmony_ci StringRef::from_lit("<url>;rel=preload;, <url>")); 4122c593315Sopenharmony_ci CU_ASSERT(0 == res.size()); 4132c593315Sopenharmony_ci } 4142c593315Sopenharmony_ci { 4152c593315Sopenharmony_ci // OK if input ends with ',' 4162c593315Sopenharmony_ci auto res = 4172c593315Sopenharmony_ci http2::parse_link_header(StringRef::from_lit("<url>;rel=preload,")); 4182c593315Sopenharmony_ci CU_ASSERT(1 == res.size()); 4192c593315Sopenharmony_ci CU_ASSERT("url" == res[0].uri); 4202c593315Sopenharmony_ci } 4212c593315Sopenharmony_ci { 4222c593315Sopenharmony_ci // Multiple repeated ','s between fields is OK 4232c593315Sopenharmony_ci auto res = http2::parse_link_header( 4242c593315Sopenharmony_ci StringRef::from_lit("<url>,,,<url2>;rel=preload")); 4252c593315Sopenharmony_ci CU_ASSERT(1 == res.size()); 4262c593315Sopenharmony_ci CU_ASSERT("url2" == res[0].uri); 4272c593315Sopenharmony_ci } 4282c593315Sopenharmony_ci { 4292c593315Sopenharmony_ci // Error if url is not enclosed by <> 4302c593315Sopenharmony_ci auto res = 4312c593315Sopenharmony_ci http2::parse_link_header(StringRef::from_lit("url>;rel=preload")); 4322c593315Sopenharmony_ci CU_ASSERT(0 == res.size()); 4332c593315Sopenharmony_ci } 4342c593315Sopenharmony_ci { 4352c593315Sopenharmony_ci // Error if url is not enclosed by <> 4362c593315Sopenharmony_ci auto res = 4372c593315Sopenharmony_ci http2::parse_link_header(StringRef::from_lit("<url;rel=preload")); 4382c593315Sopenharmony_ci CU_ASSERT(0 == res.size()); 4392c593315Sopenharmony_ci } 4402c593315Sopenharmony_ci { 4412c593315Sopenharmony_ci // Empty parameter value is not allowed 4422c593315Sopenharmony_ci auto res = 4432c593315Sopenharmony_ci http2::parse_link_header(StringRef::from_lit("<url>;rel=preload; as=")); 4442c593315Sopenharmony_ci CU_ASSERT(0 == res.size()); 4452c593315Sopenharmony_ci } 4462c593315Sopenharmony_ci { 4472c593315Sopenharmony_ci // Empty parameter value is not allowed 4482c593315Sopenharmony_ci auto res = 4492c593315Sopenharmony_ci http2::parse_link_header(StringRef::from_lit("<url>;as=;rel=preload")); 4502c593315Sopenharmony_ci CU_ASSERT(0 == res.size()); 4512c593315Sopenharmony_ci } 4522c593315Sopenharmony_ci { 4532c593315Sopenharmony_ci // Empty parameter value is not allowed 4542c593315Sopenharmony_ci auto res = http2::parse_link_header( 4552c593315Sopenharmony_ci StringRef::from_lit("<url>;as=, <url>;rel=preload")); 4562c593315Sopenharmony_ci CU_ASSERT(0 == res.size()); 4572c593315Sopenharmony_ci } 4582c593315Sopenharmony_ci { 4592c593315Sopenharmony_ci // Empty parameter name is not allowed 4602c593315Sopenharmony_ci auto res = http2::parse_link_header( 4612c593315Sopenharmony_ci StringRef::from_lit("<url>; =file; rel=preload")); 4622c593315Sopenharmony_ci CU_ASSERT(0 == res.size()); 4632c593315Sopenharmony_ci } 4642c593315Sopenharmony_ci { 4652c593315Sopenharmony_ci // Without whitespaces 4662c593315Sopenharmony_ci auto res = http2::parse_link_header( 4672c593315Sopenharmony_ci StringRef::from_lit("<url>;as=file;rel=preload,<url2>;rel=preload")); 4682c593315Sopenharmony_ci CU_ASSERT(2 == res.size()); 4692c593315Sopenharmony_ci CU_ASSERT("url" == res[0].uri); 4702c593315Sopenharmony_ci CU_ASSERT("url2" == res[1].uri); 4712c593315Sopenharmony_ci } 4722c593315Sopenharmony_ci { 4732c593315Sopenharmony_ci // link-extension may have no value 4742c593315Sopenharmony_ci auto res = 4752c593315Sopenharmony_ci http2::parse_link_header(StringRef::from_lit("<url>; as; rel=preload")); 4762c593315Sopenharmony_ci CU_ASSERT(1 == res.size()); 4772c593315Sopenharmony_ci CU_ASSERT("url" == res[0].uri); 4782c593315Sopenharmony_ci } 4792c593315Sopenharmony_ci { 4802c593315Sopenharmony_ci // ext-name-star 4812c593315Sopenharmony_ci auto res = http2::parse_link_header( 4822c593315Sopenharmony_ci StringRef::from_lit("<url>; foo*=bar; rel=preload")); 4832c593315Sopenharmony_ci CU_ASSERT(1 == res.size()); 4842c593315Sopenharmony_ci CU_ASSERT("url" == res[0].uri); 4852c593315Sopenharmony_ci } 4862c593315Sopenharmony_ci { 4872c593315Sopenharmony_ci // '*' is not allowed expect for trailing one 4882c593315Sopenharmony_ci auto res = http2::parse_link_header( 4892c593315Sopenharmony_ci StringRef::from_lit("<url>; *=bar; rel=preload")); 4902c593315Sopenharmony_ci CU_ASSERT(0 == res.size()); 4912c593315Sopenharmony_ci } 4922c593315Sopenharmony_ci { 4932c593315Sopenharmony_ci // '*' is not allowed expect for trailing one 4942c593315Sopenharmony_ci auto res = http2::parse_link_header( 4952c593315Sopenharmony_ci StringRef::from_lit("<url>; foo*bar=buzz; rel=preload")); 4962c593315Sopenharmony_ci CU_ASSERT(0 == res.size()); 4972c593315Sopenharmony_ci } 4982c593315Sopenharmony_ci { 4992c593315Sopenharmony_ci // ext-name-star must be followed by '=' 5002c593315Sopenharmony_ci auto res = http2::parse_link_header( 5012c593315Sopenharmony_ci StringRef::from_lit("<url>; foo*; rel=preload")); 5022c593315Sopenharmony_ci CU_ASSERT(0 == res.size()); 5032c593315Sopenharmony_ci } 5042c593315Sopenharmony_ci { 5052c593315Sopenharmony_ci // '>' is not followed by ';' 5062c593315Sopenharmony_ci auto res = 5072c593315Sopenharmony_ci http2::parse_link_header(StringRef::from_lit("<url> rel=preload")); 5082c593315Sopenharmony_ci CU_ASSERT(0 == res.size()); 5092c593315Sopenharmony_ci } 5102c593315Sopenharmony_ci { 5112c593315Sopenharmony_ci // Starting with whitespace is no problem. 5122c593315Sopenharmony_ci auto res = 5132c593315Sopenharmony_ci http2::parse_link_header(StringRef::from_lit(" <url>; rel=preload")); 5142c593315Sopenharmony_ci CU_ASSERT(1 == res.size()); 5152c593315Sopenharmony_ci CU_ASSERT("url" == res[0].uri); 5162c593315Sopenharmony_ci } 5172c593315Sopenharmony_ci { 5182c593315Sopenharmony_ci // preload is a prefix of bogus rel parameter value 5192c593315Sopenharmony_ci auto res = 5202c593315Sopenharmony_ci http2::parse_link_header(StringRef::from_lit("<url>; rel=preloadx")); 5212c593315Sopenharmony_ci CU_ASSERT(0 == res.size()); 5222c593315Sopenharmony_ci } 5232c593315Sopenharmony_ci { 5242c593315Sopenharmony_ci // preload in relation-types list 5252c593315Sopenharmony_ci auto res = http2::parse_link_header( 5262c593315Sopenharmony_ci StringRef::from_lit(R"(<url>; rel="preload")")); 5272c593315Sopenharmony_ci CU_ASSERT(1 == res.size()); 5282c593315Sopenharmony_ci CU_ASSERT("url" == res[0].uri); 5292c593315Sopenharmony_ci } 5302c593315Sopenharmony_ci { 5312c593315Sopenharmony_ci // preload in relation-types list followed by another parameter 5322c593315Sopenharmony_ci auto res = http2::parse_link_header( 5332c593315Sopenharmony_ci StringRef::from_lit(R"(<url>; rel="preload foo")")); 5342c593315Sopenharmony_ci CU_ASSERT(1 == res.size()); 5352c593315Sopenharmony_ci CU_ASSERT("url" == res[0].uri); 5362c593315Sopenharmony_ci } 5372c593315Sopenharmony_ci { 5382c593315Sopenharmony_ci // preload in relation-types list following another parameter 5392c593315Sopenharmony_ci auto res = http2::parse_link_header( 5402c593315Sopenharmony_ci StringRef::from_lit(R"(<url>; rel="foo preload")")); 5412c593315Sopenharmony_ci CU_ASSERT(1 == res.size()); 5422c593315Sopenharmony_ci CU_ASSERT("url" == res[0].uri); 5432c593315Sopenharmony_ci } 5442c593315Sopenharmony_ci { 5452c593315Sopenharmony_ci // preload in relation-types list between other parameters 5462c593315Sopenharmony_ci auto res = http2::parse_link_header( 5472c593315Sopenharmony_ci StringRef::from_lit(R"(<url>; rel="foo preload bar")")); 5482c593315Sopenharmony_ci CU_ASSERT(1 == res.size()); 5492c593315Sopenharmony_ci CU_ASSERT("url" == res[0].uri); 5502c593315Sopenharmony_ci } 5512c593315Sopenharmony_ci { 5522c593315Sopenharmony_ci // preload in relation-types list between other parameters 5532c593315Sopenharmony_ci auto res = http2::parse_link_header( 5542c593315Sopenharmony_ci StringRef::from_lit(R"(<url>; rel="foo preload bar")")); 5552c593315Sopenharmony_ci CU_ASSERT(1 == res.size()); 5562c593315Sopenharmony_ci CU_ASSERT("url" == res[0].uri); 5572c593315Sopenharmony_ci } 5582c593315Sopenharmony_ci { 5592c593315Sopenharmony_ci // no preload in relation-types list 5602c593315Sopenharmony_ci auto res = 5612c593315Sopenharmony_ci http2::parse_link_header(StringRef::from_lit(R"(<url>; rel="foo")")); 5622c593315Sopenharmony_ci CU_ASSERT(0 == res.size()); 5632c593315Sopenharmony_ci } 5642c593315Sopenharmony_ci { 5652c593315Sopenharmony_ci // no preload in relation-types list, multiple unrelated elements. 5662c593315Sopenharmony_ci auto res = http2::parse_link_header( 5672c593315Sopenharmony_ci StringRef::from_lit(R"(<url>; rel="foo bar")")); 5682c593315Sopenharmony_ci CU_ASSERT(0 == res.size()); 5692c593315Sopenharmony_ci } 5702c593315Sopenharmony_ci { 5712c593315Sopenharmony_ci // preload in relation-types list, followed by another link-value. 5722c593315Sopenharmony_ci auto res = http2::parse_link_header( 5732c593315Sopenharmony_ci StringRef::from_lit(R"(<url>; rel="preload", <url2>)")); 5742c593315Sopenharmony_ci CU_ASSERT(1 == res.size()); 5752c593315Sopenharmony_ci CU_ASSERT("url" == res[0].uri); 5762c593315Sopenharmony_ci } 5772c593315Sopenharmony_ci { 5782c593315Sopenharmony_ci // preload in relation-types list, following another link-value. 5792c593315Sopenharmony_ci auto res = http2::parse_link_header( 5802c593315Sopenharmony_ci StringRef::from_lit(R"(<url>, <url2>; rel="preload")")); 5812c593315Sopenharmony_ci CU_ASSERT(1 == res.size()); 5822c593315Sopenharmony_ci CU_ASSERT("url2" == res[0].uri); 5832c593315Sopenharmony_ci } 5842c593315Sopenharmony_ci { 5852c593315Sopenharmony_ci // preload in relation-types list, followed by another link-param. 5862c593315Sopenharmony_ci auto res = http2::parse_link_header( 5872c593315Sopenharmony_ci StringRef::from_lit(R"(<url>; rel="preload"; as="font")")); 5882c593315Sopenharmony_ci CU_ASSERT(1 == res.size()); 5892c593315Sopenharmony_ci CU_ASSERT("url" == res[0].uri); 5902c593315Sopenharmony_ci } 5912c593315Sopenharmony_ci { 5922c593315Sopenharmony_ci // preload in relation-types list, followed by character other 5932c593315Sopenharmony_ci // than ';' or ',' 5942c593315Sopenharmony_ci auto res = http2::parse_link_header( 5952c593315Sopenharmony_ci StringRef::from_lit(R"(<url>; rel="preload".)")); 5962c593315Sopenharmony_ci CU_ASSERT(0 == res.size()); 5972c593315Sopenharmony_ci } 5982c593315Sopenharmony_ci { 5992c593315Sopenharmony_ci // preload in relation-types list, followed by ';' but it 6002c593315Sopenharmony_ci // terminates input 6012c593315Sopenharmony_ci auto res = http2::parse_link_header( 6022c593315Sopenharmony_ci StringRef::from_lit(R"(<url>; rel="preload";)")); 6032c593315Sopenharmony_ci CU_ASSERT(0 == res.size()); 6042c593315Sopenharmony_ci } 6052c593315Sopenharmony_ci { 6062c593315Sopenharmony_ci // preload in relation-types list, followed by ',' but it 6072c593315Sopenharmony_ci // terminates input 6082c593315Sopenharmony_ci auto res = http2::parse_link_header( 6092c593315Sopenharmony_ci StringRef::from_lit(R"(<url>; rel="preload",)")); 6102c593315Sopenharmony_ci CU_ASSERT(1 == res.size()); 6112c593315Sopenharmony_ci CU_ASSERT("url" == res[0].uri); 6122c593315Sopenharmony_ci } 6132c593315Sopenharmony_ci { 6142c593315Sopenharmony_ci // preload in relation-types list but there is preceding white 6152c593315Sopenharmony_ci // space. 6162c593315Sopenharmony_ci auto res = http2::parse_link_header( 6172c593315Sopenharmony_ci StringRef::from_lit(R"(<url>; rel=" preload")")); 6182c593315Sopenharmony_ci CU_ASSERT(0 == res.size()); 6192c593315Sopenharmony_ci } 6202c593315Sopenharmony_ci { 6212c593315Sopenharmony_ci // preload in relation-types list but there is trailing white 6222c593315Sopenharmony_ci // space. 6232c593315Sopenharmony_ci auto res = http2::parse_link_header( 6242c593315Sopenharmony_ci StringRef::from_lit(R"(<url>; rel="preload ")")); 6252c593315Sopenharmony_ci CU_ASSERT(0 == res.size()); 6262c593315Sopenharmony_ci } 6272c593315Sopenharmony_ci { 6282c593315Sopenharmony_ci // backslash escaped characters in quoted-string 6292c593315Sopenharmony_ci auto res = http2::parse_link_header( 6302c593315Sopenharmony_ci StringRef::from_lit(R"(<url>; rel=preload; title="foo\"baz\"bar")")); 6312c593315Sopenharmony_ci CU_ASSERT(1 == res.size()); 6322c593315Sopenharmony_ci CU_ASSERT("url" == res[0].uri); 6332c593315Sopenharmony_ci } 6342c593315Sopenharmony_ci { 6352c593315Sopenharmony_ci // anchor="" is acceptable 6362c593315Sopenharmony_ci auto res = http2::parse_link_header( 6372c593315Sopenharmony_ci StringRef::from_lit(R"(<url>; rel=preload; anchor="")")); 6382c593315Sopenharmony_ci CU_ASSERT(1 == res.size()); 6392c593315Sopenharmony_ci CU_ASSERT("url" == res[0].uri); 6402c593315Sopenharmony_ci } 6412c593315Sopenharmony_ci { 6422c593315Sopenharmony_ci // With anchor="#foo", url should be ignored 6432c593315Sopenharmony_ci auto res = http2::parse_link_header( 6442c593315Sopenharmony_ci StringRef::from_lit(R"(<url>; rel=preload; anchor="#foo")")); 6452c593315Sopenharmony_ci CU_ASSERT(0 == res.size()); 6462c593315Sopenharmony_ci } 6472c593315Sopenharmony_ci { 6482c593315Sopenharmony_ci // With anchor=f, url should be ignored 6492c593315Sopenharmony_ci auto res = http2::parse_link_header( 6502c593315Sopenharmony_ci StringRef::from_lit("<url>; rel=preload; anchor=f")); 6512c593315Sopenharmony_ci CU_ASSERT(0 == res.size()); 6522c593315Sopenharmony_ci } 6532c593315Sopenharmony_ci { 6542c593315Sopenharmony_ci // First url is ignored With anchor="#foo", but url should be 6552c593315Sopenharmony_ci // accepted. 6562c593315Sopenharmony_ci auto res = http2::parse_link_header(StringRef::from_lit( 6572c593315Sopenharmony_ci R"(<url>; rel=preload; anchor="#foo", <url2>; rel=preload)")); 6582c593315Sopenharmony_ci CU_ASSERT(1 == res.size()); 6592c593315Sopenharmony_ci CU_ASSERT("url2" == res[0].uri); 6602c593315Sopenharmony_ci } 6612c593315Sopenharmony_ci { 6622c593315Sopenharmony_ci // With loadpolicy="next", url should be ignored 6632c593315Sopenharmony_ci auto res = http2::parse_link_header( 6642c593315Sopenharmony_ci StringRef::from_lit(R"(<url>; rel=preload; loadpolicy="next")")); 6652c593315Sopenharmony_ci CU_ASSERT(0 == res.size()); 6662c593315Sopenharmony_ci } 6672c593315Sopenharmony_ci { 6682c593315Sopenharmony_ci // url should be picked up if empty loadpolicy is specified 6692c593315Sopenharmony_ci auto res = http2::parse_link_header( 6702c593315Sopenharmony_ci StringRef::from_lit(R"(<url>; rel=preload; loadpolicy="")")); 6712c593315Sopenharmony_ci CU_ASSERT(1 == res.size()); 6722c593315Sopenharmony_ci CU_ASSERT("url" == res[0].uri); 6732c593315Sopenharmony_ci } 6742c593315Sopenharmony_ci { 6752c593315Sopenharmony_ci // case-insensitive match 6762c593315Sopenharmony_ci auto res = http2::parse_link_header( 6772c593315Sopenharmony_ci StringRef::from_lit(R"(<url>; rel=preload; ANCHOR="#foo", <url2>; )" 6782c593315Sopenharmony_ci R"(REL=PRELOAD, <url3>; REL="foo PRELOAD bar")")); 6792c593315Sopenharmony_ci CU_ASSERT(2 == res.size()); 6802c593315Sopenharmony_ci CU_ASSERT("url2" == res[0].uri); 6812c593315Sopenharmony_ci CU_ASSERT("url3" == res[1].uri); 6822c593315Sopenharmony_ci } 6832c593315Sopenharmony_ci { 6842c593315Sopenharmony_ci // nopush at the end of input 6852c593315Sopenharmony_ci auto res = http2::parse_link_header( 6862c593315Sopenharmony_ci StringRef::from_lit("<url>; rel=preload; nopush")); 6872c593315Sopenharmony_ci CU_ASSERT(0 == res.size()); 6882c593315Sopenharmony_ci } 6892c593315Sopenharmony_ci { 6902c593315Sopenharmony_ci // nopush followed by ';' 6912c593315Sopenharmony_ci auto res = http2::parse_link_header( 6922c593315Sopenharmony_ci StringRef::from_lit("<url>; rel=preload; nopush; foo")); 6932c593315Sopenharmony_ci CU_ASSERT(0 == res.size()); 6942c593315Sopenharmony_ci } 6952c593315Sopenharmony_ci { 6962c593315Sopenharmony_ci // nopush followed by ',' 6972c593315Sopenharmony_ci auto res = http2::parse_link_header( 6982c593315Sopenharmony_ci StringRef::from_lit("<url>; nopush; rel=preload")); 6992c593315Sopenharmony_ci CU_ASSERT(0 == res.size()); 7002c593315Sopenharmony_ci } 7012c593315Sopenharmony_ci { 7022c593315Sopenharmony_ci // string whose prefix is nopush 7032c593315Sopenharmony_ci auto res = http2::parse_link_header( 7042c593315Sopenharmony_ci StringRef::from_lit("<url>; nopushyes; rel=preload")); 7052c593315Sopenharmony_ci CU_ASSERT(1 == res.size()); 7062c593315Sopenharmony_ci CU_ASSERT("url" == res[0].uri); 7072c593315Sopenharmony_ci } 7082c593315Sopenharmony_ci { 7092c593315Sopenharmony_ci // rel=preload twice 7102c593315Sopenharmony_ci auto res = http2::parse_link_header( 7112c593315Sopenharmony_ci StringRef::from_lit("<url>; rel=preload; rel=preload")); 7122c593315Sopenharmony_ci CU_ASSERT(1 == res.size()); 7132c593315Sopenharmony_ci CU_ASSERT("url" == res[0].uri); 7142c593315Sopenharmony_ci } 7152c593315Sopenharmony_ci} 7162c593315Sopenharmony_ci 7172c593315Sopenharmony_civoid test_http2_path_join(void) { 7182c593315Sopenharmony_ci { 7192c593315Sopenharmony_ci auto base = StringRef::from_lit("/"); 7202c593315Sopenharmony_ci auto rel = StringRef::from_lit("/"); 7212c593315Sopenharmony_ci CU_ASSERT("/" == http2::path_join(base, StringRef{}, rel, StringRef{})); 7222c593315Sopenharmony_ci } 7232c593315Sopenharmony_ci { 7242c593315Sopenharmony_ci auto base = StringRef::from_lit("/"); 7252c593315Sopenharmony_ci auto rel = StringRef::from_lit("/alpha"); 7262c593315Sopenharmony_ci CU_ASSERT("/alpha" == 7272c593315Sopenharmony_ci http2::path_join(base, StringRef{}, rel, StringRef{})); 7282c593315Sopenharmony_ci } 7292c593315Sopenharmony_ci { 7302c593315Sopenharmony_ci // rel ends with trailing '/' 7312c593315Sopenharmony_ci auto base = StringRef::from_lit("/"); 7322c593315Sopenharmony_ci auto rel = StringRef::from_lit("/alpha/"); 7332c593315Sopenharmony_ci CU_ASSERT("/alpha/" == 7342c593315Sopenharmony_ci http2::path_join(base, StringRef{}, rel, StringRef{})); 7352c593315Sopenharmony_ci } 7362c593315Sopenharmony_ci { 7372c593315Sopenharmony_ci // rel contains multiple components 7382c593315Sopenharmony_ci auto base = StringRef::from_lit("/"); 7392c593315Sopenharmony_ci auto rel = StringRef::from_lit("/alpha/bravo"); 7402c593315Sopenharmony_ci CU_ASSERT("/alpha/bravo" == 7412c593315Sopenharmony_ci http2::path_join(base, StringRef{}, rel, StringRef{})); 7422c593315Sopenharmony_ci } 7432c593315Sopenharmony_ci { 7442c593315Sopenharmony_ci // rel is relative 7452c593315Sopenharmony_ci auto base = StringRef::from_lit("/"); 7462c593315Sopenharmony_ci auto rel = StringRef::from_lit("alpha/bravo"); 7472c593315Sopenharmony_ci CU_ASSERT("/alpha/bravo" == 7482c593315Sopenharmony_ci http2::path_join(base, StringRef{}, rel, StringRef{})); 7492c593315Sopenharmony_ci } 7502c593315Sopenharmony_ci { 7512c593315Sopenharmony_ci // rel is relative and base ends without /, which means it refers 7522c593315Sopenharmony_ci // to file. 7532c593315Sopenharmony_ci auto base = StringRef::from_lit("/alpha"); 7542c593315Sopenharmony_ci auto rel = StringRef::from_lit("bravo/charlie"); 7552c593315Sopenharmony_ci CU_ASSERT("/bravo/charlie" == 7562c593315Sopenharmony_ci http2::path_join(base, StringRef{}, rel, StringRef{})); 7572c593315Sopenharmony_ci } 7582c593315Sopenharmony_ci { 7592c593315Sopenharmony_ci // rel contains repeated '/'s 7602c593315Sopenharmony_ci auto base = StringRef::from_lit("/"); 7612c593315Sopenharmony_ci auto rel = StringRef::from_lit("/alpha/////bravo/////"); 7622c593315Sopenharmony_ci CU_ASSERT("/alpha/bravo/" == 7632c593315Sopenharmony_ci http2::path_join(base, StringRef{}, rel, StringRef{})); 7642c593315Sopenharmony_ci } 7652c593315Sopenharmony_ci { 7662c593315Sopenharmony_ci // base ends with '/', so '..' eats 'bravo' 7672c593315Sopenharmony_ci auto base = StringRef::from_lit("/alpha/bravo/"); 7682c593315Sopenharmony_ci auto rel = StringRef::from_lit("../charlie/delta"); 7692c593315Sopenharmony_ci CU_ASSERT("/alpha/charlie/delta" == 7702c593315Sopenharmony_ci http2::path_join(base, StringRef{}, rel, StringRef{})); 7712c593315Sopenharmony_ci } 7722c593315Sopenharmony_ci { 7732c593315Sopenharmony_ci // base does not end with '/', so '..' eats 'alpha/bravo' 7742c593315Sopenharmony_ci auto base = StringRef::from_lit("/alpha/bravo"); 7752c593315Sopenharmony_ci auto rel = StringRef::from_lit("../charlie"); 7762c593315Sopenharmony_ci CU_ASSERT("/charlie" == 7772c593315Sopenharmony_ci http2::path_join(base, StringRef{}, rel, StringRef{})); 7782c593315Sopenharmony_ci } 7792c593315Sopenharmony_ci { 7802c593315Sopenharmony_ci // 'charlie' is eaten by following '..' 7812c593315Sopenharmony_ci auto base = StringRef::from_lit("/alpha/bravo/"); 7822c593315Sopenharmony_ci auto rel = StringRef::from_lit("../charlie/../delta"); 7832c593315Sopenharmony_ci CU_ASSERT("/alpha/delta" == 7842c593315Sopenharmony_ci http2::path_join(base, StringRef{}, rel, StringRef{})); 7852c593315Sopenharmony_ci } 7862c593315Sopenharmony_ci { 7872c593315Sopenharmony_ci // excessive '..' results in '/' 7882c593315Sopenharmony_ci auto base = StringRef::from_lit("/alpha/bravo/"); 7892c593315Sopenharmony_ci auto rel = StringRef::from_lit("../../../"); 7902c593315Sopenharmony_ci CU_ASSERT("/" == http2::path_join(base, StringRef{}, rel, StringRef{})); 7912c593315Sopenharmony_ci } 7922c593315Sopenharmony_ci { 7932c593315Sopenharmony_ci // excessive '..' and path component 7942c593315Sopenharmony_ci auto base = StringRef::from_lit("/alpha/bravo/"); 7952c593315Sopenharmony_ci auto rel = StringRef::from_lit("../../../charlie"); 7962c593315Sopenharmony_ci CU_ASSERT("/charlie" == 7972c593315Sopenharmony_ci http2::path_join(base, StringRef{}, rel, StringRef{})); 7982c593315Sopenharmony_ci } 7992c593315Sopenharmony_ci { 8002c593315Sopenharmony_ci // rel ends with '..' 8012c593315Sopenharmony_ci auto base = StringRef::from_lit("/alpha/bravo/"); 8022c593315Sopenharmony_ci auto rel = StringRef::from_lit("charlie/.."); 8032c593315Sopenharmony_ci CU_ASSERT("/alpha/bravo/" == 8042c593315Sopenharmony_ci http2::path_join(base, StringRef{}, rel, StringRef{})); 8052c593315Sopenharmony_ci } 8062c593315Sopenharmony_ci { 8072c593315Sopenharmony_ci // base empty and rel contains '..' 8082c593315Sopenharmony_ci auto base = StringRef{}; 8092c593315Sopenharmony_ci auto rel = StringRef::from_lit("charlie/.."); 8102c593315Sopenharmony_ci CU_ASSERT("/" == http2::path_join(base, StringRef{}, rel, StringRef{})); 8112c593315Sopenharmony_ci } 8122c593315Sopenharmony_ci { 8132c593315Sopenharmony_ci // '.' is ignored 8142c593315Sopenharmony_ci auto base = StringRef::from_lit("/"); 8152c593315Sopenharmony_ci auto rel = StringRef::from_lit("charlie/././././delta"); 8162c593315Sopenharmony_ci CU_ASSERT("/charlie/delta" == 8172c593315Sopenharmony_ci http2::path_join(base, StringRef{}, rel, StringRef{})); 8182c593315Sopenharmony_ci } 8192c593315Sopenharmony_ci { 8202c593315Sopenharmony_ci // trailing '.' is ignored 8212c593315Sopenharmony_ci auto base = StringRef::from_lit("/"); 8222c593315Sopenharmony_ci auto rel = StringRef::from_lit("charlie/."); 8232c593315Sopenharmony_ci CU_ASSERT("/charlie/" == 8242c593315Sopenharmony_ci http2::path_join(base, StringRef{}, rel, StringRef{})); 8252c593315Sopenharmony_ci } 8262c593315Sopenharmony_ci { 8272c593315Sopenharmony_ci // query 8282c593315Sopenharmony_ci auto base = StringRef::from_lit("/"); 8292c593315Sopenharmony_ci auto rel = StringRef::from_lit("/"); 8302c593315Sopenharmony_ci auto relq = StringRef::from_lit("q"); 8312c593315Sopenharmony_ci CU_ASSERT("/?q" == http2::path_join(base, StringRef{}, rel, relq)); 8322c593315Sopenharmony_ci } 8332c593315Sopenharmony_ci { 8342c593315Sopenharmony_ci // empty rel and query 8352c593315Sopenharmony_ci auto base = StringRef::from_lit("/alpha"); 8362c593315Sopenharmony_ci auto rel = StringRef{}; 8372c593315Sopenharmony_ci auto relq = StringRef::from_lit("q"); 8382c593315Sopenharmony_ci CU_ASSERT("/alpha?q" == http2::path_join(base, StringRef{}, rel, relq)); 8392c593315Sopenharmony_ci } 8402c593315Sopenharmony_ci { 8412c593315Sopenharmony_ci // both rel and query are empty 8422c593315Sopenharmony_ci auto base = StringRef::from_lit("/alpha"); 8432c593315Sopenharmony_ci auto baseq = StringRef::from_lit("r"); 8442c593315Sopenharmony_ci auto rel = StringRef{}; 8452c593315Sopenharmony_ci auto relq = StringRef{}; 8462c593315Sopenharmony_ci CU_ASSERT("/alpha?r" == http2::path_join(base, baseq, rel, relq)); 8472c593315Sopenharmony_ci } 8482c593315Sopenharmony_ci { 8492c593315Sopenharmony_ci // empty base 8502c593315Sopenharmony_ci auto base = StringRef{}; 8512c593315Sopenharmony_ci auto rel = StringRef::from_lit("/alpha"); 8522c593315Sopenharmony_ci CU_ASSERT("/alpha" == 8532c593315Sopenharmony_ci http2::path_join(base, StringRef{}, rel, StringRef{})); 8542c593315Sopenharmony_ci } 8552c593315Sopenharmony_ci { 8562c593315Sopenharmony_ci // everything is empty 8572c593315Sopenharmony_ci CU_ASSERT("/" == http2::path_join(StringRef{}, StringRef{}, StringRef{}, 8582c593315Sopenharmony_ci StringRef{})); 8592c593315Sopenharmony_ci } 8602c593315Sopenharmony_ci { 8612c593315Sopenharmony_ci // only baseq is not empty 8622c593315Sopenharmony_ci auto base = StringRef{}; 8632c593315Sopenharmony_ci auto baseq = StringRef::from_lit("r"); 8642c593315Sopenharmony_ci auto rel = StringRef{}; 8652c593315Sopenharmony_ci CU_ASSERT("/?r" == http2::path_join(base, baseq, rel, StringRef{})); 8662c593315Sopenharmony_ci } 8672c593315Sopenharmony_ci { 8682c593315Sopenharmony_ci // path starts with multiple '/'s. 8692c593315Sopenharmony_ci auto base = StringRef{}; 8702c593315Sopenharmony_ci auto baseq = StringRef{}; 8712c593315Sopenharmony_ci auto rel = StringRef::from_lit("//alpha//bravo"); 8722c593315Sopenharmony_ci auto relq = StringRef::from_lit("charlie"); 8732c593315Sopenharmony_ci CU_ASSERT("/alpha/bravo?charlie" == 8742c593315Sopenharmony_ci http2::path_join(base, baseq, rel, relq)); 8752c593315Sopenharmony_ci } 8762c593315Sopenharmony_ci // Test cases from RFC 3986, section 5.4. 8772c593315Sopenharmony_ci constexpr auto base = StringRef::from_lit("/b/c/d;p"); 8782c593315Sopenharmony_ci constexpr auto baseq = StringRef::from_lit("q"); 8792c593315Sopenharmony_ci { 8802c593315Sopenharmony_ci auto rel = StringRef::from_lit("g"); 8812c593315Sopenharmony_ci auto relq = StringRef{}; 8822c593315Sopenharmony_ci CU_ASSERT("/b/c/g" == http2::path_join(base, baseq, rel, relq)); 8832c593315Sopenharmony_ci } 8842c593315Sopenharmony_ci { 8852c593315Sopenharmony_ci auto rel = StringRef::from_lit("./g"); 8862c593315Sopenharmony_ci auto relq = StringRef{}; 8872c593315Sopenharmony_ci CU_ASSERT("/b/c/g" == http2::path_join(base, baseq, rel, relq)); 8882c593315Sopenharmony_ci } 8892c593315Sopenharmony_ci { 8902c593315Sopenharmony_ci auto rel = StringRef::from_lit("g/"); 8912c593315Sopenharmony_ci auto relq = StringRef{}; 8922c593315Sopenharmony_ci CU_ASSERT("/b/c/g/" == http2::path_join(base, baseq, rel, relq)); 8932c593315Sopenharmony_ci } 8942c593315Sopenharmony_ci { 8952c593315Sopenharmony_ci auto rel = StringRef::from_lit("/g"); 8962c593315Sopenharmony_ci auto relq = StringRef{}; 8972c593315Sopenharmony_ci CU_ASSERT("/g" == http2::path_join(base, baseq, rel, relq)); 8982c593315Sopenharmony_ci } 8992c593315Sopenharmony_ci { 9002c593315Sopenharmony_ci auto rel = StringRef{}; 9012c593315Sopenharmony_ci auto relq = StringRef::from_lit("y"); 9022c593315Sopenharmony_ci CU_ASSERT("/b/c/d;p?y" == http2::path_join(base, baseq, rel, relq)); 9032c593315Sopenharmony_ci } 9042c593315Sopenharmony_ci { 9052c593315Sopenharmony_ci auto rel = StringRef::from_lit("g"); 9062c593315Sopenharmony_ci auto relq = StringRef::from_lit("y"); 9072c593315Sopenharmony_ci CU_ASSERT("/b/c/g?y" == http2::path_join(base, baseq, rel, relq)); 9082c593315Sopenharmony_ci } 9092c593315Sopenharmony_ci { 9102c593315Sopenharmony_ci auto rel = StringRef::from_lit(";x"); 9112c593315Sopenharmony_ci auto relq = StringRef{}; 9122c593315Sopenharmony_ci CU_ASSERT("/b/c/;x" == http2::path_join(base, baseq, rel, relq)); 9132c593315Sopenharmony_ci } 9142c593315Sopenharmony_ci { 9152c593315Sopenharmony_ci auto rel = StringRef::from_lit("g;x"); 9162c593315Sopenharmony_ci auto relq = StringRef{}; 9172c593315Sopenharmony_ci CU_ASSERT("/b/c/g;x" == http2::path_join(base, baseq, rel, relq)); 9182c593315Sopenharmony_ci } 9192c593315Sopenharmony_ci { 9202c593315Sopenharmony_ci auto rel = StringRef::from_lit("g;x"); 9212c593315Sopenharmony_ci auto relq = StringRef::from_lit("y"); 9222c593315Sopenharmony_ci CU_ASSERT("/b/c/g;x?y" == http2::path_join(base, baseq, rel, relq)); 9232c593315Sopenharmony_ci } 9242c593315Sopenharmony_ci { 9252c593315Sopenharmony_ci auto rel = StringRef{}; 9262c593315Sopenharmony_ci auto relq = StringRef{}; 9272c593315Sopenharmony_ci CU_ASSERT("/b/c/d;p?q" == http2::path_join(base, baseq, rel, relq)); 9282c593315Sopenharmony_ci } 9292c593315Sopenharmony_ci { 9302c593315Sopenharmony_ci auto rel = StringRef::from_lit("."); 9312c593315Sopenharmony_ci auto relq = StringRef{}; 9322c593315Sopenharmony_ci CU_ASSERT("/b/c/" == http2::path_join(base, baseq, rel, relq)); 9332c593315Sopenharmony_ci } 9342c593315Sopenharmony_ci { 9352c593315Sopenharmony_ci auto rel = StringRef::from_lit("./"); 9362c593315Sopenharmony_ci auto relq = StringRef{}; 9372c593315Sopenharmony_ci CU_ASSERT("/b/c/" == http2::path_join(base, baseq, rel, relq)); 9382c593315Sopenharmony_ci } 9392c593315Sopenharmony_ci { 9402c593315Sopenharmony_ci auto rel = StringRef::from_lit(".."); 9412c593315Sopenharmony_ci auto relq = StringRef{}; 9422c593315Sopenharmony_ci CU_ASSERT("/b/" == http2::path_join(base, baseq, rel, relq)); 9432c593315Sopenharmony_ci } 9442c593315Sopenharmony_ci { 9452c593315Sopenharmony_ci auto rel = StringRef::from_lit("../"); 9462c593315Sopenharmony_ci auto relq = StringRef{}; 9472c593315Sopenharmony_ci CU_ASSERT("/b/" == http2::path_join(base, baseq, rel, relq)); 9482c593315Sopenharmony_ci } 9492c593315Sopenharmony_ci { 9502c593315Sopenharmony_ci auto rel = StringRef::from_lit("../g"); 9512c593315Sopenharmony_ci auto relq = StringRef{}; 9522c593315Sopenharmony_ci CU_ASSERT("/b/g" == http2::path_join(base, baseq, rel, relq)); 9532c593315Sopenharmony_ci } 9542c593315Sopenharmony_ci { 9552c593315Sopenharmony_ci auto rel = StringRef::from_lit("../.."); 9562c593315Sopenharmony_ci auto relq = StringRef{}; 9572c593315Sopenharmony_ci CU_ASSERT("/" == http2::path_join(base, baseq, rel, relq)); 9582c593315Sopenharmony_ci } 9592c593315Sopenharmony_ci { 9602c593315Sopenharmony_ci auto rel = StringRef::from_lit("../../"); 9612c593315Sopenharmony_ci auto relq = StringRef{}; 9622c593315Sopenharmony_ci CU_ASSERT("/" == http2::path_join(base, baseq, rel, relq)); 9632c593315Sopenharmony_ci } 9642c593315Sopenharmony_ci { 9652c593315Sopenharmony_ci auto rel = StringRef::from_lit("../../g"); 9662c593315Sopenharmony_ci auto relq = StringRef{}; 9672c593315Sopenharmony_ci CU_ASSERT("/g" == http2::path_join(base, baseq, rel, relq)); 9682c593315Sopenharmony_ci } 9692c593315Sopenharmony_ci { 9702c593315Sopenharmony_ci auto rel = StringRef::from_lit("../../../g"); 9712c593315Sopenharmony_ci auto relq = StringRef{}; 9722c593315Sopenharmony_ci CU_ASSERT("/g" == http2::path_join(base, baseq, rel, relq)); 9732c593315Sopenharmony_ci } 9742c593315Sopenharmony_ci { 9752c593315Sopenharmony_ci auto rel = StringRef::from_lit("../../../../g"); 9762c593315Sopenharmony_ci auto relq = StringRef{}; 9772c593315Sopenharmony_ci CU_ASSERT("/g" == http2::path_join(base, baseq, rel, relq)); 9782c593315Sopenharmony_ci } 9792c593315Sopenharmony_ci { 9802c593315Sopenharmony_ci auto rel = StringRef::from_lit("/./g"); 9812c593315Sopenharmony_ci auto relq = StringRef{}; 9822c593315Sopenharmony_ci CU_ASSERT("/g" == http2::path_join(base, baseq, rel, relq)); 9832c593315Sopenharmony_ci } 9842c593315Sopenharmony_ci { 9852c593315Sopenharmony_ci auto rel = StringRef::from_lit("/../g"); 9862c593315Sopenharmony_ci auto relq = StringRef{}; 9872c593315Sopenharmony_ci CU_ASSERT("/g" == http2::path_join(base, baseq, rel, relq)); 9882c593315Sopenharmony_ci } 9892c593315Sopenharmony_ci { 9902c593315Sopenharmony_ci auto rel = StringRef::from_lit("g."); 9912c593315Sopenharmony_ci auto relq = StringRef{}; 9922c593315Sopenharmony_ci CU_ASSERT("/b/c/g." == http2::path_join(base, baseq, rel, relq)); 9932c593315Sopenharmony_ci } 9942c593315Sopenharmony_ci { 9952c593315Sopenharmony_ci auto rel = StringRef::from_lit(".g"); 9962c593315Sopenharmony_ci auto relq = StringRef{}; 9972c593315Sopenharmony_ci CU_ASSERT("/b/c/.g" == http2::path_join(base, baseq, rel, relq)); 9982c593315Sopenharmony_ci } 9992c593315Sopenharmony_ci { 10002c593315Sopenharmony_ci auto rel = StringRef::from_lit("g.."); 10012c593315Sopenharmony_ci auto relq = StringRef{}; 10022c593315Sopenharmony_ci CU_ASSERT("/b/c/g.." == http2::path_join(base, baseq, rel, relq)); 10032c593315Sopenharmony_ci } 10042c593315Sopenharmony_ci { 10052c593315Sopenharmony_ci auto rel = StringRef::from_lit("..g"); 10062c593315Sopenharmony_ci auto relq = StringRef{}; 10072c593315Sopenharmony_ci CU_ASSERT("/b/c/..g" == http2::path_join(base, baseq, rel, relq)); 10082c593315Sopenharmony_ci } 10092c593315Sopenharmony_ci { 10102c593315Sopenharmony_ci auto rel = StringRef::from_lit("./../g"); 10112c593315Sopenharmony_ci auto relq = StringRef{}; 10122c593315Sopenharmony_ci CU_ASSERT("/b/g" == http2::path_join(base, baseq, rel, relq)); 10132c593315Sopenharmony_ci } 10142c593315Sopenharmony_ci { 10152c593315Sopenharmony_ci auto rel = StringRef::from_lit("./g/."); 10162c593315Sopenharmony_ci auto relq = StringRef{}; 10172c593315Sopenharmony_ci CU_ASSERT("/b/c/g/" == http2::path_join(base, baseq, rel, relq)); 10182c593315Sopenharmony_ci } 10192c593315Sopenharmony_ci { 10202c593315Sopenharmony_ci auto rel = StringRef::from_lit("g/./h"); 10212c593315Sopenharmony_ci auto relq = StringRef{}; 10222c593315Sopenharmony_ci CU_ASSERT("/b/c/g/h" == http2::path_join(base, baseq, rel, relq)); 10232c593315Sopenharmony_ci } 10242c593315Sopenharmony_ci { 10252c593315Sopenharmony_ci auto rel = StringRef::from_lit("g/../h"); 10262c593315Sopenharmony_ci auto relq = StringRef{}; 10272c593315Sopenharmony_ci CU_ASSERT("/b/c/h" == http2::path_join(base, baseq, rel, relq)); 10282c593315Sopenharmony_ci } 10292c593315Sopenharmony_ci { 10302c593315Sopenharmony_ci auto rel = StringRef::from_lit("g;x=1/./y"); 10312c593315Sopenharmony_ci auto relq = StringRef{}; 10322c593315Sopenharmony_ci CU_ASSERT("/b/c/g;x=1/y" == http2::path_join(base, baseq, rel, relq)); 10332c593315Sopenharmony_ci } 10342c593315Sopenharmony_ci { 10352c593315Sopenharmony_ci auto rel = StringRef::from_lit("g;x=1/../y"); 10362c593315Sopenharmony_ci auto relq = StringRef{}; 10372c593315Sopenharmony_ci CU_ASSERT("/b/c/y" == http2::path_join(base, baseq, rel, relq)); 10382c593315Sopenharmony_ci } 10392c593315Sopenharmony_ci} 10402c593315Sopenharmony_ci 10412c593315Sopenharmony_civoid test_http2_normalize_path(void) { 10422c593315Sopenharmony_ci CU_ASSERT("/alpha/charlie" == 10432c593315Sopenharmony_ci http2::normalize_path( 10442c593315Sopenharmony_ci StringRef::from_lit("/alpha/bravo/../charlie"), StringRef{})); 10452c593315Sopenharmony_ci 10462c593315Sopenharmony_ci CU_ASSERT("/alpha" == 10472c593315Sopenharmony_ci http2::normalize_path(StringRef::from_lit("/a%6c%70%68%61"), 10482c593315Sopenharmony_ci StringRef{})); 10492c593315Sopenharmony_ci 10502c593315Sopenharmony_ci CU_ASSERT( 10512c593315Sopenharmony_ci "/alpha%2F%3A" == 10522c593315Sopenharmony_ci http2::normalize_path(StringRef::from_lit("/alpha%2f%3a"), StringRef{})); 10532c593315Sopenharmony_ci 10542c593315Sopenharmony_ci CU_ASSERT("/%2F" == 10552c593315Sopenharmony_ci http2::normalize_path(StringRef::from_lit("%2f"), StringRef{})); 10562c593315Sopenharmony_ci 10572c593315Sopenharmony_ci CU_ASSERT("/%f" == 10582c593315Sopenharmony_ci http2::normalize_path(StringRef::from_lit("%f"), StringRef{})); 10592c593315Sopenharmony_ci 10602c593315Sopenharmony_ci CU_ASSERT("/%" == 10612c593315Sopenharmony_ci http2::normalize_path(StringRef::from_lit("%"), StringRef{})); 10622c593315Sopenharmony_ci 10632c593315Sopenharmony_ci CU_ASSERT("/" == http2::normalize_path(StringRef{}, StringRef{})); 10642c593315Sopenharmony_ci 10652c593315Sopenharmony_ci CU_ASSERT("/alpha?bravo" == 10662c593315Sopenharmony_ci http2::normalize_path(StringRef::from_lit("/alpha"), 10672c593315Sopenharmony_ci StringRef::from_lit("bravo"))); 10682c593315Sopenharmony_ci} 10692c593315Sopenharmony_ci 10702c593315Sopenharmony_civoid test_http2_rewrite_clean_path(void) { 10712c593315Sopenharmony_ci BlockAllocator balloc(4096, 4096); 10722c593315Sopenharmony_ci 10732c593315Sopenharmony_ci // unreserved characters 10742c593315Sopenharmony_ci CU_ASSERT("/alpha/bravo/" == 10752c593315Sopenharmony_ci http2::rewrite_clean_path(balloc, 10762c593315Sopenharmony_ci StringRef::from_lit("/alpha/%62ravo/"))); 10772c593315Sopenharmony_ci 10782c593315Sopenharmony_ci // percent-encoding is converted to upper case. 10792c593315Sopenharmony_ci CU_ASSERT("/delta%3A" == http2::rewrite_clean_path( 10802c593315Sopenharmony_ci balloc, StringRef::from_lit("/delta%3a"))); 10812c593315Sopenharmony_ci 10822c593315Sopenharmony_ci // path component is normalized before matching 10832c593315Sopenharmony_ci CU_ASSERT( 10842c593315Sopenharmony_ci "/alpha/bravo/" == 10852c593315Sopenharmony_ci http2::rewrite_clean_path( 10862c593315Sopenharmony_ci balloc, StringRef::from_lit("/alpha/charlie/%2e././bravo/delta/.."))); 10872c593315Sopenharmony_ci 10882c593315Sopenharmony_ci CU_ASSERT("alpha%3a" == 10892c593315Sopenharmony_ci http2::rewrite_clean_path(balloc, StringRef::from_lit("alpha%3a"))); 10902c593315Sopenharmony_ci 10912c593315Sopenharmony_ci CU_ASSERT("" == http2::rewrite_clean_path(balloc, StringRef{})); 10922c593315Sopenharmony_ci 10932c593315Sopenharmony_ci CU_ASSERT( 10942c593315Sopenharmony_ci "/alpha?bravo" == 10952c593315Sopenharmony_ci http2::rewrite_clean_path(balloc, StringRef::from_lit("//alpha?bravo"))); 10962c593315Sopenharmony_ci} 10972c593315Sopenharmony_ci 10982c593315Sopenharmony_civoid test_http2_get_pure_path_component(void) { 10992c593315Sopenharmony_ci CU_ASSERT("/" == http2::get_pure_path_component(StringRef::from_lit("/"))); 11002c593315Sopenharmony_ci 11012c593315Sopenharmony_ci CU_ASSERT("/foo" == 11022c593315Sopenharmony_ci http2::get_pure_path_component(StringRef::from_lit("/foo"))); 11032c593315Sopenharmony_ci 11042c593315Sopenharmony_ci CU_ASSERT("/bar" == http2::get_pure_path_component( 11052c593315Sopenharmony_ci StringRef::from_lit("https://example.org/bar"))); 11062c593315Sopenharmony_ci 11072c593315Sopenharmony_ci CU_ASSERT("/alpha" == http2::get_pure_path_component(StringRef::from_lit( 11082c593315Sopenharmony_ci "https://example.org/alpha?q=a"))); 11092c593315Sopenharmony_ci 11102c593315Sopenharmony_ci CU_ASSERT("/bravo" == http2::get_pure_path_component(StringRef::from_lit( 11112c593315Sopenharmony_ci "https://example.org/bravo?q=a#fragment"))); 11122c593315Sopenharmony_ci 11132c593315Sopenharmony_ci CU_ASSERT("" == 11142c593315Sopenharmony_ci http2::get_pure_path_component(StringRef::from_lit("\x01\x02"))); 11152c593315Sopenharmony_ci} 11162c593315Sopenharmony_ci 11172c593315Sopenharmony_civoid test_http2_construct_push_component(void) { 11182c593315Sopenharmony_ci BlockAllocator balloc(4096, 4096); 11192c593315Sopenharmony_ci StringRef base, uri; 11202c593315Sopenharmony_ci StringRef scheme, authority, path; 11212c593315Sopenharmony_ci 11222c593315Sopenharmony_ci base = StringRef::from_lit("/b/"); 11232c593315Sopenharmony_ci uri = StringRef::from_lit("https://example.org/foo"); 11242c593315Sopenharmony_ci 11252c593315Sopenharmony_ci CU_ASSERT(0 == http2::construct_push_component(balloc, scheme, authority, 11262c593315Sopenharmony_ci path, base, uri)); 11272c593315Sopenharmony_ci CU_ASSERT("https" == scheme); 11282c593315Sopenharmony_ci CU_ASSERT("example.org" == authority); 11292c593315Sopenharmony_ci CU_ASSERT("/foo" == path); 11302c593315Sopenharmony_ci 11312c593315Sopenharmony_ci scheme = StringRef{}; 11322c593315Sopenharmony_ci authority = StringRef{}; 11332c593315Sopenharmony_ci path = StringRef{}; 11342c593315Sopenharmony_ci 11352c593315Sopenharmony_ci uri = StringRef::from_lit("/foo/bar?q=a"); 11362c593315Sopenharmony_ci 11372c593315Sopenharmony_ci CU_ASSERT(0 == http2::construct_push_component(balloc, scheme, authority, 11382c593315Sopenharmony_ci path, base, uri)); 11392c593315Sopenharmony_ci CU_ASSERT("" == scheme); 11402c593315Sopenharmony_ci CU_ASSERT("" == authority); 11412c593315Sopenharmony_ci CU_ASSERT("/foo/bar?q=a" == path); 11422c593315Sopenharmony_ci 11432c593315Sopenharmony_ci scheme = StringRef{}; 11442c593315Sopenharmony_ci authority = StringRef{}; 11452c593315Sopenharmony_ci path = StringRef{}; 11462c593315Sopenharmony_ci 11472c593315Sopenharmony_ci uri = StringRef::from_lit("foo/../bar?q=a"); 11482c593315Sopenharmony_ci 11492c593315Sopenharmony_ci CU_ASSERT(0 == http2::construct_push_component(balloc, scheme, authority, 11502c593315Sopenharmony_ci path, base, uri)); 11512c593315Sopenharmony_ci CU_ASSERT("" == scheme); 11522c593315Sopenharmony_ci CU_ASSERT("" == authority); 11532c593315Sopenharmony_ci CU_ASSERT("/b/bar?q=a" == path); 11542c593315Sopenharmony_ci 11552c593315Sopenharmony_ci scheme = StringRef{}; 11562c593315Sopenharmony_ci authority = StringRef{}; 11572c593315Sopenharmony_ci path = StringRef{}; 11582c593315Sopenharmony_ci 11592c593315Sopenharmony_ci uri = StringRef{}; 11602c593315Sopenharmony_ci 11612c593315Sopenharmony_ci CU_ASSERT(-1 == http2::construct_push_component(balloc, scheme, authority, 11622c593315Sopenharmony_ci path, base, uri)); 11632c593315Sopenharmony_ci scheme = StringRef{}; 11642c593315Sopenharmony_ci authority = StringRef{}; 11652c593315Sopenharmony_ci path = StringRef{}; 11662c593315Sopenharmony_ci 11672c593315Sopenharmony_ci uri = StringRef::from_lit("?q=a"); 11682c593315Sopenharmony_ci 11692c593315Sopenharmony_ci CU_ASSERT(0 == http2::construct_push_component(balloc, scheme, authority, 11702c593315Sopenharmony_ci path, base, uri)); 11712c593315Sopenharmony_ci CU_ASSERT("" == scheme); 11722c593315Sopenharmony_ci CU_ASSERT("" == authority); 11732c593315Sopenharmony_ci CU_ASSERT("/b/?q=a" == path); 11742c593315Sopenharmony_ci} 11752c593315Sopenharmony_ci 11762c593315Sopenharmony_civoid test_http2_contains_trailers(void) { 11772c593315Sopenharmony_ci CU_ASSERT(!http2::contains_trailers(StringRef::from_lit(""))); 11782c593315Sopenharmony_ci CU_ASSERT(http2::contains_trailers(StringRef::from_lit("trailers"))); 11792c593315Sopenharmony_ci // Match must be case-insensitive. 11802c593315Sopenharmony_ci CU_ASSERT(http2::contains_trailers(StringRef::from_lit("TRAILERS"))); 11812c593315Sopenharmony_ci CU_ASSERT(!http2::contains_trailers(StringRef::from_lit("trailer"))); 11822c593315Sopenharmony_ci CU_ASSERT(!http2::contains_trailers(StringRef::from_lit("trailers 3"))); 11832c593315Sopenharmony_ci CU_ASSERT(http2::contains_trailers(StringRef::from_lit("trailers,"))); 11842c593315Sopenharmony_ci CU_ASSERT(http2::contains_trailers(StringRef::from_lit("trailers,foo"))); 11852c593315Sopenharmony_ci CU_ASSERT(http2::contains_trailers(StringRef::from_lit("foo,trailers"))); 11862c593315Sopenharmony_ci CU_ASSERT(http2::contains_trailers(StringRef::from_lit("foo,trailers,bar"))); 11872c593315Sopenharmony_ci CU_ASSERT( 11882c593315Sopenharmony_ci http2::contains_trailers(StringRef::from_lit("foo, trailers ,bar"))); 11892c593315Sopenharmony_ci CU_ASSERT(http2::contains_trailers(StringRef::from_lit(",trailers"))); 11902c593315Sopenharmony_ci} 11912c593315Sopenharmony_ci 11922c593315Sopenharmony_civoid test_http2_check_transfer_encoding(void) { 11932c593315Sopenharmony_ci CU_ASSERT(http2::check_transfer_encoding(StringRef::from_lit("chunked"))); 11942c593315Sopenharmony_ci CU_ASSERT(http2::check_transfer_encoding(StringRef::from_lit("foo,chunked"))); 11952c593315Sopenharmony_ci CU_ASSERT( 11962c593315Sopenharmony_ci http2::check_transfer_encoding(StringRef::from_lit("foo, chunked"))); 11972c593315Sopenharmony_ci CU_ASSERT( 11982c593315Sopenharmony_ci http2::check_transfer_encoding(StringRef::from_lit("foo , chunked"))); 11992c593315Sopenharmony_ci CU_ASSERT( 12002c593315Sopenharmony_ci http2::check_transfer_encoding(StringRef::from_lit("chunked;foo=bar"))); 12012c593315Sopenharmony_ci CU_ASSERT( 12022c593315Sopenharmony_ci http2::check_transfer_encoding(StringRef::from_lit("chunked ; foo=bar"))); 12032c593315Sopenharmony_ci CU_ASSERT(http2::check_transfer_encoding( 12042c593315Sopenharmony_ci StringRef::from_lit(R"(chunked;foo="bar")"))); 12052c593315Sopenharmony_ci CU_ASSERT(http2::check_transfer_encoding( 12062c593315Sopenharmony_ci StringRef::from_lit(R"(chunked;foo="\bar\"";FOO=BAR)"))); 12072c593315Sopenharmony_ci CU_ASSERT( 12082c593315Sopenharmony_ci http2::check_transfer_encoding(StringRef::from_lit(R"(chunked;foo="")"))); 12092c593315Sopenharmony_ci CU_ASSERT(http2::check_transfer_encoding( 12102c593315Sopenharmony_ci StringRef::from_lit(R"(chunked;foo="bar" , gzip)"))); 12112c593315Sopenharmony_ci 12122c593315Sopenharmony_ci CU_ASSERT(!http2::check_transfer_encoding(StringRef{})); 12132c593315Sopenharmony_ci CU_ASSERT(!http2::check_transfer_encoding(StringRef::from_lit(",chunked"))); 12142c593315Sopenharmony_ci CU_ASSERT(!http2::check_transfer_encoding(StringRef::from_lit("chunked,"))); 12152c593315Sopenharmony_ci CU_ASSERT(!http2::check_transfer_encoding(StringRef::from_lit("chunked, "))); 12162c593315Sopenharmony_ci CU_ASSERT( 12172c593315Sopenharmony_ci !http2::check_transfer_encoding(StringRef::from_lit("foo,,chunked"))); 12182c593315Sopenharmony_ci CU_ASSERT( 12192c593315Sopenharmony_ci !http2::check_transfer_encoding(StringRef::from_lit("chunked;foo"))); 12202c593315Sopenharmony_ci CU_ASSERT(!http2::check_transfer_encoding(StringRef::from_lit("chunked;"))); 12212c593315Sopenharmony_ci CU_ASSERT( 12222c593315Sopenharmony_ci !http2::check_transfer_encoding(StringRef::from_lit("chunked;foo=bar;"))); 12232c593315Sopenharmony_ci CU_ASSERT( 12242c593315Sopenharmony_ci !http2::check_transfer_encoding(StringRef::from_lit("chunked;?=bar"))); 12252c593315Sopenharmony_ci CU_ASSERT( 12262c593315Sopenharmony_ci !http2::check_transfer_encoding(StringRef::from_lit("chunked;=bar"))); 12272c593315Sopenharmony_ci CU_ASSERT(!http2::check_transfer_encoding(StringRef::from_lit("chunked;;"))); 12282c593315Sopenharmony_ci CU_ASSERT(!http2::check_transfer_encoding(StringRef::from_lit("chunked?"))); 12292c593315Sopenharmony_ci CU_ASSERT(!http2::check_transfer_encoding(StringRef::from_lit(","))); 12302c593315Sopenharmony_ci CU_ASSERT(!http2::check_transfer_encoding(StringRef::from_lit(" "))); 12312c593315Sopenharmony_ci CU_ASSERT(!http2::check_transfer_encoding(StringRef::from_lit(";"))); 12322c593315Sopenharmony_ci CU_ASSERT(!http2::check_transfer_encoding(StringRef::from_lit("\""))); 12332c593315Sopenharmony_ci CU_ASSERT(!http2::check_transfer_encoding( 12342c593315Sopenharmony_ci StringRef::from_lit(R"(chunked;foo="bar)"))); 12352c593315Sopenharmony_ci CU_ASSERT(!http2::check_transfer_encoding( 12362c593315Sopenharmony_ci StringRef::from_lit(R"(chunked;foo="bar\)"))); 12372c593315Sopenharmony_ci CU_ASSERT( 12382c593315Sopenharmony_ci !http2::check_transfer_encoding(StringRef::from_lit(R"(chunked;foo="bar\)" 12392c593315Sopenharmony_ci "\x0a" 12402c593315Sopenharmony_ci R"(")"))); 12412c593315Sopenharmony_ci CU_ASSERT( 12422c593315Sopenharmony_ci !http2::check_transfer_encoding(StringRef::from_lit(R"(chunked;foo=")" 12432c593315Sopenharmony_ci "\x0a" 12442c593315Sopenharmony_ci R"(")"))); 12452c593315Sopenharmony_ci CU_ASSERT(!http2::check_transfer_encoding( 12462c593315Sopenharmony_ci StringRef::from_lit(R"(chunked;foo="bar",,gzip)"))); 12472c593315Sopenharmony_ci} 12482c593315Sopenharmony_ci 12492c593315Sopenharmony_ci} // namespace shrpx 1250