1 // Copyright 2021 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "net/third_party/quiche/src/quiche/common/platform/default/quiche_platform_impl/quiche_url_utils_impl.h"
6 
7 #include <cstdint>
8 #include <limits>
9 #include <optional>
10 #include <string>
11 #include <string_view>
12 
13 #include "net/third_party/uri_template/uri_template.h"
14 #include "third_party/abseil-cpp/absl/container/flat_hash_map.h"
15 #include "third_party/abseil-cpp/absl/container/flat_hash_set.h"
16 #include "third_party/abseil-cpp/absl/strings/str_cat.h"
17 #include "third_party/abseil-cpp/absl/strings/str_replace.h"
18 #include "url/url_canon.h"
19 #include "url/url_util.h"
20 
21 namespace quiche {
22 
ExpandURITemplateImpl(const std::string & uri_template,const absl::flat_hash_map<std::string,std::string> & parameters,std::string * target,absl::flat_hash_set<std::string> * vars_found)23 bool ExpandURITemplateImpl(
24     const std::string& uri_template,
25     const absl::flat_hash_map<std::string, std::string>& parameters,
26     std::string* target,
27     absl::flat_hash_set<std::string>* vars_found) {
28   std::unordered_map<std::string, std::string> std_parameters;
29   for (const auto& pair : parameters) {
30     std_parameters[pair.first] = pair.second;
31   }
32   std::set<std::string> std_vars_found;
33   const bool result =
34       uri_template::Expand(uri_template, std_parameters, target,
35                            vars_found != nullptr ? &std_vars_found : nullptr);
36   if (vars_found != nullptr) {
37     for (const std::string& var_found : std_vars_found) {
38       vars_found->insert(var_found);
39     }
40   }
41   return result;
42 }
43 
AsciiUrlDecodeImpl(std::string_view input)44 std::optional<std::string> AsciiUrlDecodeImpl(std::string_view input) {
45   url::RawCanonOutputW<1024> canon_output;
46   url::DecodeURLEscapeSequences(input, url::DecodeURLMode::kUTF8,
47                                 &canon_output);
48   std::string output;
49   output.reserve(canon_output.length());
50   for (uint16_t c : canon_output.view()) {
51     if (c > std::numeric_limits<signed char>::max()) {
52       return std::nullopt;
53     }
54     output += static_cast<char>(c);
55   }
56   return output;
57 }
58 
59 }  // namespace quiche
60