1 //
2 // Copyright 2015 gRPC authors.
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 //     http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 //
16 
17 #ifndef GRPC_SRC_CORE_LIB_URI_URI_PARSER_H
18 #define GRPC_SRC_CORE_LIB_URI_URI_PARSER_H
19 
20 #include <grpc/support/port_platform.h>
21 
22 #include <map>
23 #include <string>
24 #include <vector>
25 
26 #include "absl/status/statusor.h"
27 #include "absl/strings/string_view.h"
28 
29 namespace grpc_core {
30 
31 class URI {
32  public:
33   struct QueryParam {
34     std::string key;
35     std::string value;
36     bool operator==(const QueryParam& other) const {
37       return key == other.key && value == other.value;
38     }
39     bool operator<(const QueryParam& other) const {
40       int c = key.compare(other.key);
41       if (c != 0) return c < 0;
42       return value < other.value;
43     }
44   };
45 
46   // Creates a URI by parsing an rfc3986 URI string. Returns an
47   // InvalidArgumentError on failure.
48   static absl::StatusOr<URI> Parse(absl::string_view uri_text);
49   // Creates a URI from components. Returns an InvalidArgumentError on failure.
50   static absl::StatusOr<URI> Create(
51       std::string scheme, std::string authority, std::string path,
52       std::vector<QueryParam> query_parameter_pairs, std::string fragment);
53 
54   URI() = default;
55 
56   // Copy construction and assignment
57   URI(const URI& other);
58   URI& operator=(const URI& other);
59   // Move construction and assignment
60   URI(URI&&) = default;
61   URI& operator=(URI&&) = default;
62 
63   static std::string PercentEncodeAuthority(absl::string_view str);
64   static std::string PercentEncodePath(absl::string_view str);
65 
66   static std::string PercentDecode(absl::string_view str);
67 
scheme()68   const std::string& scheme() const { return scheme_; }
authority()69   const std::string& authority() const { return authority_; }
path()70   const std::string& path() const { return path_; }
71   // Stores the *last* value appearing for each repeated key in the query
72   // string. If you need to capture repeated query parameters, use
73   // `query_parameter_pairs`.
query_parameter_map()74   const std::map<absl::string_view, absl::string_view>& query_parameter_map()
75       const {
76     return query_parameter_map_;
77   }
78   // A vector of key:value query parameter pairs, kept in order of appearance
79   // within the URI search string. Repeated keys are represented as separate
80   // key:value elements.
query_parameter_pairs()81   const std::vector<QueryParam>& query_parameter_pairs() const {
82     return query_parameter_pairs_;
83   }
fragment()84   const std::string& fragment() const { return fragment_; }
85 
86   std::string ToString() const;
87 
88  private:
89   URI(std::string scheme, std::string authority, std::string path,
90       std::vector<QueryParam> query_parameter_pairs, std::string fragment);
91 
92   std::string scheme_;
93   std::string authority_;
94   std::string path_;
95   std::map<absl::string_view, absl::string_view> query_parameter_map_;
96   std::vector<QueryParam> query_parameter_pairs_;
97   std::string fragment_;
98 };
99 }  // namespace grpc_core
100 
101 #endif  // GRPC_SRC_CORE_LIB_URI_URI_PARSER_H
102