7#include <botan/internal/uri.h>
8#include <botan/exceptn.h>
12#if defined(BOTAN_TARGET_OS_HAS_SOCKETS)
13 #include <arpa/inet.h>
14 #include <sys/socket.h>
15 #include <netinet/in.h>
16#elif defined(BOTAN_TARGET_OS_HAS_WINSOCK2)
20#if defined(BOTAN_TARGET_OS_HAS_SOCKETS) || defined(BOTAN_TARGET_OS_HAS_WINSOCK2)
24constexpr bool isdigit(
char ch)
26 return ch >=
'0' && ch <=
'9';
29bool isDomain(
const std::string& domain)
31#if defined(__GLIBCXX__) && (__GLIBCXX__ < 20160726)
37 R
"(^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\-]*[A-Za-z0-9])$)");
39 return std::regex_match(domain.c_str(), m, re);
43bool isIPv4(
const std::string& ip)
45 sockaddr_storage inaddr;
46 return !!inet_pton(AF_INET, ip.c_str(), &inaddr);
49bool isIPv6(
const std::string& ip)
51 sockaddr_storage in6addr;
52 return !!inet_pton(AF_INET6, ip.c_str(), &in6addr);
61 const auto port_pos = uri.find(
':');
62 if(port_pos != std::string::npos)
64 for(
char c : uri.substr(port_pos+1))
67 {
throw Invalid_Argument(
"invalid"); }
70 {
throw Invalid_Argument(
"invalid"); }
73 const auto domain = uri.substr(0, port_pos);
75 {
throw Invalid_Argument(
"invalid"); }
77 {
throw Invalid_Argument(
"invalid"); }
84 const auto port_pos = uri.find(
':');
85 if(port_pos != std::string::npos)
87 for(
char c : uri.substr(port_pos+1))
90 {
throw Invalid_Argument(
"invalid"); }
93 {
throw Invalid_Argument(
"invalid"); }
96 const auto ip = uri.substr(0, port_pos);
98 {
throw Invalid_Argument(
"invalid"); }
105 const auto port_pos = uri.find(
']');
106 const bool with_braces = (port_pos != std::string::npos);
107 if((uri[0]==
'[') != with_braces)
108 {
throw Invalid_Argument(
"invalid"); }
110 if(with_braces && (uri.size() > port_pos + 1))
112 if(uri[port_pos+1]!=
':')
113 {
throw Invalid_Argument(
"invalid"); }
114 for(
char c : uri.substr(port_pos+2))
117 {
throw Invalid_Argument(
"invalid"); }
120 {
throw Invalid_Argument(
"invalid"); }
123 const auto ip = uri.substr((with_braces ? 1 : 0), port_pos - with_braces);
125 {
throw Invalid_Argument(
"invalid"); }
132 bool colon_seen=
false;
133 bool non_number=
false;
144 else if(!isdigit(c) && c !=
'.')
151 if(isIPv4(uri.substr(0, uri.find(
':'))))
163 throw Invalid_Argument(
"not set");
169 {
return "[" +
host +
"]:" + std::to_string(
port); }
170 return host +
":" + std::to_string(
port);
#define BOTAN_UNUSED(...)
static URI fromAny(const std::string &uri)
static URI fromIPv4(const std::string &uri)
static URI fromIPv6(const std::string &uri)
static URI fromDomain(const std::string &uri)
std::string to_string() const