From be1c7e50e1e8809ea56f2c9d472eccd8ffd73a97 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Fri, 19 Apr 2024 04:57:58 +0200 Subject: Adding upstream version 1.44.3. Signed-off-by: Daniel Baumann --- web/server/h2o/libh2o/t/00unit/lib/common/url.c | 662 ++++++++++++++++++++++++ 1 file changed, 662 insertions(+) create mode 100644 web/server/h2o/libh2o/t/00unit/lib/common/url.c (limited to 'web/server/h2o/libh2o/t/00unit/lib/common/url.c') diff --git a/web/server/h2o/libh2o/t/00unit/lib/common/url.c b/web/server/h2o/libh2o/t/00unit/lib/common/url.c new file mode 100644 index 00000000..ce167600 --- /dev/null +++ b/web/server/h2o/libh2o/t/00unit/lib/common/url.c @@ -0,0 +1,662 @@ +/* + * Copyright (c) 2014,2015 DeNA Co., Ltd. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ +#include "../../test.h" +#include "../../../../lib/common/url.c" + +static void test_normalize_path(void) +{ + h2o_mem_pool_t pool; + + h2o_mem_init_pool(&pool); + + size_t q; + size_t *norm_indexes = NULL; + h2o_iovec_t input; + h2o_iovec_t b; + + input = h2o_iovec_init(NULL, 0); + b = h2o_url_normalize_path(&pool, input.base, input.len, &q, &norm_indexes); + ok(b.len == 1); + ok(memcmp(b.base, H2O_STRLIT("/")) == 0); + ok(q == SIZE_MAX); + ok(norm_indexes == NULL); + + input = h2o_iovec_init(H2O_STRLIT("a")); + b = h2o_url_normalize_path(&pool, input.base, input.len, &q, &norm_indexes); + ok(b.len == 2); + ok(memcmp(b.base, H2O_STRLIT("/a")) == 0); + ok(q == SIZE_MAX); + ok(norm_indexes != NULL); + ok(norm_indexes[0] == 0); + ok(norm_indexes[1] == 1); + norm_indexes = NULL; + + input = h2o_iovec_init(H2O_STRLIT("aa")); + b = h2o_url_normalize_path(&pool, input.base, input.len, &q, &norm_indexes); + ok(b.len == 3); + ok(memcmp(b.base, H2O_STRLIT("/aa")) == 0); + ok(q == SIZE_MAX); + ok(norm_indexes != NULL); + ok(norm_indexes[0] == 0); + ok(norm_indexes[1] == 1); + ok(norm_indexes[2] == 2); + norm_indexes = NULL; + + input = h2o_iovec_init(H2O_STRLIT("/")); + b = h2o_url_normalize_path(&pool, input.base, input.len, &q, &norm_indexes); + ok(b.len == 1); + ok(memcmp(b.base, H2O_STRLIT("/")) == 0); + ok(q == SIZE_MAX); + ok(norm_indexes == NULL); + + input = h2o_iovec_init(H2O_STRLIT("/.")); + b = h2o_url_normalize_path(&pool, input.base, input.len, &q, &norm_indexes); + ok(b.len == 1); + ok(memcmp(b.base, H2O_STRLIT("/")) == 0); + ok(q == SIZE_MAX); + ok(norm_indexes != NULL); + ok(norm_indexes[0] == 1); + norm_indexes = NULL; + + input = h2o_iovec_init(H2O_STRLIT("/./")); + b = h2o_url_normalize_path(&pool, input.base, input.len, &q, &norm_indexes); + ok(b.len == 1); + ok(memcmp(b.base, H2O_STRLIT("/")) == 0); + ok(q == SIZE_MAX); + ok(norm_indexes != NULL); + ok(norm_indexes[0] == 1); + norm_indexes = NULL; + + input = h2o_iovec_init(H2O_STRLIT("/..")); + b = h2o_url_normalize_path(&pool, input.base, input.len, &q, &norm_indexes); + ok(b.len == 1); + ok(memcmp(b.base, H2O_STRLIT("/")) == 0); + ok(q == SIZE_MAX); + ok(norm_indexes != NULL); + ok(norm_indexes[0] == 1); + norm_indexes = NULL; + + input = h2o_iovec_init(H2O_STRLIT("/../")); + b = h2o_url_normalize_path(&pool, input.base, input.len, &q, &norm_indexes); + ok(b.len == 1); + ok(memcmp(b.base, H2O_STRLIT("/")) == 0); + ok(q == SIZE_MAX); + ok(norm_indexes != NULL); + ok(norm_indexes[0] == 1); + norm_indexes = NULL; + + input = h2o_iovec_init(H2O_STRLIT("/abc")); + b = h2o_url_normalize_path(&pool, input.base, input.len, &q, &norm_indexes); + ok(b.len == 4); + ok(memcmp(b.base, H2O_STRLIT("/abc")) == 0); + ok(q == SIZE_MAX); + ok(norm_indexes == NULL); + + input = h2o_iovec_init(H2O_STRLIT("/abc")); + b = h2o_url_normalize_path(&pool, input.base, input.len, &q, &norm_indexes); + ok(b.len == 4); + ok(memcmp(b.base, H2O_STRLIT("/abc")) == 0); + ok(q == SIZE_MAX); + ok(norm_indexes == NULL); + + input = h2o_iovec_init(H2O_STRLIT("/abc/../def")); + b = h2o_url_normalize_path(&pool, input.base, input.len, &q, &norm_indexes); + ok(b.len == 4); + ok(memcmp(b.base, H2O_STRLIT("/def")) == 0); + ok(q == SIZE_MAX); + ok(norm_indexes != NULL); + ok(norm_indexes[0] == 1); + ok(norm_indexes[1] == 9); + ok(norm_indexes[2] == 10); + ok(norm_indexes[3] == 11); + norm_indexes = NULL; + + input = h2o_iovec_init(H2O_STRLIT("/abc/../../def")); + b = h2o_url_normalize_path(&pool, input.base, input.len, &q, &norm_indexes); + ok(b.len == 4); + ok(memcmp(b.base, H2O_STRLIT("/def")) == 0); + ok(q == SIZE_MAX); + ok(norm_indexes != NULL); + ok(norm_indexes[0] == 1); + ok(norm_indexes[1] == 12); + ok(norm_indexes[2] == 13); + ok(norm_indexes[3] == 14); + norm_indexes = NULL; + + input = h2o_iovec_init(H2O_STRLIT("/abc/./def")); + b = h2o_url_normalize_path(&pool, input.base, input.len, &q, &norm_indexes); + ok(b.len == 8); + ok(memcmp(b.base, H2O_STRLIT("/abc/def")) == 0); + ok(q == SIZE_MAX); + ok(norm_indexes != NULL); + ok(norm_indexes[0] == 1); + ok(norm_indexes[1] == 2); + ok(norm_indexes[2] == 3); + ok(norm_indexes[3] == 4); + ok(norm_indexes[4] == 5); + ok(norm_indexes[5] == 8); + ok(norm_indexes[6] == 9); + ok(norm_indexes[7] == 10); + norm_indexes = NULL; + + input = h2o_iovec_init(H2O_STRLIT("/abc/././def")); + b = h2o_url_normalize_path(&pool, input.base, input.len, &q, &norm_indexes); + ok(b.len == 8); + ok(memcmp(b.base, H2O_STRLIT("/abc/def")) == 0); + ok(q == SIZE_MAX); + ok(norm_indexes != NULL); + ok(norm_indexes[0] == 1); + ok(norm_indexes[1] == 2); + ok(norm_indexes[2] == 3); + ok(norm_indexes[3] == 4); + ok(norm_indexes[4] == 5); + ok(norm_indexes[5] == 10); + ok(norm_indexes[6] == 11); + ok(norm_indexes[7] == 12); + norm_indexes = NULL; + + input = h2o_iovec_init(H2O_STRLIT("/abc/def/ghi/../..")); + b = h2o_url_normalize_path(&pool, input.base, input.len, &q, &norm_indexes); + ok(b.len == 5); + ok(memcmp(b.base, H2O_STRLIT("/abc/")) == 0); + ok(q == SIZE_MAX); + ok(norm_indexes != NULL); + ok(norm_indexes[0] == 1); + ok(norm_indexes[1] == 2); + ok(norm_indexes[2] == 3); + ok(norm_indexes[3] == 4); + ok(norm_indexes[4] == 5); + norm_indexes = NULL; + + input = h2o_iovec_init(H2O_STRLIT("/abc/def/./.")); + b = h2o_url_normalize_path(&pool, input.base, input.len, &q, &norm_indexes); + ok(b.len == 9); + ok(memcmp(b.base, H2O_STRLIT("/abc/def/")) == 0); + ok(q == SIZE_MAX); + ok(norm_indexes != NULL); + ok(norm_indexes[0] == 1); + ok(norm_indexes[1] == 2); + ok(norm_indexes[2] == 3); + ok(norm_indexes[3] == 4); + ok(norm_indexes[4] == 5); + ok(norm_indexes[5] == 6); + ok(norm_indexes[6] == 7); + ok(norm_indexes[7] == 8); + norm_indexes = NULL; + + input = h2o_iovec_init(H2O_STRLIT("/abc/def/ghi/../.")); + b = h2o_url_normalize_path(&pool, input.base, input.len, &q, &norm_indexes); + ok(b.len == 9); + ok(memcmp(b.base, H2O_STRLIT("/abc/def/")) == 0); + ok(q == SIZE_MAX); + ok(norm_indexes != NULL); + ok(norm_indexes[0] == 1); + ok(norm_indexes[1] == 2); + ok(norm_indexes[2] == 3); + ok(norm_indexes[3] == 4); + ok(norm_indexes[4] == 5); + ok(norm_indexes[5] == 6); + ok(norm_indexes[6] == 7); + ok(norm_indexes[7] == 8); + norm_indexes = NULL; + + input = h2o_iovec_init(H2O_STRLIT("/abc/def/./..")); + b = h2o_url_normalize_path(&pool, input.base, input.len, &q, &norm_indexes); + ok(b.len == 5); + ok(memcmp(b.base, H2O_STRLIT("/abc/")) == 0); + ok(q == SIZE_MAX); + ok(norm_indexes != NULL); + ok(norm_indexes[0] == 1); + ok(norm_indexes[1] == 2); + ok(norm_indexes[2] == 3); + ok(norm_indexes[3] == 4); + ok(norm_indexes[4] == 5); + norm_indexes = NULL; + + input = h2o_iovec_init(H2O_STRLIT("/abc/def/..")); + b = h2o_url_normalize_path(&pool, input.base, input.len, &q, &norm_indexes); + ok(b.len == 5); + ok(memcmp(b.base, H2O_STRLIT("/abc/")) == 0); + ok(q == SIZE_MAX); + ok(norm_indexes != NULL); + ok(norm_indexes[0] == 1); + ok(norm_indexes[1] == 2); + ok(norm_indexes[2] == 3); + ok(norm_indexes[3] == 4); + ok(norm_indexes[4] == 5); + norm_indexes = NULL; + + input = h2o_iovec_init(H2O_STRLIT("/abc/def/.")); + b = h2o_url_normalize_path(&pool, input.base, input.len, &q, &norm_indexes); + ok(b.len == 9); + ok(memcmp(b.base, H2O_STRLIT("/abc/def/")) == 0); + ok(q == SIZE_MAX); + ok(norm_indexes != NULL); + ok(norm_indexes[0] == 1); + ok(norm_indexes[1] == 2); + ok(norm_indexes[2] == 3); + ok(norm_indexes[3] == 4); + ok(norm_indexes[4] == 5); + ok(norm_indexes[5] == 6); + ok(norm_indexes[6] == 7); + norm_indexes = NULL; + + input = h2o_iovec_init(H2O_STRLIT("/abc?xx")); + b = h2o_url_normalize_path(&pool, input.base, input.len, &q, &norm_indexes); + ok(b.len == 4); + ok(memcmp(b.base, H2O_STRLIT("/abc")) == 0); + ok(q == 4); + ok(norm_indexes == NULL); + + input = h2o_iovec_init(H2O_STRLIT("/abc/../def?xx")); + b = h2o_url_normalize_path(&pool, input.base, input.len, &q, &norm_indexes); + ok(b.len == 4); + ok(memcmp(b.base, H2O_STRLIT("/def")) == 0); + ok(q == 11); + ok(norm_indexes != NULL); + ok(norm_indexes[0] == 1); + ok(norm_indexes[1] == 9); + ok(norm_indexes[2] == 10); + ok(norm_indexes[3] == 11); + norm_indexes = NULL; + + input = h2o_iovec_init(H2O_STRLIT("/a%62c")); + b = h2o_url_normalize_path(&pool, input.base, input.len, &q, &norm_indexes); + ok(b.len == 4); + ok(memcmp(b.base, H2O_STRLIT("/abc")) == 0); + ok(q == SIZE_MAX); + ok(norm_indexes != NULL); + ok(norm_indexes[0] == 1); + ok(norm_indexes[1] == 2); + ok(norm_indexes[2] == 5); + ok(norm_indexes[3] == 6); + norm_indexes = NULL; + + input = h2o_iovec_init(H2O_STRLIT("/a%6")); + b = h2o_url_normalize_path(&pool, input.base, input.len, &q, &norm_indexes); + ok(b.len == 4); + ok(memcmp(b.base, H2O_STRLIT("/a%6")) == 0); + ok(q == SIZE_MAX); + ok(norm_indexes != NULL); + ok(norm_indexes[0] == 1); + ok(norm_indexes[1] == 2); + ok(norm_indexes[2] == 3); + ok(norm_indexes[3] == 4); + norm_indexes = NULL; + + input = h2o_iovec_init(H2O_STRLIT("/a%6?")); + b = h2o_url_normalize_path(&pool, input.base, input.len, &q, &norm_indexes); + ok(b.len == 4); + ok(memcmp(b.base, H2O_STRLIT("/a%6")) == 0); + ok(q == 4); + ok(norm_indexes != NULL); + ok(norm_indexes[0] == 1); + ok(norm_indexes[1] == 2); + ok(norm_indexes[2] == 3); + ok(norm_indexes[3] == 4); + norm_indexes = NULL; + + input = h2o_iovec_init(H2O_STRLIT("/%25")); + b = h2o_url_normalize_path(&pool, input.base, input.len, &q, &norm_indexes); + ok(b.len == 2); + ok(memcmp(b.base, H2O_STRLIT("/%")) == 0); + ok(q == SIZE_MAX); + ok(norm_indexes != NULL); + ok(norm_indexes[0] == 1); + ok(norm_indexes[1] == 4); + norm_indexes = NULL; + + input = h2o_iovec_init(H2O_STRLIT("/abc//")); + b = h2o_url_normalize_path(&pool, input.base, input.len, &q, &norm_indexes); + ok(b.len == 6); + ok(memcmp(b.base, H2O_STRLIT("/abc//")) == 0); + ok(q == SIZE_MAX); + ok(norm_indexes == NULL); + + input = h2o_iovec_init(H2O_STRLIT("/abc//d")); + b = h2o_url_normalize_path(&pool, input.base, input.len, &q, &norm_indexes); + ok(b.len == 7); + ok(memcmp(b.base, H2O_STRLIT("/abc//d")) == 0); + ok(q == SIZE_MAX); + ok(norm_indexes == NULL); + + input = h2o_iovec_init(H2O_STRLIT("//")); + b = h2o_url_normalize_path(&pool, input.base, input.len, &q, &norm_indexes); + ok(b.len == 2); + ok(memcmp(b.base, H2O_STRLIT("//")) == 0); + ok(q == SIZE_MAX); + ok(norm_indexes == NULL); + + input = h2o_iovec_init(H2O_STRLIT("//abc")); + b = h2o_url_normalize_path(&pool, input.base, input.len, &q, &norm_indexes); + ok(b.len == 5); + ok(memcmp(b.base, H2O_STRLIT("//abc")) == 0); + ok(q == SIZE_MAX); + ok(norm_indexes == NULL); + + h2o_mem_clear_pool(&pool); +} + +static void test_hostport(void) +{ + h2o_iovec_t input, host; + uint16_t port; + const char *ret; + + input = h2o_iovec_init(H2O_STRLIT("127.0.0.1")); + ret = h2o_url_parse_hostport(input.base, input.len, &host, &port); + ok(ret == input.base + input.len); + ok(h2o_memis(host.base, host.len, H2O_STRLIT("127.0.0.1"))); + ok(port == 65535); + + input = h2o_iovec_init(H2O_STRLIT("127.0.0.1/")); + ret = h2o_url_parse_hostport(input.base, input.len, &host, &port); + ok(strcmp(ret, "/") == 0); + ok(h2o_memis(host.base, host.len, H2O_STRLIT("127.0.0.1"))); + ok(port == 65535); + + input = h2o_iovec_init(H2O_STRLIT("127.0.0.1:8081/")); + ret = h2o_url_parse_hostport(input.base, input.len, &host, &port); + ok(strcmp(ret, "/") == 0); + ok(h2o_memis(host.base, host.len, H2O_STRLIT("127.0.0.1"))); + ok(port == 8081); + + input = h2o_iovec_init(H2O_STRLIT("[::ffff:192.0.2.1]:8081/")); + ret = h2o_url_parse_hostport(input.base, input.len, &host, &port); + ok(strcmp(ret, "/") == 0); + ok(h2o_memis(host.base, host.len, H2O_STRLIT("::ffff:192.0.2.1"))); + ok(port == 8081); + + input = h2o_iovec_init(H2O_STRLIT("[::ffff:192.0.2.1:8081/")); + ret = h2o_url_parse_hostport(input.base, input.len, &host, &port); + ok(ret == NULL); + + input = h2o_iovec_init(H2O_STRLIT(":8081/")); + ret = h2o_url_parse_hostport(input.base, input.len, &host, &port); + ok(ret == NULL); + + input = h2o_iovec_init(H2O_STRLIT("[]:8081/")); + ret = h2o_url_parse_hostport(input.base, input.len, &host, &port); + ok(ret == NULL); +} + +static void test_parse(void) +{ + h2o_url_t parsed; + int ret; + + ret = h2o_url_parse("http://example.com/abc", SIZE_MAX, &parsed); + ok(ret == 0); + ok(parsed.scheme == &H2O_URL_SCHEME_HTTP); + ok(h2o_memis(parsed.authority.base, parsed.authority.len, H2O_STRLIT("example.com"))); + ok(h2o_memis(parsed.host.base, parsed.host.len, H2O_STRLIT("example.com"))); + ok(parsed._port == 65535); + ok(h2o_url_get_port(&parsed) == 80); + ok(h2o_memis(parsed.path.base, parsed.path.len, H2O_STRLIT("/abc"))); + + ret = h2o_url_parse("http://example.com", SIZE_MAX, &parsed); + ok(ret == 0); + ok(parsed.scheme == &H2O_URL_SCHEME_HTTP); + ok(h2o_memis(parsed.authority.base, parsed.authority.len, H2O_STRLIT("example.com"))); + ok(h2o_memis(parsed.host.base, parsed.host.len, H2O_STRLIT("example.com"))); + ok(parsed._port == 65535); + ok(h2o_url_get_port(&parsed) == 80); + ok(h2o_memis(parsed.path.base, parsed.path.len, H2O_STRLIT("/"))); + + ret = h2o_url_parse("http://example.com:81/abc", SIZE_MAX, &parsed); + ok(ret == 0); + ok(parsed.scheme == &H2O_URL_SCHEME_HTTP); + ok(h2o_memis(parsed.authority.base, parsed.authority.len, H2O_STRLIT("example.com:81"))); + ok(h2o_memis(parsed.host.base, parsed.host.len, H2O_STRLIT("example.com"))); + ok(parsed._port == 81); + ok(h2o_url_get_port(&parsed) == 81); + ok(h2o_memis(parsed.path.base, parsed.path.len, H2O_STRLIT("/abc"))); + + ret = h2o_url_parse("http://example.com:81", SIZE_MAX, &parsed); + ok(ret == 0); + ok(parsed.scheme == &H2O_URL_SCHEME_HTTP); + ok(h2o_memis(parsed.authority.base, parsed.authority.len, H2O_STRLIT("example.com:81"))); + ok(h2o_memis(parsed.host.base, parsed.host.len, H2O_STRLIT("example.com"))); + ok(parsed._port == 81); + ok(h2o_url_get_port(&parsed) == 81); + ok(h2o_memis(parsed.path.base, parsed.path.len, H2O_STRLIT("/"))); + + ret = h2o_url_parse("https://example.com/abc", SIZE_MAX, &parsed); + ok(ret == 0); + ok(parsed.scheme == &H2O_URL_SCHEME_HTTPS); + ok(h2o_memis(parsed.authority.base, parsed.authority.len, H2O_STRLIT("example.com"))); + ok(h2o_memis(parsed.host.base, parsed.host.len, H2O_STRLIT("example.com"))); + ok(parsed._port == 65535); + ok(h2o_url_get_port(&parsed) == 443); + ok(h2o_memis(parsed.path.base, parsed.path.len, H2O_STRLIT("/abc"))); + + ret = h2o_url_parse("http:/abc", SIZE_MAX, &parsed); + ok(ret != 0); + + ret = h2o_url_parse("ftp://example.com/abc", SIZE_MAX, &parsed); + ok(ret != 0); + + ret = h2o_url_parse("http://abc:111111/def", SIZE_MAX, &parsed); + ok(ret != 0); + + ret = h2o_url_parse("http://[::ffff:192.0.2.128]", SIZE_MAX, &parsed); + ok(ret == 0); + ok(parsed.scheme == &H2O_URL_SCHEME_HTTP); + ok(h2o_memis(parsed.authority.base, parsed.authority.len, H2O_STRLIT("[::ffff:192.0.2.128]"))); + ok(h2o_memis(parsed.host.base, parsed.host.len, H2O_STRLIT("::ffff:192.0.2.128"))); + ok(parsed._port == 65535); + ok(h2o_url_get_port(&parsed) == 80); + ok(h2o_memis(parsed.path.base, parsed.path.len, H2O_STRLIT("/"))); + + ret = h2o_url_parse("https://[::ffff:192.0.2.128]/abc", SIZE_MAX, &parsed); + ok(ret == 0); + ok(parsed.scheme == &H2O_URL_SCHEME_HTTPS); + ok(h2o_memis(parsed.authority.base, parsed.authority.len, H2O_STRLIT("[::ffff:192.0.2.128]"))); + ok(h2o_memis(parsed.host.base, parsed.host.len, H2O_STRLIT("::ffff:192.0.2.128"))); + ok(parsed._port == 65535); + ok(h2o_url_get_port(&parsed) == 443); + ok(h2o_memis(parsed.path.base, parsed.path.len, H2O_STRLIT("/abc"))); + + ret = h2o_url_parse("https://[::ffff:192.0.2.128]:111/abc", SIZE_MAX, &parsed); + ok(ret == 0); + ok(parsed.scheme == &H2O_URL_SCHEME_HTTPS); + ok(h2o_memis(parsed.authority.base, parsed.authority.len, H2O_STRLIT("[::ffff:192.0.2.128]:111"))); + ok(h2o_memis(parsed.host.base, parsed.host.len, H2O_STRLIT("::ffff:192.0.2.128"))); + ok(parsed._port == 111); + ok(h2o_url_get_port(&parsed) == 111); + ok(h2o_memis(parsed.path.base, parsed.path.len, H2O_STRLIT("/abc"))); +} + +static void test_parse_relative(void) +{ + h2o_url_t parsed; + int ret; + + memset(&parsed, 0x55, sizeof(parsed)); + ret = h2o_url_parse_relative("abc", SIZE_MAX, &parsed); + ok(ret == 0); + ok(parsed.scheme == NULL); + ok(parsed.authority.base == NULL); + ok(parsed.host.base == NULL); + ok(parsed._port == 65535); + ok(h2o_memis(parsed.path.base, parsed.path.len, H2O_STRLIT("abc"))); + + memset(&parsed, 0x55, sizeof(parsed)); + ret = h2o_url_parse_relative("/abc", SIZE_MAX, &parsed); + ok(ret == 0); + ok(parsed.scheme == NULL); + ok(parsed.authority.base == NULL); + ok(parsed.host.base == NULL); + ok(parsed._port == 65535); + ok(h2o_memis(parsed.path.base, parsed.path.len, H2O_STRLIT("/abc"))); + + memset(&parsed, 0x55, sizeof(parsed)); + ret = h2o_url_parse_relative("http:abc", SIZE_MAX, &parsed); + ok(ret == 0); + ok(parsed.scheme == &H2O_URL_SCHEME_HTTP); + ok(parsed.authority.base == NULL); + ok(parsed.host.base == NULL); + ok(parsed._port == 65535); + ok(h2o_memis(parsed.path.base, parsed.path.len, H2O_STRLIT("abc"))); + + memset(&parsed, 0x55, sizeof(parsed)); + ret = h2o_url_parse_relative("//host", SIZE_MAX, &parsed); + ok(ret == 0); + ok(parsed.scheme == NULL); + ok(h2o_memis(parsed.authority.base, parsed.authority.len, H2O_STRLIT("host"))); + ok(h2o_memis(parsed.host.base, parsed.host.len, H2O_STRLIT("host"))); + ok(parsed._port == 65535); + ok(h2o_memis(parsed.path.base, parsed.path.len, H2O_STRLIT("/"))); + + memset(&parsed, 0x55, sizeof(parsed)); + ret = h2o_url_parse_relative("//host:12345/path", SIZE_MAX, &parsed); + ok(ret == 0); + ok(parsed.scheme == NULL); + ok(h2o_memis(parsed.authority.base, parsed.authority.len, H2O_STRLIT("host:12345"))); + ok(h2o_memis(parsed.host.base, parsed.host.len, H2O_STRLIT("host"))); + ok(parsed._port == 12345); + ok(h2o_memis(parsed.path.base, parsed.path.len, H2O_STRLIT("/path"))); + + memset(&parsed, 0x55, sizeof(parsed)); + ret = h2o_url_parse_relative("https://host:12345/path", SIZE_MAX, &parsed); + ok(ret == 0); + ok(parsed.scheme == &H2O_URL_SCHEME_HTTPS); + ok(h2o_memis(parsed.authority.base, parsed.authority.len, H2O_STRLIT("host:12345"))); + ok(h2o_memis(parsed.host.base, parsed.host.len, H2O_STRLIT("host"))); + ok(parsed._port == 12345); + ok(h2o_memis(parsed.path.base, parsed.path.len, H2O_STRLIT("/path"))); +} + +static void test_resolve(void) +{ + h2o_mem_pool_t pool; + h2o_url_t base, relative, resolved; + h2o_iovec_t final; + int ret; + + h2o_mem_init_pool(&pool); + + ret = h2o_url_parse("http://example.com/dir/index.html", SIZE_MAX, &base); + ok(ret == 0); + + ret = h2o_url_parse_relative("../assets/jquery.js", SIZE_MAX, &relative); + ok(ret == 0); + final = h2o_url_resolve(&pool, &base, &relative, &resolved); + ok(h2o_memis(final.base, final.len, H2O_STRLIT("http://example.com/assets/jquery.js"))); + ok(resolved.scheme == &H2O_URL_SCHEME_HTTP); + ok(h2o_memis(resolved.authority.base, resolved.authority.len, H2O_STRLIT("example.com"))); + ok(h2o_memis(resolved.host.base, resolved.host.len, H2O_STRLIT("example.com"))); + ok(resolved._port == 65535); + ok(h2o_url_get_port(&resolved) == 80); + ok(h2o_memis(resolved.path.base, resolved.path.len, H2O_STRLIT("/assets/jquery.js"))); + + ret = h2o_url_parse_relative("foo.html", SIZE_MAX, &relative); + ok(ret == 0); + final = h2o_url_resolve(&pool, &base, &relative, &resolved); + ok(h2o_memis(final.base, final.len, H2O_STRLIT("http://example.com/dir/foo.html"))); + ok(resolved.scheme == &H2O_URL_SCHEME_HTTP); + ok(h2o_memis(resolved.authority.base, resolved.authority.len, H2O_STRLIT("example.com"))); + ok(h2o_memis(resolved.host.base, resolved.host.len, H2O_STRLIT("example.com"))); + ok(resolved._port == 65535); + ok(h2o_url_get_port(&resolved) == 80); + ok(h2o_memis(resolved.path.base, resolved.path.len, H2O_STRLIT("/dir/foo.html"))); + + ret = h2o_url_parse_relative("./bar.txt", SIZE_MAX, &relative); + ok(ret == 0); + final = h2o_url_resolve(&pool, &base, &relative, &resolved); + ok(h2o_memis(final.base, final.len, H2O_STRLIT("http://example.com/dir/bar.txt"))); + ok(resolved.scheme == &H2O_URL_SCHEME_HTTP); + ok(h2o_memis(resolved.authority.base, resolved.authority.len, H2O_STRLIT("example.com"))); + ok(h2o_memis(resolved.host.base, resolved.host.len, H2O_STRLIT("example.com"))); + ok(resolved._port == 65535); + ok(h2o_url_get_port(&resolved) == 80); + ok(h2o_memis(resolved.path.base, resolved.path.len, H2O_STRLIT("/dir/bar.txt"))); + + ret = h2o_url_parse_relative("../../../traverse", SIZE_MAX, &relative); + ok(ret == 0); + final = h2o_url_resolve(&pool, &base, &relative, &resolved); + ok(h2o_memis(final.base, final.len, H2O_STRLIT("http://example.com/traverse"))); + ok(resolved.scheme == &H2O_URL_SCHEME_HTTP); + ok(h2o_memis(resolved.authority.base, resolved.authority.len, H2O_STRLIT("example.com"))); + ok(h2o_memis(resolved.host.base, resolved.host.len, H2O_STRLIT("example.com"))); + ok(resolved._port == 65535); + ok(h2o_url_get_port(&resolved) == 80); + ok(h2o_memis(resolved.path.base, resolved.path.len, H2O_STRLIT("/traverse"))); + + ret = h2o_url_parse_relative("http:foo.html", SIZE_MAX, &relative); + ok(ret == 0); + final = h2o_url_resolve(&pool, &base, &relative, &resolved); + ok(h2o_memis(final.base, final.len, H2O_STRLIT("http://example.com/dir/foo.html"))); + ok(resolved.scheme == &H2O_URL_SCHEME_HTTP); + ok(h2o_memis(resolved.authority.base, resolved.authority.len, H2O_STRLIT("example.com"))); + ok(h2o_memis(resolved.host.base, resolved.host.len, H2O_STRLIT("example.com"))); + ok(resolved._port == 65535); + ok(h2o_url_get_port(&resolved) == 80); + ok(h2o_memis(resolved.path.base, resolved.path.len, H2O_STRLIT("/dir/foo.html"))); + + ret = h2o_url_parse_relative("http:/icon.ico", SIZE_MAX, &relative); + ok(ret == 0); + final = h2o_url_resolve(&pool, &base, &relative, &resolved); + ok(h2o_memis(final.base, final.len, H2O_STRLIT("http://example.com/icon.ico"))); + ok(resolved.scheme == &H2O_URL_SCHEME_HTTP); + ok(h2o_memis(resolved.authority.base, resolved.authority.len, H2O_STRLIT("example.com"))); + ok(h2o_memis(resolved.host.base, resolved.host.len, H2O_STRLIT("example.com"))); + ok(resolved._port == 65535); + ok(h2o_url_get_port(&resolved) == 80); + ok(h2o_memis(resolved.path.base, resolved.path.len, H2O_STRLIT("/icon.ico"))); + + ret = h2o_url_parse_relative("https:/icon.ico", SIZE_MAX, &relative); + ok(ret == 0); + final = h2o_url_resolve(&pool, &base, &relative, &resolved); + ok(h2o_memis(final.base, final.len, H2O_STRLIT("https://example.com/icon.ico"))); + ok(resolved.scheme == &H2O_URL_SCHEME_HTTPS); + ok(h2o_memis(resolved.authority.base, resolved.authority.len, H2O_STRLIT("example.com"))); + ok(h2o_memis(resolved.host.base, resolved.host.len, H2O_STRLIT("example.com"))); + ok(resolved._port == 65535); + ok(h2o_url_get_port(&resolved) == 443); + ok(h2o_memis(resolved.path.base, resolved.path.len, H2O_STRLIT("/icon.ico"))); + + ret = h2o_url_parse_relative("//example.jp:81/icon.ico", SIZE_MAX, &relative); + ok(ret == 0); + final = h2o_url_resolve(&pool, &base, &relative, &resolved); + ok(h2o_memis(final.base, final.len, H2O_STRLIT("http://example.jp:81/icon.ico"))); + ok(resolved.scheme == &H2O_URL_SCHEME_HTTP); + ok(h2o_memis(resolved.authority.base, resolved.authority.len, H2O_STRLIT("example.jp:81"))); + ok(h2o_memis(resolved.host.base, resolved.host.len, H2O_STRLIT("example.jp"))); + ok(resolved._port == 81); + ok(h2o_url_get_port(&resolved) == 81); + ok(h2o_memis(resolved.path.base, resolved.path.len, H2O_STRLIT("/icon.ico"))); + + final = h2o_url_stringify(&pool, &base); + ok(h2o_memis(final.base, final.len, H2O_STRLIT("http://example.com/dir/index.html"))); + + h2o_mem_clear_pool(&pool); +} + +void test_lib__common__url_c(void) +{ + subtest("normalize_path", test_normalize_path); + subtest("hostport", test_hostport); + subtest("parse", test_parse); + subtest("parse_relative", test_parse_relative); + subtest("resolve", test_resolve); +} -- cgit v1.2.3