NVIDIA DeepStream SDK API Reference

9.2 Release
includes/opentelemetry/ext/http/common/url_parser.h
Go to the documentation of this file.
1 // Copyright The OpenTelemetry Authors
2 // SPDX-License-Identifier: Apache-2.0
3 
4 #pragma once
5 
6 #include <cerrno>
7 #include <cstdint>
8 #include <cstdlib>
9 #include <string>
10 #include <utility>
11 
12 #include "opentelemetry/version.h"
13 
15 namespace ext
16 {
17 namespace http
18 {
19 namespace common
20 {
21 // http://user:password@host:port/path1/path2?key1=val2&key2=val2
22 // http://host:port/path1/path2?key1=val1&key2=val2
23 // host:port/path1
24 // host:port ( path defaults to "/")
25 // host:port?
26 
27 class UrlParser
28 {
29 public:
30  std::string url_;
31  std::string host_;
32  std::string scheme_;
33  std::string path_;
34  uint16_t port_;
35  std::string query_;
36  bool success_;
37 
38  UrlParser(std::string url) : url_(std::move(url)), success_(true)
39  {
40  if (url_.length() == 0)
41  {
42  return;
43  }
44  size_t cpos = 0;
45  // scheme
46  size_t pos = url_.find("://", cpos);
47  if (pos == std::string::npos)
48  {
49  // scheme missing, use default as http
50  scheme_ = "http";
51  }
52  else
53  {
54  scheme_ = url_.substr(cpos, pos - cpos);
55  cpos = pos + 3;
56  }
57 
58  // credentials
59  size_t pos1 = url_.find_first_of('@', cpos);
60  if (pos1 != std::string::npos)
61  {
62  size_t pos2 = url_.find_first_of('/', cpos);
63  // TODO - handle credentials
64  if (pos2 == std::string::npos || pos1 < pos2)
65  {
66  pos = pos1;
67  cpos = pos1 + 1;
68  }
69  }
70  pos = FindPortPosition(url_, cpos);
71  bool is_port = false;
72  if (pos == std::string::npos)
73  {
74  // port missing. Used default 80 / 443
75  if (scheme_ == "http")
76  {
77  port_ = 80;
78  }
79  else if (scheme_ == "https")
80  {
81  port_ = 443;
82  }
83  }
84  else
85  {
86  // port present
87  is_port = true;
88  host_ = url_.substr(cpos, pos - cpos);
89  cpos = pos + 1;
90  }
91  pos = url_.find_first_of("/?", cpos);
92  if (pos == std::string::npos)
93  {
94  path_ = std::string("/"); // use default path
95  if (is_port)
96  {
97  auto port_str = url_.substr(cpos);
98  port_ = GetPort(port_str);
99  }
100  else
101  {
102  host_ = url_.substr(cpos);
103  }
104  return;
105  }
106  if (is_port)
107  {
108  auto port_str = url_.substr(cpos, pos - cpos);
109  port_ = GetPort(port_str);
110  }
111  else
112  {
113  host_ = url_.substr(cpos, pos - cpos);
114  }
115  cpos = pos;
116 
117  if (url_[cpos] == '/')
118  {
119  pos = url_.find('?', cpos);
120  if (pos == std::string::npos)
121  {
122  path_ = url_.substr(cpos);
123  }
124  else
125  {
126  path_ = url_.substr(cpos, pos - cpos);
127  cpos = pos + 1;
128  query_ = url_.substr(cpos);
129  }
130  return;
131  }
132  path_ = std::string("/");
133  if (url_[cpos] == '?')
134  {
135  query_ = url_.substr(cpos);
136  }
137  }
138 
139 private:
140  static std::string::size_type FindPortPosition(const std::string &url,
141  std::string::size_type offset)
142  {
143  // @see https://www.rfc-editor.org/rfc/rfc3986#page-18
144  size_t sub_expression_counter = 0;
145  for (std::string::size_type i = offset; i < url.size(); ++i)
146  {
147  char c = url[i];
148  if (0 == sub_expression_counter && c == ':')
149  {
150  return i;
151  }
152 
153  if (c == '[')
154  {
155  ++sub_expression_counter;
156  }
157  else if (c == ']')
158  {
159  if (sub_expression_counter > 0)
160  {
161  --sub_expression_counter;
162  }
163  }
164  else if (0 == sub_expression_counter && c == '/')
165  {
166  break;
167  }
168  }
169 
170  return std::string::npos;
171  }
172 
173  std::uint16_t GetPort(const std::string &s)
174  {
175  char *e = nullptr;
176  errno = 0;
177  auto port = std::strtol(s.c_str(), &e, 10);
178  if (e == s.c_str() || e != s.c_str() + s.size() || errno == ERANGE || port < 0 || port > 65535)
179  {
180  success_ = false;
181  return 0;
182  }
183 
184  return static_cast<uint16_t>(port);
185  }
186 };
187 
189 {
190 public:
191  static std::string Decode(const std::string &encoded)
192  {
193  std::string result;
194  result.reserve(encoded.size());
195 
196  auto hex_to_int = [](int ch) -> int {
197  if (ch >= '0' && ch <= '9')
198  return ch - '0';
199  if (ch >= 'a' && ch <= 'f')
200  return ch - 'a' + 10;
201  if (ch >= 'A' && ch <= 'F')
202  return ch - 'A' + 10;
203  return -1;
204  };
205 
206  for (size_t pos = 0; pos < encoded.size(); pos++)
207  {
208  auto c = encoded[pos];
209  if (c == '%')
210  {
211  if (pos + 2 >= encoded.size())
212  {
213  return encoded;
214  }
215 
216  int hi = hex_to_int(encoded[pos + 1]);
217  int lo = hex_to_int(encoded[pos + 2]);
218 
219  if (hi == -1 || lo == -1)
220  {
221  return encoded;
222  }
223 
224  c = static_cast<char>((hi << 4) | lo);
225  pos += 2;
226  }
227 
228  result.push_back(c);
229  }
230 
231  return result;
232  }
233 };
234 
235 } // namespace common
236 
237 } // namespace http
238 } // namespace ext
ext
Definition: includes/opentelemetry/ext/http/client/http_client.h:63
ext::http::common::UrlDecoder::Decode
static std::string Decode(const std::string &encoded)
Definition: includes/opentelemetry/ext/http/common/url_parser.h:191
ext::http::common::UrlParser::success_
bool success_
Definition: includes/opentelemetry/ext/http/common/url_parser.h:36
ext::http::common::UrlParser::UrlParser
UrlParser(std::string url)
Definition: includes/opentelemetry/ext/http/common/url_parser.h:38
OPENTELEMETRY_BEGIN_NAMESPACE
#define OPENTELEMETRY_BEGIN_NAMESPACE
Definition: includes/opentelemetry/version.h:21
ext::http::common::UrlParser::host_
std::string host_
Definition: includes/opentelemetry/ext/http/common/url_parser.h:31
ext::http::common::UrlParser
Definition: includes/opentelemetry/ext/http/common/url_parser.h:27
ext::http::common::UrlParser::query_
std::string query_
Definition: includes/opentelemetry/ext/http/common/url_parser.h:35
OPENTELEMETRY_END_NAMESPACE
#define OPENTELEMETRY_END_NAMESPACE
Definition: includes/opentelemetry/version.h:24
absl::move
constexpr absl::OTABSL_OPTION_NAMESPACE_NAME::remove_reference_t< T > && move(T &&t) noexcept
Definition: includes/opentelemetry/nostd/internal/absl/utility/utility.h:199
ext::http::common::UrlDecoder
Definition: includes/opentelemetry/ext/http/common/url_parser.h:188
ext::http::common::UrlParser::scheme_
std::string scheme_
Definition: includes/opentelemetry/ext/http/common/url_parser.h:32
ext::http::common::UrlParser::port_
uint16_t port_
Definition: includes/opentelemetry/ext/http/common/url_parser.h:34
std
Extensions to the C++ standard library.
Definition: includes/opentelemetry/nostd/string_view.h:212
ext::http::common::UrlParser::url_
std::string url_
Definition: includes/opentelemetry/ext/http/common/url_parser.h:30
common
Definition: includes/opentelemetry/common/attribute_value.h:14
ext::http::common::UrlParser::path_
std::string path_
Definition: includes/opentelemetry/ext/http/common/url_parser.h:33