-
Notifications
You must be signed in to change notification settings - Fork 423
/
url_parser.h
132 lines (124 loc) · 2.93 KB
/
url_parser.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
// Copyright The OpenTelemetry Authors
// SPDX-License-Identifier: Apache-2.0
#pragma once
#include <string>
#include <vector>
#include "opentelemetry/nostd/string_view.h"
#include "opentelemetry/version.h"
OPENTELEMETRY_BEGIN_NAMESPACE
namespace ext
{
namespace http
{
namespace common
{
// http://user:password@host:port/path1/path2?key1=val2&key2=val2
// http://host:port/path1/path2?key1=val1&key2=val2
// host:port/path1
// host:port ( path defaults to "/")
// host:port?
class UrlParser
{
public:
std::string url_;
std::string host_;
std::string scheme_;
std::string path_;
uint16_t port_;
std::string query_;
bool success_;
UrlParser(std::string url) : url_(url), success_(true)
{
if (url_.length() == 0)
{
return;
}
size_t cpos = 0;
// scheme
size_t pos = url_.find("://", cpos);
if (pos == std::string::npos)
{
// scheme missing, use default as http
scheme_ = "http";
}
else
{
scheme_ = std::string(url_.begin() + cpos, url_.begin() + pos);
cpos = pos + 3;
}
// credentials
pos = url_.find_first_of("@", cpos);
if (pos != std::string::npos)
{
// TODO - handle credentials
cpos = pos + 1;
}
pos = url_.find_first_of(":", cpos);
bool is_port = false;
if (pos == std::string::npos)
{
// port missing. Used default 80 / 443
if (scheme_ == "http")
port_ = 80;
if (scheme_ == "https")
port_ = 443;
}
else
{
// port present
is_port = true;
host_ = std::string(url_.begin() + cpos, url_.begin() + pos);
cpos = pos + 1;
}
pos = url_.find_first_of("/?", cpos);
if (pos == std::string::npos)
{
path_ = "/"; // use default path
if (is_port)
{
port_ = static_cast<uint16_t>(
std::stoi(std::string(url_.begin() + cpos, url_.begin() + url_.length())));
}
else
{
host_ = std::string(url_.begin() + cpos, url_.begin() + url_.length());
}
return;
}
if (is_port)
{
port_ =
static_cast<uint16_t>(std::stoi(std::string(url_.begin() + cpos, url_.begin() + pos)));
}
else
{
host_ = std::string(url_.begin() + cpos, url_.begin() + pos);
}
cpos = pos;
if (url_[cpos] == '/')
{
pos = url_.find('?', cpos);
if (pos == std::string::npos)
{
path_ = std::string(url_.begin() + cpos, url_.begin() + url_.length());
query_ = "";
}
else
{
path_ = std::string(url_.begin() + cpos, url_.begin() + pos);
cpos = pos + 1;
query_ = std::string(url_.begin() + cpos, url_.begin() + url_.length());
}
return;
}
path_ = "/";
if (url_[cpos] == '?')
{
query_ = std::string(url_.begin() + cpos, url_.begin() + url_.length());
}
}
};
} // namespace common
} // namespace http
} // namespace ext
OPENTELEMETRY_END_NAMESPACE