Go to the documentation of this file.
30 #include "absl/status/status.h"
31 #include "absl/strings/ascii.h"
32 #include "absl/strings/escaping.h"
33 #include "absl/strings/match.h"
34 #include "absl/strings/str_cat.h"
35 #include "absl/strings/str_format.h"
36 #include "absl/strings/str_join.h"
37 #include "absl/strings/str_split.h"
38 #include "absl/strings/strip.h"
48 bool IsSubDelimChar(
char c) {
68 bool IsUnreservedChar(
char c) {
82 bool IsSchemeChar(
char c) {
95 bool IsAuthorityChar(
char c) {
96 if (IsUnreservedChar(c))
return true;
97 if (IsSubDelimChar(c))
return true;
110 bool IsPChar(
char c) {
111 if (IsUnreservedChar(c))
return true;
112 if (IsSubDelimChar(c))
return true;
123 bool IsPathChar(
char c) {
return IsPChar(c) ||
c ==
'/'; }
128 bool IsQueryOrFragmentChar(
char c) {
129 return IsPChar(c) ||
c ==
'/' ||
c ==
'?';
133 bool IsQueryKeyOrValueChar(
char c) {
134 return c !=
'&' &&
c !=
'=' && IsQueryOrFragmentChar(c);
143 if (!is_allowed_char(c)) {
163 if (!IsQueryOrFragmentChar(c) && c !=
'%')
return false;
172 "Could not parse '%s' from uri '%s'. %s", part_name, uri, extra));
178 return PercentEncode(
str, IsAuthorityChar);
182 return PercentEncode(
str, IsPathChar);
194 for (
size_t i = 0;
i <
str.length();
i++) {
196 if (
str[
i] ==
'%' &&
i + 3 <=
str.length() &&
199 unescaped.length() == 1) {
215 return MakeInvalidURIStatus(
"scheme", uri_text,
"Scheme not found.");
218 if (
scheme.find_first_not_of(
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
219 "abcdefghijklmnopqrstuvwxyz"
220 "0123456789+-.") != std::string::npos) {
221 return MakeInvalidURIStatus(
"scheme", uri_text,
222 "Scheme contains invalid characters.");
224 if (!isalpha(
scheme[0])) {
225 return MakeInvalidURIStatus(
227 "Scheme must begin with an alpha character [A-Za-z].");
243 if (!remaining.
empty()) {
253 std::vector<QueryParam> query_param_pairs;
257 if (tmp_query.
empty()) {
258 return MakeInvalidURIStatus(
"query", uri_text,
"Invalid query string.");
260 if (!IsQueryOrFragmentString(tmp_query)) {
261 return MakeInvalidURIStatus(
"query string", uri_text,
262 "Query string contains invalid characters.");
265 const std::pair<absl::string_view, absl::string_view> possible_kv =
267 if (possible_kv.first.empty())
continue;
268 query_param_pairs.push_back({
PercentDecode(possible_kv.first),
279 if (!IsQueryOrFragmentString(remaining)) {
280 return MakeInvalidURIStatus(
"fragment", uri_text,
281 "Fragment contains invalid characters.");
291 std::vector<QueryParam> query_parameter_pairs,
295 "if authority is present, path must start with a '/'");
302 std::vector<QueryParam> query_parameter_pairs,
std::string fragment)
304 authority_(
std::
move(authority)),
306 query_parameter_pairs_(
std::
move(query_parameter_pairs)),
307 fragment_(
std::
move(fragment)) {
314 : scheme_(other.scheme_),
315 authority_(other.authority_),
317 query_parameter_pairs_(other.query_parameter_pairs_),
318 fragment_(other.fragment_) {
325 if (
this == &other) {
342 struct QueryParameterFormatter {
345 absl::StrCat(PercentEncode(query_param.
key, IsQueryKeyOrValueChar),
"=",
346 PercentEncode(query_param.
value, IsQueryKeyOrValueChar)));
353 std::vector<std::string> parts = {PercentEncode(
scheme_, IsSchemeChar),
":"};
355 parts.emplace_back(
"//");
356 parts.emplace_back(PercentEncode(
authority_, IsAuthorityChar));
358 if (!
path_.empty()) {
359 parts.emplace_back(PercentEncode(
path_, IsPathChar));
362 parts.push_back(
"?");
367 parts.push_back(
"#");
368 parts.push_back(PercentEncode(
fragment_, IsQueryOrFragmentChar));
strings_internal::Splitter< typename strings_internal::SelectDelimiter< Delimiter >::type, AllowEmpty, absl::string_view > StrSplit(strings_internal::ConvertibleToStringView text, Delimiter d)
Status InvalidArgumentError(absl::string_view message)
static std::string PercentDecode(absl::string_view str)
strings_internal::MaxSplitsImpl< typename strings_internal::SelectDelimiter< Delimiter >::type > MaxSplits(Delimiter delimiter, int limit)
std::vector< QueryParam > query_parameter_pairs_
std::string StrCat(const AlphaNum &a, const AlphaNum &b)
ABSL_MUST_USE_RESULT std::string StrFormat(const FormatSpec< Args... > &format, const Args &... args)
size_type find(string_view s, size_type pos=0) const noexcept
const std::string & fragment() const
URI & operator=(const URI &other)
static absl::StatusOr< URI > Parse(absl::string_view uri_text)
size_type find_first_of(string_view s, size_type pos=0) const noexcept
const std::string & path() const
bool CUnescape(absl::string_view source, std::string *dest, std::string *error)
bool ascii_isalnum(unsigned char c)
std::string BytesToHexString(absl::string_view from)
constexpr absl::remove_reference_t< T > && move(T &&t) noexcept
std::string StrJoin(Iterator start, Iterator end, absl::string_view sep, Formatter &&fmt)
const std::string & authority() const
void AsciiStrToUpper(std::string *s)
std::map< absl::string_view, absl::string_view > query_parameter_map_
ABSL_NAMESPACE_BEGIN bool StrContains(absl::string_view haystack, absl::string_view needle) noexcept
const std::vector< QueryParam > & query_parameter_pairs() const
const std::string & scheme() const
static std::string PercentEncodePath(absl::string_view str)
ABSL_INTERNAL_STRING_VIEW_CXX14_CONSTEXPR void remove_prefix(size_type n)
static absl::StatusOr< URI > Create(std::string scheme, std::string authority, std::string path, std::vector< QueryParam > query_parameter_pairs, std::string fragment)
constexpr bool empty() const noexcept
static std::string PercentEncodeAuthority(absl::string_view str)
static constexpr size_type npos
constexpr string_view substr(size_type pos=0, size_type n=npos) const
std::string ToString() const
ABSL_NAMESPACE_BEGIN bool ConsumePrefix(absl::string_view *str, absl::string_view expected)
grpc
Author(s):
autogenerated on Thu Mar 13 2025 03:01:47