-
Notifications
You must be signed in to change notification settings - Fork 4.8k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
http: Use GURL as HTTP URL parser utility (#11670)
This replaces http_parser's URL parser with GURL. Risk Level: Medium Testing: Unit Docs Changes: N/A Release Notes: N/A Signed-off-by: Dhi Aurrahman <dio@tetrate.io>
- Loading branch information
Showing
21 changed files
with
454 additions
and
111 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,119 @@ | ||
# TODO(dio): Consider to remove this patch when we have the ability to compile the project using | ||
# clang-cl. Tracked in https://github.com/envoyproxy/envoy/issues/11974. | ||
|
||
diff --git a/base/compiler_specific.h b/base/compiler_specific.h | ||
index 2962537..6193b56 100644 | ||
--- a/base/compiler_specific.h | ||
+++ b/base/compiler_specific.h | ||
@@ -7,10 +7,6 @@ | ||
|
||
#include "build/build_config.h" | ||
|
||
-#if defined(COMPILER_MSVC) && !defined(__clang__) | ||
-#error "Only clang-cl is supported on Windows, see https://crbug.com/988071" | ||
-#endif | ||
- | ||
// Annotate a variable indicating it's ok if the variable is not used. | ||
// (Typically used to silence a compiler warning when the assignment | ||
// is important for some other reason.) | ||
@@ -212,7 +208,9 @@ | ||
#endif | ||
#endif | ||
|
||
-#if defined(__clang__) && __has_attribute(uninitialized) | ||
+#if defined(__clang__) | ||
+#if defined(__has_attribute) | ||
+#if __has_attribute(uninitialized) | ||
// Attribute "uninitialized" disables -ftrivial-auto-var-init=pattern for | ||
// the specified variable. | ||
// Library-wide alternative is | ||
@@ -243,6 +241,8 @@ | ||
// E.g. platform, bot, benchmark or test name in patch description or next to | ||
// the attribute. | ||
#define STACK_UNINITIALIZED __attribute__((uninitialized)) | ||
+#endif | ||
+#endif | ||
#else | ||
#define STACK_UNINITIALIZED | ||
#endif | ||
diff --git a/base/strings/BUILD b/base/strings/BUILD | ||
index 7a06170..7c86a5f 100644 | ||
--- a/base/strings/BUILD | ||
+++ b/base/strings/BUILD | ||
@@ -6,23 +6,21 @@ load("//:build_config.bzl", "build_config") | ||
cc_library( | ||
name = "strings", | ||
srcs = [ | ||
- "string16.cc", | ||
"string_piece.cc", | ||
"string_util.cc", | ||
"string_util_constants.cc", | ||
"utf_string_conversion_utils.cc", | ||
"utf_string_conversions.cc", | ||
- ], | ||
+ ] + build_config.strings_srcs, | ||
hdrs = [ | ||
"char_traits.h", | ||
"string16.h", | ||
"string_piece.h", | ||
"string_piece_forward.h", | ||
"string_util.h", | ||
- "string_util_posix.h", | ||
"utf_string_conversion_utils.h", | ||
"utf_string_conversions.h", | ||
- ], | ||
+ ] + build_config.strings_hdrs, | ||
copts = build_config.default_copts, | ||
visibility = ["//visibility:public"], | ||
deps = [ | ||
diff --git a/build_config.bzl b/build_config.bzl | ||
index d5fca65..fc0d7e5 100644 | ||
--- a/build_config/build_config.bzl | ||
+++ b/build_config/build_config.bzl | ||
@@ -1,8 +1,25 @@ | ||
-_default_copts = [ | ||
- "-std=c++14", | ||
- "-fno-strict-aliasing", | ||
-] | ||
+_default_copts = select({ | ||
+ "@envoy//bazel:windows_x86_64": [ | ||
+ "/std:c++14", | ||
+ ], | ||
+ "//conditions:default": [ | ||
+ "-std=c++14", | ||
+ "-fno-strict-aliasing", | ||
+ ], | ||
+}) | ||
+ | ||
+_strings_srcs = select({ | ||
+ "@envoy//bazel:windows_x86_64": [], | ||
+ "//conditions:default": ["string16.cc"], | ||
+}) | ||
+ | ||
+_strings_hdrs = select({ | ||
+ "@envoy//bazel:windows_x86_64": ["string_util_win.h"], | ||
+ "//conditions:default": ["string_util_posix.h"], | ||
+}) | ||
|
||
build_config = struct( | ||
default_copts = _default_copts, | ||
+ strings_srcs = _strings_srcs, | ||
+ strings_hdrs = _strings_hdrs, | ||
) | ||
diff --git a/url/BUILD b/url/BUILD | ||
index 0126bdc..5d1a171 100644 | ||
--- a/url/BUILD | ||
+++ b/url/BUILD | ||
@@ -43,11 +43,11 @@ cc_library( | ||
"url_util.h", | ||
], | ||
copts = build_config.default_copts, | ||
- linkopts = ["-licuuc"], | ||
visibility = ["//visibility:public"], | ||
deps = [ | ||
"//base", | ||
"//base/strings", | ||
"//polyfills", | ||
+ "@org_unicode_icuuc//:common", | ||
], | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
load("@rules_cc//cc:defs.bzl", "cc_library") | ||
|
||
licenses(["notice"]) # Apache 2 | ||
|
||
exports_files([ | ||
"icu4c/LICENSE", | ||
"icu4j/main/shared/licenses/LICENSE", | ||
]) | ||
|
||
icuuc_copts = [ | ||
"-DU_STATIC_IMPLEMENTATION", | ||
"-DU_COMMON_IMPLEMENTATION", | ||
"-DU_HAVE_STD_ATOMICS", | ||
] + select({ | ||
"@envoy//bazel:apple": [ | ||
"-Wno-shorten-64-to-32", | ||
"-Wno-unused-variable", | ||
], | ||
"@envoy//bazel:windows_x86_64": [ | ||
"/utf-8", | ||
"/DLOCALE_ALLOW_NEUTRAL_NAMES=0", | ||
], | ||
# TODO(dio): Add "@envoy//bazel:android" when we have it. | ||
# "@envoy//bazel:android": [ | ||
# "-fdata-sections", | ||
# "-DU_HAVE_NL_LANGINFO_CODESET=0", | ||
# "-Wno-deprecated-declarations", | ||
# ], | ||
"//conditions:default": [], | ||
}) | ||
|
||
cc_library( | ||
name = "headers", | ||
hdrs = glob(["icu4c/source/common/unicode/*.h"]), | ||
includes = ["icu4c/source/common"], | ||
visibility = ["//visibility:public"], | ||
) | ||
|
||
cc_library( | ||
name = "common", | ||
hdrs = glob(["icu4c/source/common/unicode/*.h"]), | ||
includes = ["icu4c/source/common"], | ||
visibility = ["//visibility:public"], | ||
deps = [":icuuc"], | ||
) | ||
|
||
cc_library( | ||
name = "icuuc", | ||
srcs = glob([ | ||
"icu4c/source/common/*.c", | ||
"icu4c/source/common/*.cpp", | ||
"icu4c/source/stubdata/*.cpp", | ||
]), | ||
hdrs = glob(["icu4c/source/common/*.h"]), | ||
copts = icuuc_copts, | ||
tags = ["requires-rtti"], | ||
visibility = ["//visibility:private"], | ||
deps = [":headers"], | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
#include "common/http/url_utility.h" | ||
|
||
#include <sys/types.h> | ||
|
||
#include <iostream> | ||
#include <string> | ||
|
||
#include "common/common/assert.h" | ||
#include "common/common/empty_string.h" | ||
#include "common/common/utility.h" | ||
|
||
#include "absl/strings/numbers.h" | ||
#include "absl/strings/str_cat.h" | ||
|
||
namespace Envoy { | ||
namespace Http { | ||
namespace Utility { | ||
|
||
bool Url::initialize(absl::string_view absolute_url, bool is_connect) { | ||
// TODO(dio): When we have access to base::StringPiece, probably we can convert absolute_url to | ||
// that instead. | ||
GURL parsed(std::string{absolute_url}); | ||
if (is_connect) { | ||
return initializeForConnect(std::move(parsed)); | ||
} | ||
|
||
// TODO(dio): Check if we need to accommodate to strictly validate only http(s) AND ws(s) schemes. | ||
// Currently, we only accept http(s). | ||
if (!parsed.is_valid() || !parsed.SchemeIsHTTPOrHTTPS()) { | ||
return false; | ||
} | ||
|
||
scheme_ = parsed.scheme(); | ||
|
||
// Only non-default ports will be rendered as part of host_and_port_. For example, | ||
// http://www.host.com:80 has port component (i.e. 80). However, since 80 is a default port for | ||
// http scheme, host_and_port_ will be rendered as www.host.com (without port). The same case with | ||
// https scheme (with port 443) as well. | ||
host_and_port_ = | ||
absl::StrCat(parsed.host(), parsed.has_port() ? ":" : EMPTY_STRING, parsed.port()); | ||
|
||
const int port = parsed.EffectiveIntPort(); | ||
if (port <= 0 || port > std::numeric_limits<uint16_t>::max()) { | ||
return false; | ||
} | ||
port_ = static_cast<uint16_t>(port); | ||
|
||
// RFC allows the absolute URI to not end in "/", but the absolute path form must start with "/". | ||
path_and_query_params_ = parsed.PathForRequest(); | ||
if (parsed.has_ref()) { | ||
absl::StrAppend(&path_and_query_params_, "#", parsed.ref()); | ||
} | ||
|
||
return true; | ||
} | ||
|
||
bool Url::initializeForConnect(GURL&& url) { | ||
// CONNECT requests can only contain "hostname:port" | ||
// https://github.com/nodejs/http-parser/blob/d9275da4650fd1133ddc96480df32a9efe4b059b/http_parser.c#L2503-L2506. | ||
if (!url.is_valid() || url.IsStandard()) { | ||
return false; | ||
} | ||
|
||
const auto& parsed = url.parsed_for_possibly_invalid_spec(); | ||
// The parsed.scheme contains the URL's hostname (stored by GURL). While host and port have -1 | ||
// as its length. | ||
if (parsed.scheme.len <= 0 || parsed.host.len > 0 || parsed.port.len > 0) { | ||
return false; | ||
} | ||
|
||
host_and_port_ = url.possibly_invalid_spec(); | ||
const auto& parts = StringUtil::splitToken(host_and_port_, ":", /*keep_empty_string=*/true, | ||
/*trim_whitespace=*/false); | ||
if (parts.size() != 2 || static_cast<size_t>(parsed.scheme.len) != parts.at(0).size() || | ||
!validPortForConnect(parts.at(1))) { | ||
return false; | ||
} | ||
|
||
return true; | ||
} | ||
|
||
bool Url::validPortForConnect(absl::string_view port_string) { | ||
int port; | ||
const bool valid = absl::SimpleAtoi(port_string, &port); | ||
// Only a port value in valid range (1-65535) is allowed. | ||
if (!valid || port <= 0 || port > std::numeric_limits<uint16_t>::max()) { | ||
return false; | ||
} | ||
port_ = static_cast<uint16_t>(port); | ||
return true; | ||
} | ||
|
||
} // namespace Utility | ||
} // namespace Http | ||
} // namespace Envoy |
Oops, something went wrong.