Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Upgrade percent encoding #155

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Apr 5, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 4 additions & 14 deletions include/skyr/v1/percent_encoding/percent_encode.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,21 +14,11 @@
namespace skyr {
inline namespace v1 {
/// Percent encodes the input
/// \returns The percent encoded output when successful, an error otherwise.
inline auto percent_encode(std::string_view input) {
using percent_encoding::percent_encoded_char;

/// \returns The percent encoded output.
inline auto percent_encode(std::string_view input) -> std::string {
static constexpr auto encode = [] (auto byte) {
if ((byte == '\x2a') || (byte == '\x2d') || (byte == '\x2e') ||
((byte >= '\x30') && (byte <= '\x39')) ||
((byte >= '\x41') && (byte <= '\x5a')) || (byte == '\x5f') ||
((byte >= '\x61') && (byte <= '\x7a'))) {
return percent_encoded_char(
std::byte(byte), percent_encoded_char::no_encode());
} else if (byte == '\x20') {
return percent_encoded_char(std::byte('+'), percent_encoded_char::no_encode());
}
return percent_encoded_char(std::byte(byte));
using percent_encoding::percent_encode_byte;
return percent_encode_byte(std::byte(byte), percent_encoding::encode_set::component);
};

auto result = std::string{};
Expand Down
61 changes: 54 additions & 7 deletions include/skyr/v1/percent_encoding/percent_encoded_char.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,11 +52,33 @@ inline constexpr auto is_fragment_byte(std::byte value) {
///
/// \param value
/// \return
inline constexpr auto is_path_byte(std::byte value) {
inline constexpr auto is_query_byte(std::byte value) {
return
is_fragment_byte(value) ||
is_c0_control_byte(value) ||
(value == std::byte(0x20)) ||
(value == std::byte(0x22)) ||
(value == std::byte(0x23)) ||
(value == std::byte(0x3c)) ||
(value == std::byte(0x3e));
}

///
/// \param value
/// \return
inline constexpr auto is_special_query_byte(std::byte value) {
return
is_query_byte(value) ||
(value == std::byte(0x27));
}

///
/// \param value
/// \return
inline constexpr auto is_path_byte(std::byte value) {
return
is_query_byte(value) ||
(value == std::byte(0x3f)) ||
(value == std::byte(0x60)) ||
(value == std::byte(0x7b)) ||
(value == std::byte(0x7d));
}
Expand All @@ -78,20 +100,39 @@ inline constexpr auto is_userinfo_byte(std::byte value) {
(value == std::byte(0x5e)) ||
(value == std::byte(0x7c));
}

///
/// \param value
/// \return
inline constexpr auto is_component_byte(std::byte value) {
return
is_userinfo_byte(value) ||
(value == std::byte(0x24)) ||
(value == std::byte(0x25)) ||
(value == std::byte(0x26)) ||
(value == std::byte(0x2b)) ||
(value == std::byte(0x2c));
}
} // namespace details

///
enum class encode_set {
///
none = 0,
any = 0,
///
c0_control,
///
fragment,
///
query,
///
special_query,
///
path,
///
userinfo,
///
component,
};

///
Expand Down Expand Up @@ -199,18 +240,24 @@ inline auto percent_encode_byte(std::byte byte, Pred pred) -> percent_encoded_ch

///
/// \param value
/// \param excludes
/// \param encodes
/// \return
inline auto percent_encode_byte(std::byte value, encode_set excludes) -> percent_encoded_char {
switch (excludes) {
case encode_set::none:
inline auto percent_encode_byte(std::byte value, encode_set encodes) -> percent_encoded_char {
switch (encodes) {
case encode_set::any:
return percent_encoding::percent_encoded_char(value);
case encode_set::c0_control:
return percent_encode_byte(value, details::is_c0_control_byte);
case encode_set::component:
return percent_encode_byte(value, details::is_component_byte);
case encode_set::userinfo:
return percent_encode_byte(value, details::is_userinfo_byte);
case encode_set::path:
return percent_encode_byte(value, details::is_path_byte);
case encode_set::special_query:
return percent_encode_byte(value, details::is_special_query_byte);
case encode_set::query:
return percent_encode_byte(value, details::is_query_byte);
case encode_set::fragment:
return percent_encode_byte(value, details::is_fragment_byte);
}
Expand Down
2 changes: 1 addition & 1 deletion include/skyr/v2/core/parse_path.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ inline auto parse_path(
std::string_view path, bool *validation_error) -> tl::expected<std::vector<std::string>, url_parse_errc> {
auto url = details::basic_parse(path, validation_error, nullptr, nullptr, url_parse_state::path_start);
if (url) {
return url.value().path;
return std::move(url.value()).path;
}
return tl::make_unexpected(url.error());
}
Expand Down
13 changes: 6 additions & 7 deletions include/skyr/v2/core/parse_query.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
#include <range/v3/view/split_when.hpp>
#include <range/v3/view/transform.hpp>
#include <skyr/v2/core/parse.hpp>
#include <skyr/v2/percent_encoding/percent_decode.hpp>

namespace skyr::inline v2 {
///
Expand Down Expand Up @@ -46,17 +45,17 @@ inline auto parse_query(
if (url) {
static constexpr auto is_separator = [](auto c) { return c == '&' || c == ';'; };

static constexpr auto to_nvp = [](auto &&param) -> query_parameter {
if (ranges::empty(param)) {
static constexpr auto to_nvp = [](auto &&parameter) -> query_parameter {
if (ranges::empty(parameter)) {
return {};
}

auto element = std::string_view(std::addressof(*std::begin(param)), ranges::distance(param));
auto delim = element.find_first_of('=');
auto view = std::string_view(std::addressof(*std::begin(parameter)), ranges::distance(parameter));
auto delim = view.find_first_of('=');
if (delim != std::string_view::npos) {
return {std::string(element.substr(0, delim)), std::string(element.substr(delim + 1))};
return {std::string(view.substr(0, delim)), std::string(view.substr(delim + 1))};
} else {
return {std::string(element)};
return {std::string(view)};
}
};

Expand Down
2 changes: 1 addition & 1 deletion include/skyr/v2/core/url_parser_context.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -889,7 +889,7 @@ class url_parser_context {
if (!url.query) {
set_empty_query();
}
auto pct_encoded = percent_encode_byte(std::byte(byte), percent_encoding::encode_set::none);
auto pct_encoded = percent_encode_byte(std::byte(byte), percent_encoding::encode_set::any);
url.query.value() += std::move(pct_encoded).to_string();
}

Expand Down
4 changes: 2 additions & 2 deletions include/skyr/v2/domain/domain.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ inline auto domain_to_ascii_impl(domain_to_ascii_context &&context) -> tl::expec
}
};

constexpr auto process_labels = [](auto &&ctx) -> tl::expected<domain_to_ascii_context, domain_errc> {
constexpr auto process_labels = [](auto &&ctx) -> tl::expected<std::decay_t<decltype(ctx)>, domain_errc> {
using namespace std::string_view_literals;

constexpr auto to_string_view = [](auto &&label) {
Expand Down Expand Up @@ -198,7 +198,7 @@ inline auto domain_to_ascii_impl(domain_to_ascii_context &&context) -> tl::expec
};

constexpr auto check_length =
[](domain_to_ascii_context &&ctx) -> tl::expected<domain_to_ascii_context, domain_errc> {
[](auto &&ctx) -> tl::expected<std::decay_t<decltype(ctx)>, domain_errc> {
constexpr auto max_domain_length = 253;
constexpr auto max_label_length = 63;

Expand Down
19 changes: 8 additions & 11 deletions include/skyr/v2/percent_encoding/percent_encode.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,10 @@
namespace skyr::inline v2 {
/// Percent encodes the input
/// \returns The percent encoded output when successful, an error otherwise.
inline auto percent_encode(std::string_view input) {
using percent_encoding::percent_encoded_char;

static constexpr auto encode = [](auto byte) {
if ((byte == '\x2a') || (byte == '\x2d') || (byte == '\x2e') || ((byte >= '\x30') && (byte <= '\x39')) ||
((byte >= '\x41') && (byte <= '\x5a')) || (byte == '\x5f') || ((byte >= '\x61') && (byte <= '\x7a'))) {
return percent_encoded_char(std::byte(byte), percent_encoded_char::no_encode());
} else if (byte == '\x20') {
return percent_encoded_char(std::byte('+'), percent_encoded_char::no_encode());
}
return percent_encoded_char(std::byte(byte));
inline auto percent_encode_bytes(std::string_view input, percent_encoding::encode_set encodes) -> std::string {
static auto encode = [&encodes] (auto byte) {
using percent_encoding::percent_encode_byte;
return percent_encode_byte(std::byte(byte), encodes);
};

auto result = std::string{};
Expand All @@ -33,6 +26,10 @@ inline auto percent_encode(std::string_view input) {
}
return result;
}

inline auto percent_encode(std::string_view input) -> std::string {
return percent_encode_bytes(input, percent_encoding::encode_set::component);
}
} // namespace skyr::inline v2

#endif // SKYR_V2_PERCENT_ENCODING_PERCENT_ENCODE_HPP
Loading