From b47430c842d0f79342d8af3e89fa99b8cc3510b5 Mon Sep 17 00:00:00 2001 From: Anna Henningsen Date: Sat, 29 Jan 2022 22:14:02 +0100 Subject: [PATCH 1/6] src: fix query/fragment serialization in URL::SerializeURL These are presumably typos. --- src/node_url.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/node_url.cc b/src/node_url.cc index 708d79f8d80826..d5c7091094fe2a 100644 --- a/src/node_url.cc +++ b/src/node_url.cc @@ -1578,10 +1578,10 @@ std::string URL::SerializeURL(const struct url_data* url, } } if (url->flags & URL_FLAGS_HAS_QUERY) { - output = "?" + url->query; + output += "?" + url->query; } if (!exclude && url->flags & URL_FLAGS_HAS_FRAGMENT) { - output = "#" + url->fragment; + output += "#" + url->fragment; } return output; } From c9ea544abf1dc2d67e88731c0a08f806feb5c10f Mon Sep 17 00:00:00 2001 From: Anna Henningsen Date: Sat, 29 Jan 2022 22:20:10 +0100 Subject: [PATCH 2/6] src: reserve string allocation space early in URL::SerializeURL This can be useful for performance when doing many string concatenations. --- src/node_url.cc | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/src/node_url.cc b/src/node_url.cc index d5c7091094fe2a..8cbac90ad237b1 100644 --- a/src/node_url.cc +++ b/src/node_url.cc @@ -7,6 +7,7 @@ #include #include +#include #include #include @@ -1547,7 +1548,23 @@ void URL::Parse(const char* input, // https://url.spec.whatwg.org/#url-serializing std::string URL::SerializeURL(const struct url_data* url, bool exclude = false) { - std::string output = url->scheme; + std::string output; + output.reserve( + 10 + + url->scheme.size() + + url->username.size() + + url->password.size() + + url->host.size() + + url->query.size() + + url->fragment.size() + + url->href.size() + + std::accumulate( + url->path.begin(), + url->path.end(), + 0, + [](size_t sum, const auto& str) { return sum + str.size(); })); + + output += url->scheme; if (url->flags & URL_FLAGS_HAS_HOST) { output += "//"; if (url->flags & URL_FLAGS_HAS_USERNAME || @@ -1583,6 +1600,7 @@ std::string URL::SerializeURL(const struct url_data* url, if (!exclude && url->flags & URL_FLAGS_HAS_FRAGMENT) { output += "#" + url->fragment; } + output.shrink_to_fit(); return output; } From 2fe8dcfed6b32e7882ccca2d8e8d483d93f8b5ef Mon Sep 17 00:00:00 2001 From: Anna Henningsen Date: Sat, 29 Jan 2022 22:22:09 +0100 Subject: [PATCH 3/6] src: use const reference instead of pointer in URL::SerializeURL Just some general cleanup to make things C++-y instead of C-y. --- src/node_url.cc | 64 ++++++++++++++++++++++++------------------------- src/node_url.h | 6 ++--- 2 files changed, 35 insertions(+), 35 deletions(-) diff --git a/src/node_url.cc b/src/node_url.cc index 8cbac90ad237b1..4a16d1a5e10a8a 100644 --- a/src/node_url.cc +++ b/src/node_url.cc @@ -1546,59 +1546,59 @@ void URL::Parse(const char* input, } // NOLINT(readability/fn_size) // https://url.spec.whatwg.org/#url-serializing -std::string URL::SerializeURL(const struct url_data* url, +std::string URL::SerializeURL(const url_data& url, bool exclude = false) { std::string output; output.reserve( 10 + - url->scheme.size() + - url->username.size() + - url->password.size() + - url->host.size() + - url->query.size() + - url->fragment.size() + - url->href.size() + + url.scheme.size() + + url.username.size() + + url.password.size() + + url.host.size() + + url.query.size() + + url.fragment.size() + + url.href.size() + std::accumulate( - url->path.begin(), - url->path.end(), + url.path.begin(), + url.path.end(), 0, [](size_t sum, const auto& str) { return sum + str.size(); })); - output += url->scheme; - if (url->flags & URL_FLAGS_HAS_HOST) { + output += url.scheme; + if (url.flags & URL_FLAGS_HAS_HOST) { output += "//"; - if (url->flags & URL_FLAGS_HAS_USERNAME || - url->flags & URL_FLAGS_HAS_PASSWORD) { - if (url->flags & URL_FLAGS_HAS_USERNAME) { - output += url->username; + if (url.flags & URL_FLAGS_HAS_USERNAME || + url.flags & URL_FLAGS_HAS_PASSWORD) { + if (url.flags & URL_FLAGS_HAS_USERNAME) { + output += url.username; } - if (url->flags & URL_FLAGS_HAS_PASSWORD) { - output += ":" + url->password; + if (url.flags & URL_FLAGS_HAS_PASSWORD) { + output += ":" + url.password; } output += "@"; } - output += url->host; - if (url->port != -1) { - output += ":" + std::to_string(url->port); + output += url.host; + if (url.port != -1) { + output += ":" + std::to_string(url.port); } } - if (url->flags & URL_FLAGS_CANNOT_BE_BASE) { - output += url->path[0]; + if (url.flags & URL_FLAGS_CANNOT_BE_BASE) { + output += url.path[0]; } else { - if (!(url->flags & URL_FLAGS_HAS_HOST) && - url->path.size() > 1 && - url->path[0].empty()) { + if (!(url.flags & URL_FLAGS_HAS_HOST) && + url.path.size() > 1 && + url.path[0].empty()) { output += "/."; } - for (size_t i = 1; i < url->path.size(); i++) { - output += "/" + url->path[i]; + for (size_t i = 1; i < url.path.size(); i++) { + output += "/" + url.path[i]; } } - if (url->flags & URL_FLAGS_HAS_QUERY) { - output += "?" + url->query; + if (url.flags & URL_FLAGS_HAS_QUERY) { + output += "?" + url.query; } - if (!exclude && url->flags & URL_FLAGS_HAS_FRAGMENT) { - output += "#" + url->fragment; + if (!exclude && url.flags & URL_FLAGS_HAS_FRAGMENT) { + output += "#" + url.fragment; } output.shrink_to_fit(); return output; diff --git a/src/node_url.h b/src/node_url.h index 0de05e96e100fa..d7b9a1c368cdae 100644 --- a/src/node_url.h +++ b/src/node_url.h @@ -94,7 +94,7 @@ class URL { const struct url_data* base, bool has_base); - static std::string SerializeURL(const struct url_data* url, bool exclude); + static std::string SerializeURL(const url_data& url, bool exclude); URL(const char* input, const size_t len) { Parse(input, len, kUnknownState, &context_, false, nullptr, false); @@ -174,7 +174,7 @@ class URL { } std::string href() const { - return SerializeURL(&context_, false); + return SerializeURL(context_, false); } // Get the path of the file: URL in a format consumable by native file system @@ -193,7 +193,7 @@ class URL { URL() : URL("") {} private: - struct url_data context_; + url_data context_; }; } // namespace url From 438849a043507ddc90a3915a00e0c214d99935bf Mon Sep 17 00:00:00 2001 From: Anna Henningsen Date: Mon, 31 Jan 2022 15:29:29 +0100 Subject: [PATCH 4/6] fixup! src: use const reference instead of pointer in URL::SerializeURL Co-authored-by: Timothy Gu --- src/node_url.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/node_url.cc b/src/node_url.cc index 4a16d1a5e10a8a..7a720aa094dc4c 100644 --- a/src/node_url.cc +++ b/src/node_url.cc @@ -1597,7 +1597,7 @@ std::string URL::SerializeURL(const url_data& url, if (url.flags & URL_FLAGS_HAS_QUERY) { output += "?" + url.query; } - if (!exclude && url.flags & URL_FLAGS_HAS_FRAGMENT) { + if (!exclude && (url.flags & URL_FLAGS_HAS_FRAGMENT)) { output += "#" + url.fragment; } output.shrink_to_fit(); From 6552e4159b37a6e5c4f0c214ef33ffb23af70ebd Mon Sep 17 00:00:00 2001 From: Anna Henningsen Date: Mon, 31 Jan 2022 15:30:48 +0100 Subject: [PATCH 5/6] fixup! src: use const reference instead of pointer in URL::SerializeURL --- src/node_url.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/node_url.cc b/src/node_url.cc index 7a720aa094dc4c..3bfc003eb65560 100644 --- a/src/node_url.cc +++ b/src/node_url.cc @@ -1550,7 +1550,7 @@ std::string URL::SerializeURL(const url_data& url, bool exclude = false) { std::string output; output.reserve( - 10 + + 10 + // We generally insert < 10 separator characters between URL parts url.scheme.size() + url.username.size() + url.password.size() + From 08ec1d53bfd6e338d9b3229f5fbc625e692db3b3 Mon Sep 17 00:00:00 2001 From: Anna Henningsen Date: Mon, 7 Feb 2022 11:29:56 +0100 Subject: [PATCH 6/6] fixup! src: use const reference instead of pointer in URL::SerializeURL Co-authored-by: James M Snell --- src/node_url.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/node_url.cc b/src/node_url.cc index 3bfc003eb65560..e4b15917f5d77b 100644 --- a/src/node_url.cc +++ b/src/node_url.cc @@ -1550,7 +1550,7 @@ std::string URL::SerializeURL(const url_data& url, bool exclude = false) { std::string output; output.reserve( - 10 + // We generally insert < 10 separator characters between URL parts + 10 + // We generally insert < 10 separator characters between URL parts url.scheme.size() + url.username.size() + url.password.size() +