summaryrefslogtreecommitdiff
path: root/src/url.cc
diff options
context:
space:
mode:
authorJoel Klinghed <the_jk@yahoo.com>2017-03-01 22:54:09 +0100
committerJoel Klinghed <the_jk@yahoo.com>2017-03-01 22:54:09 +0100
commit719d90a40e83e870be19f8d46cc55caed618aa35 (patch)
tree10bc226c44aff6cfa3c53e5d837a32720c9bf836 /src/url.cc
parent537ed164ae1875a8d38e06dbc214ef4f91bc4642 (diff)
Add support for CONNECT
Diffstat (limited to 'src/url.cc')
-rw-r--r--src/url.cc44
1 files changed, 31 insertions, 13 deletions
diff --git a/src/url.cc b/src/url.cc
index 63419ba..2c160d2 100644
--- a/src/url.cc
+++ b/src/url.cc
@@ -364,7 +364,8 @@ bool UrlImpl::relative(std::string const& url, Url const* base) {
return true;
}
-char const* UrlImpl::parse_authority(char const* pos) {
+char const* parse_authority(char const* pos, char** userinfo,
+ std::string* host, uint16_t* port) {
/* authority = [ userinfo "@" ] host [ ":" port ]
userinfo = *( unreserved / pct-encoded / sub-delims / ":" )
host = IP-literal / IPv4address / reg-name
@@ -417,9 +418,10 @@ char const* UrlImpl::parse_authority(char const* pos) {
// userinfo?
if (at) {
+ if (!userinfo) return nullptr;
host_start = at + 1;
- userinfo_ = dup(start, at);
- if (strchr(userinfo_, '[') || strchr(userinfo_, ']')) {
+ *userinfo = dup(start, at);
+ if (strchr(*userinfo, '[') || strchr(*userinfo, ']')) {
return nullptr;
}
} else {
@@ -448,7 +450,7 @@ char const* UrlImpl::parse_authority(char const* pos) {
tmp++;
}
if (host_end == colon) {
- port_ = v;
+ *port = v;
}
} else {
host_end = pos;
@@ -467,17 +469,17 @@ char const* UrlImpl::parse_authority(char const* pos) {
if (!is_hex(host_start[1]) || host_start[2] != '.') {
return nullptr;
}
- host_.assign(host_start, host_end - host_start);
- lower(host_);
+ host->assign(host_start, host_end - host_start);
+ lower(*host);
} else {
if (!is_ipv6(host_start, host_end)) {
return nullptr;
}
- host_.assign(host_start, host_end - host_start);
- lower(host_);
+ host->assign(host_start, host_end - host_start);
+ lower(*host);
}
- if (host_.find('[') != std::string::npos ||
- host_.find(']') != std::string::npos) {
+ if (host->find('[') != std::string::npos ||
+ host->find(']') != std::string::npos) {
return nullptr;
}
} else {
@@ -490,14 +492,18 @@ char const* UrlImpl::parse_authority(char const* pos) {
}
tmp = unescape(const_cast<char*>(host_start), const_cast<char*>(host_end),
false);
- host_ = tmp;
- lower(host_);
+ host->assign(tmp);
+ lower(*host);
delete[] const_cast<char*>(tmp);
}
- if (host_.empty()) return nullptr;
+ if (host->empty()) return nullptr;
return pos;
}
+char const* UrlImpl::parse_authority(char const* pos) {
+ return ::parse_authority(pos, &userinfo_, &host_, &port_);
+}
+
char const* UrlImpl::parse_query(char const* pos) {
// query = *( pchar / "/" / "?" )
char const* start = ++pos;
@@ -892,6 +898,18 @@ Url* Url::parse(std::string const& url, Url const* base) {
return nullptr;
}
+// static
+bool Url::parse_authority(std::string const& str,
+ std::string* host, uint16_t* port) {
+ std::string tmp_host;
+ uint16_t tmp_port;
+ auto ret = ::parse_authority(str.c_str(), nullptr, &tmp_host, &tmp_port);
+ if (!ret || *ret) return false;
+ if (host) host->assign(tmp_host);
+ if (port) *port = tmp_port;
+ return true;
+}
+
bool Url::operator==(Url const& url) const {
if (scheme() != url.scheme()) return false;
if (host() != url.host()) return false;