From 76d8e1821e12caf6e903842b5119f0fd12e21af3 Mon Sep 17 00:00:00 2001 From: Kazuho Oku Date: Fri, 24 Nov 2023 15:52:11 +0900 Subject: [PATCH] When parsing absolute form that omits `/` (i.e., `scheme://host?query`), prepend `/` to the generated path component, otherwise callers expecting `/` at the beginning will start to fail. --- include/h2o/url.h | 7 ++-- lib/common/url.c | 18 +++++---- lib/core/proxy.c | 2 +- lib/core/request.c | 4 +- lib/core/util.c | 2 +- lib/handler/configurator/proxy.c | 23 +++++++---- lib/handler/mruby/http_request.c | 2 +- lib/handler/mruby/middleware.c | 2 +- lib/http1.c | 2 +- src/httpclient.c | 11 ++++-- t/00unit/lib/common/url.c | 65 ++++++++++++++++++-------------- t/00unit/lib/core/proxy.c | 5 +-- 12 files changed, 83 insertions(+), 60 deletions(-) diff --git a/include/h2o/url.h b/include/h2o/url.h index e43899745..8d990271d 100644 --- a/include/h2o/url.h +++ b/include/h2o/url.h @@ -77,13 +77,14 @@ int h2o_url_init_with_sun_path(h2o_url_t *url, h2o_mem_pool_t *pool, const h2o_u h2o_iovec_t path); /** - * parses absolute URL (either http or https) + * Parses absolute URL (either http or https). Upon successful return, `path` attribute of the returned object is guaranteed to be + * in absolute form (i.e., starts with `/`) so that it can be passed directly to HTTP clients. */ -int h2o_url_parse(const char *url, size_t url_len, h2o_url_t *result); +int h2o_url_parse(h2o_mem_pool_t *pool, const char *url, size_t url_len, h2o_url_t *result); /** * parses relative URL */ -int h2o_url_parse_relative(const char *url, size_t url_len, h2o_url_t *result); +int h2o_url_parse_relative(h2o_mem_pool_t *pool, const char *url, size_t url_len, h2o_url_t *result); /** * parses the authority and returns the next position (i.e. start of path) * @return pointer to the end of hostport if successful, or NULL if failed. *port becomes the specified port number or 65535 if not diff --git a/lib/common/url.c b/lib/common/url.c index 515c6a418..c7c4b328d 100644 --- a/lib/common/url.c +++ b/lib/common/url.c @@ -233,7 +233,7 @@ const char *h2o_url_parse_hostport(const char *s, size_t len, h2o_iovec_t *host, return token_start; } -static int parse_authority_and_path(const char *src, const char *url_end, h2o_url_t *parsed) +static int parse_authority_and_path(h2o_mem_pool_t *pool, const char *src, const char *url_end, h2o_url_t *parsed) { const char *p = h2o_url_parse_hostport(src, url_end - src, &parsed->host, &parsed->_port); if (p == NULL) @@ -241,15 +241,17 @@ static int parse_authority_and_path(const char *src, const char *url_end, h2o_ur parsed->authority = h2o_iovec_init(src, p - src); if (p == url_end) { parsed->path = h2o_iovec_init(H2O_STRLIT("/")); - } else { - if (*p != '/' && *p != '?') - return -1; + } else if (*p == '/') { parsed->path = h2o_iovec_init(p, url_end - p); + } else if (*p == '?') { + parsed->path = h2o_concat(pool, h2o_iovec_init(H2O_STRLIT("/")), h2o_iovec_init(p, url_end - p)); + } else { + return -1; } return 0; } -int h2o_url_parse(const char *url, size_t url_len, h2o_url_t *parsed) +int h2o_url_parse(h2o_mem_pool_t *pool, const char *url, size_t url_len, h2o_url_t *parsed) { const char *url_end, *p; @@ -266,10 +268,10 @@ int h2o_url_parse(const char *url, size_t url_len, h2o_url_t *parsed) return -1; p += 2; - return parse_authority_and_path(p, url_end, parsed); + return parse_authority_and_path(pool, p, url_end, parsed); } -int h2o_url_parse_relative(const char *url, size_t url_len, h2o_url_t *parsed) +int h2o_url_parse_relative(h2o_mem_pool_t *pool, const char *url, size_t url_len, h2o_url_t *parsed) { const char *url_end, *p; @@ -285,7 +287,7 @@ int h2o_url_parse_relative(const char *url, size_t url_len, h2o_url_t *parsed) /* handle "//" */ if (url_end - p >= 2 && p[0] == '/' && p[1] == '/') - return parse_authority_and_path(p + 2, url_end, parsed); + return parse_authority_and_path(pool, p + 2, url_end, parsed); /* reset authority, host, port, and set path */ parsed->authority = (h2o_iovec_t){NULL}; diff --git a/lib/core/proxy.c b/lib/core/proxy.c index dc7fd6705..0cdfffd75 100644 --- a/lib/core/proxy.c +++ b/lib/core/proxy.c @@ -64,7 +64,7 @@ static h2o_iovec_t rewrite_location(h2o_mem_pool_t *pool, const char *location, { h2o_url_t loc_parsed; - if (h2o_url_parse(location, location_len, &loc_parsed) != 0) + if (h2o_url_parse(pool, location, location_len, &loc_parsed) != 0) goto NoRewrite; if (loc_parsed.scheme != &H2O_URL_SCHEME_HTTP) goto NoRewrite; diff --git a/lib/core/request.c b/lib/core/request.c index 4693de56c..7c4683589 100644 --- a/lib/core/request.c +++ b/lib/core/request.c @@ -776,7 +776,7 @@ void h2o_send_redirect_internal(h2o_req_t *req, h2o_iovec_t method, const char * h2o_url_t url; /* parse the location URL */ - if (h2o_url_parse_relative(url_str, url_len, &url) != 0) { + if (h2o_url_parse_relative(&req->pool, url_str, url_len, &url) != 0) { /* TODO log h2o_error_printf("[proxy] cannot handle location header: %.*s\n", (int)url_len, url); */ h2o_send_error_deferred_502(req, "Gateway Error", "internal error", 0); return; @@ -877,7 +877,7 @@ int h2o_req_resolve_internal_redirect_url(h2o_req_t *req, h2o_iovec_t dest, h2o_ h2o_url_t input; /* resolve the URL */ - if (h2o_url_parse_relative(dest.base, dest.len, &input) != 0) { + if (h2o_url_parse_relative(&req->pool, dest.base, dest.len, &input) != 0) { return -1; } if (input.scheme != NULL && input.authority.base != NULL) { diff --git a/lib/core/util.c b/lib/core/util.c index 4e878996d..fe152dc23 100644 --- a/lib/core/util.c +++ b/lib/core/util.c @@ -600,7 +600,7 @@ static h2o_iovec_t to_push_path(h2o_mem_pool_t *pool, h2o_iovec_t url, h2o_iovec h2o_url_t parsed, resolved; /* check the authority, and extract absolute path */ - if (h2o_url_parse_relative(url.base, url.len, &parsed) != 0) + if (h2o_url_parse_relative(pool, url.base, url.len, &parsed) != 0) goto Invalid; /* fast-path for abspath form */ diff --git a/lib/handler/configurator/proxy.c b/lib/handler/configurator/proxy.c index cf470ab4f..4dfd039ce 100644 --- a/lib/handler/configurator/proxy.c +++ b/lib/handler/configurator/proxy.c @@ -316,9 +316,13 @@ static int on_config_ssl_session_cache(h2o_configurator_command_t *cmd, h2o_conf static h2o_socketpool_target_t *parse_backend(h2o_configurator_command_t *cmd, yoml_t *backend) { + h2o_mem_pool_t pool; yoml_t **url_node; + h2o_socketpool_target_t *result = NULL; h2o_socketpool_target_conf_t lb_per_target_conf = {0}; /* default weight of each target */ + h2o_mem_init_pool(&pool); + switch (backend->type) { case YOML_TYPE_SCALAR: url_node = &backend; @@ -326,14 +330,14 @@ static h2o_socketpool_target_t *parse_backend(h2o_configurator_command_t *cmd, y case YOML_TYPE_MAPPING: { yoml_t **weight_node; if (h2o_configurator_parse_mapping(cmd, backend, "url:s", "weight:*", &url_node, &weight_node) != 0) - return NULL; + goto Exit; if (weight_node != NULL) { unsigned weight; if (h2o_configurator_scanf(cmd, *weight_node, "%u", &weight) != 0) - return NULL; + goto Exit; if (!(1 <= weight && weight <= H2O_SOCKETPOOL_TARGET_MAX_WEIGHT)) { h2o_configurator_errprintf(cmd, *weight_node, "weight must be an integer in range 1 - 256"); - return NULL; + goto Exit; } lb_per_target_conf.weight_m1 = weight - 1; } @@ -341,15 +345,20 @@ static h2o_socketpool_target_t *parse_backend(h2o_configurator_command_t *cmd, y default: h2o_configurator_errprintf(cmd, backend, "items of arguments passed to proxy.reverse.url must be either a scalar or a mapping"); - return NULL; + goto Exit; } h2o_url_t url; - if (h2o_url_parse((*url_node)->data.scalar, SIZE_MAX, &url) != 0) { + if (h2o_url_parse(&pool, (*url_node)->data.scalar, SIZE_MAX, &url) != 0) { h2o_configurator_errprintf(cmd, *url_node, "failed to parse URL: %s\n", (*url_node)->data.scalar); - return NULL; + goto Exit; } - return h2o_socketpool_create_target(&url, &lb_per_target_conf); + + result = h2o_socketpool_create_target(&url, &lb_per_target_conf); + +Exit: + h2o_mem_clear_pool(&pool); + return result; } static int on_config_reverse_url(h2o_configurator_command_t *cmd, h2o_configurator_context_t *ctx, yoml_t *node) diff --git a/lib/handler/mruby/http_request.c b/lib/handler/mruby/http_request.c index 57515eb2b..d6d792750 100644 --- a/lib/handler/mruby/http_request.c +++ b/lib/handler/mruby/http_request.c @@ -551,7 +551,7 @@ static mrb_value http_request_method(mrb_state *mrb, mrb_value self) ctx->req.can_keepalive = h2o_socketpool_can_keepalive(&shared_ctx->ctx->globalconf->proxy.global_socketpool); /* uri */ - if (h2o_url_parse(arg_url, arg_url_len, &url) != 0) + if (h2o_url_parse(&ctx->pool, arg_url, arg_url_len, &url) != 0) mrb_raise(mrb, E_ARGUMENT_ERROR, "invaild URL"); h2o_url_copy(&ctx->pool, &ctx->req.url, &url); diff --git a/lib/handler/mruby/middleware.c b/lib/handler/mruby/middleware.c index cf97f7164..ff91eedb7 100644 --- a/lib/handler/mruby/middleware.c +++ b/lib/handler/mruby/middleware.c @@ -761,7 +761,7 @@ static struct st_mruby_subreq_t *create_subreq(h2o_mruby_context_t *ctx, mrb_val } h2o_iovec_t url_str = h2o_concat_list(&subreq->super.pool, url_comps, num_comps); h2o_url_t url_parsed; - if (h2o_url_parse(url_str.base, url_str.len, &url_parsed) != 0) { + if (h2o_url_parse(&subreq->super.pool, url_str.base, url_str.len, &url_parsed) != 0) { /* TODO is there any other way to show better error message? */ mrb->exc = mrb_obj_ptr(mrb_exc_new_lit(mrb, E_ARGUMENT_ERROR, "env variable contains invalid values")); goto Failed; diff --git a/lib/http1.c b/lib/http1.c index 47ea10c0d..cd237fd11 100644 --- a/lib/http1.c +++ b/lib/http1.c @@ -486,7 +486,7 @@ static const char *fixup_request(struct st_h2o_http1_conn_t *conn, struct phr_he /* request line is in ordinary form, path might contain absolute URL; if so, convert it */ if (conn->req.input.path.len != 0 && conn->req.input.path.base[0] != '/') { h2o_url_t url; - if (h2o_url_parse(conn->req.input.path.base, conn->req.input.path.len, &url) == 0) { + if (h2o_url_parse(&conn->req.pool, conn->req.input.path.base, conn->req.input.path.len, &url) == 0) { conn->req.input.scheme = url.scheme; conn->req.input.path = url.path; host = url.authority; /* authority part of the absolute form overrides the host header field (RFC 7230 S5.4) */ diff --git a/src/httpclient.c b/src/httpclient.c index f402d6848..16b53742b 100644 --- a/src/httpclient.c +++ b/src/httpclient.c @@ -279,7 +279,7 @@ static void start_request(h2o_httpclient_ctx_t *ctx) url_parsed->path = h2o_iovec_init(H2O_STRLIT("/")); } } else { - if (h2o_url_parse(req.target, SIZE_MAX, url_parsed) != 0) { + if (h2o_url_parse(pool, req.target, SIZE_MAX, url_parsed) != 0) { on_error(ctx, pool, "unrecognized type of URL: %s", req.target); return; } @@ -687,13 +687,16 @@ int main(int argc, char **argv) exit(EXIT_FAILURE); } break; - case 'x': + case 'x': { + h2o_mem_pool_t pool; + h2o_mem_init_pool(&pool); req.connect_to = h2o_mem_alloc(sizeof(*req.connect_to)); - if (h2o_url_parse(optarg, strlen(optarg), req.connect_to) != 0) { + /* we can leak pool and `req.connect_to`, as they are globals allocated only once in `main` */ + if (h2o_url_parse(&pool, optarg, strlen(optarg), req.connect_to) != 0) { fprintf(stderr, "invalid server URL specified for -x\n"); exit(EXIT_FAILURE); } - break; + } break; case 'X': { #if H2O_USE_LIBUV fprintf(stderr, "-X is not supported by the libuv backend\n"); diff --git a/t/00unit/lib/common/url.c b/t/00unit/lib/common/url.c index 2caea289a..400b1a6d0 100644 --- a/t/00unit/lib/common/url.c +++ b/t/00unit/lib/common/url.c @@ -424,10 +424,13 @@ static void test_hostport(void) static void test_parse(void) { + h2o_mem_pool_t pool; h2o_url_t parsed; int ret; - ret = h2o_url_parse("http://example.com/abc", SIZE_MAX, &parsed); + h2o_mem_init_pool(&pool); + + ret = h2o_url_parse(&pool, "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"))); @@ -436,7 +439,7 @@ static void test_parse(void) 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); + ret = h2o_url_parse(&pool, "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"))); @@ -445,7 +448,7 @@ static void test_parse(void) 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); + ret = h2o_url_parse(&pool, "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"))); @@ -454,7 +457,7 @@ static void test_parse(void) 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); + ret = h2o_url_parse(&pool, "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"))); @@ -463,7 +466,7 @@ static void test_parse(void) 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); + ret = h2o_url_parse(&pool, "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"))); @@ -472,16 +475,16 @@ static void test_parse(void) 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); + ret = h2o_url_parse(&pool, "http:/abc", SIZE_MAX, &parsed); ok(ret != 0); - ret = h2o_url_parse("ftp://example.com/abc", SIZE_MAX, &parsed); + ret = h2o_url_parse(&pool, "ftp://example.com/abc", SIZE_MAX, &parsed); ok(ret != 0); - ret = h2o_url_parse("http://abc:111111/def", SIZE_MAX, &parsed); + ret = h2o_url_parse(&pool, "http://abc:111111/def", SIZE_MAX, &parsed); ok(ret != 0); - ret = h2o_url_parse("http://[::ffff:192.0.2.128]", SIZE_MAX, &parsed); + ret = h2o_url_parse(&pool, "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]"))); @@ -490,7 +493,7 @@ static void test_parse(void) 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); + ret = h2o_url_parse(&pool, "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]"))); @@ -499,7 +502,7 @@ static void test_parse(void) 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); + ret = h2o_url_parse(&pool, "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"))); @@ -508,19 +511,23 @@ static void test_parse(void) ok(h2o_url_get_port(&parsed) == 111); ok(h2o_memis(parsed.path.base, parsed.path.len, H2O_STRLIT("/abc"))); - ret = h2o_url_parse("http://example.com:8080?abc", SIZE_MAX, &parsed); + ret = h2o_url_parse(&pool, "http://example.com:8080?abc", SIZE_MAX, &parsed); ok(ret == 0); - ok(h2o_memis(parsed.path.base, parsed.path.len, H2O_STRLIT("?abc"))); + ok(h2o_memis(parsed.path.base, parsed.path.len, H2O_STRLIT("/?abc"))); + h2o_mem_clear_pool(&pool); } static void test_parse_relative(void) { + h2o_mem_pool_t pool; h2o_url_t parsed; int ret; + h2o_mem_init_pool(&pool); + memset(&parsed, 0x55, sizeof(parsed)); - ret = h2o_url_parse_relative("abc", SIZE_MAX, &parsed); + ret = h2o_url_parse_relative(&pool, "abc", SIZE_MAX, &parsed); ok(ret == 0); ok(parsed.scheme == NULL); ok(parsed.authority.base == NULL); @@ -529,7 +536,7 @@ static void test_parse_relative(void) 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); + ret = h2o_url_parse_relative(&pool, "/abc", SIZE_MAX, &parsed); ok(ret == 0); ok(parsed.scheme == NULL); ok(parsed.authority.base == NULL); @@ -538,7 +545,7 @@ static void test_parse_relative(void) 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); + ret = h2o_url_parse_relative(&pool, "http:abc", SIZE_MAX, &parsed); ok(ret == 0); ok(parsed.scheme == &H2O_URL_SCHEME_HTTP); ok(parsed.authority.base == NULL); @@ -547,7 +554,7 @@ static void test_parse_relative(void) 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); + ret = h2o_url_parse_relative(&pool, "//host", SIZE_MAX, &parsed); ok(ret == 0); ok(parsed.scheme == NULL); ok(h2o_memis(parsed.authority.base, parsed.authority.len, H2O_STRLIT("host"))); @@ -556,7 +563,7 @@ static void test_parse_relative(void) 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); + ret = h2o_url_parse_relative(&pool, "//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"))); @@ -565,13 +572,15 @@ static void test_parse_relative(void) 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); + ret = h2o_url_parse_relative(&pool, "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"))); + + h2o_mem_clear_pool(&pool); } static void test_resolve(void) @@ -583,10 +592,10 @@ static void test_resolve(void) h2o_mem_init_pool(&pool); - ret = h2o_url_parse("http://example.com/dir/index.html", SIZE_MAX, &base); + ret = h2o_url_parse(&pool, "http://example.com/dir/index.html", SIZE_MAX, &base); ok(ret == 0); - ret = h2o_url_parse_relative("../assets/jquery.js", SIZE_MAX, &relative); + ret = h2o_url_parse_relative(&pool, "../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"))); @@ -597,7 +606,7 @@ static void test_resolve(void) 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); + ret = h2o_url_parse_relative(&pool, "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"))); @@ -608,7 +617,7 @@ static void test_resolve(void) 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); + ret = h2o_url_parse_relative(&pool, "./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"))); @@ -619,7 +628,7 @@ static void test_resolve(void) 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); + ret = h2o_url_parse_relative(&pool, "../../../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"))); @@ -630,7 +639,7 @@ static void test_resolve(void) 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); + ret = h2o_url_parse_relative(&pool, "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"))); @@ -641,7 +650,7 @@ static void test_resolve(void) 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); + ret = h2o_url_parse_relative(&pool, "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"))); @@ -652,7 +661,7 @@ static void test_resolve(void) 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); + ret = h2o_url_parse_relative(&pool, "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"))); @@ -663,7 +672,7 @@ static void test_resolve(void) 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); + ret = h2o_url_parse_relative(&pool, "//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"))); diff --git a/t/00unit/lib/core/proxy.c b/t/00unit/lib/core/proxy.c index 6f87db1fd..83efd518b 100644 --- a/t/00unit/lib/core/proxy.c +++ b/t/00unit/lib/core/proxy.c @@ -27,11 +27,10 @@ static void test_rewrite_location(void) h2o_url_t upstream; h2o_mem_pool_t pool; h2o_iovec_t ret; - - h2o_url_parse(H2O_STRLIT("http://realhost:81/real/"), &upstream); - h2o_mem_init_pool(&pool); + h2o_url_parse(&pool, H2O_STRLIT("http://realhost:81/real/"), &upstream); + ret = rewrite_location(&pool, H2O_STRLIT("http://realhost:81/real/abc"), &upstream, &H2O_URL_SCHEME_HTTPS, h2o_iovec_init(H2O_STRLIT("vhost:8443")), h2o_iovec_init(H2O_STRLIT("/virtual/"))); ok(h2o_memis(ret.base, ret.len, H2O_STRLIT("https://vhost:8443/virtual/abc")));